feat: scripting-like tags on custom sms content
feat: add created column to custom_messages feat: custom message dynamic validators and testing feat: delete custom sms feat: employ custom sms to existing events
This commit is contained in:
parent
3480bbf8f7
commit
54b73b95b4
10 changed files with 444 additions and 95 deletions
|
|
@ -1,40 +1,128 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import { Form, Formik, Field } from 'formik'
|
||||
import React from 'react'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import { Autocomplete } from 'src/components/inputs/formik'
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { Autocomplete, TextInput } from 'src/components/inputs/formik'
|
||||
|
||||
const EVENT_OPTIONS = [
|
||||
{ code: 'sms_code', display: 'On SMS confirmation code' },
|
||||
{ code: 'cash_out_dispense_ready', display: 'Cash out dispense ready' }
|
||||
]
|
||||
import styles from './CustomSMS.styles'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const ALL_MACHINES = {
|
||||
code: 'ALL_MACHINES',
|
||||
display: 'All Machines'
|
||||
}
|
||||
|
||||
const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
|
||||
if (!formikErrors || !formikTouched) return null
|
||||
if (mutationError) return 'Internal server error'
|
||||
if (formikErrors.event && formikTouched.event) return formikErrors.event
|
||||
if (formikErrors.message && formikTouched.message) return formikErrors.message
|
||||
return null
|
||||
}
|
||||
|
||||
const prefill = {
|
||||
smsCode: {
|
||||
tags: [],
|
||||
validator: Yup.string()
|
||||
.required('The message content is required!')
|
||||
.trim()
|
||||
.test({
|
||||
name: 'has-code-tag',
|
||||
message: 'A #code tag is missing from the message!',
|
||||
exclusive: false,
|
||||
test: value => value?.match(/#code/g || [])?.length > 0
|
||||
})
|
||||
.test({
|
||||
name: 'has-single-code-tag',
|
||||
message: 'There should be a single #code tag!',
|
||||
exclusive: false,
|
||||
test: value => value?.match(/#code/g || [])?.length === 1
|
||||
})
|
||||
},
|
||||
cashOutDispenseReady: {
|
||||
tags: [],
|
||||
validator: Yup.string()
|
||||
.required('The message content is required!')
|
||||
.trim()
|
||||
.test({
|
||||
name: 'has-timestamp-tag',
|
||||
message: 'A #timestamp tag is missing from the message!',
|
||||
exclusive: false,
|
||||
test: value => value?.match(/#timestamp/g || [])?.length > 0
|
||||
})
|
||||
.test({
|
||||
name: 'has-single-timestamp-tag',
|
||||
message: 'There should be a single #timestamp tag!',
|
||||
exclusive: false,
|
||||
test: value => value?.match(/#timestamp/g || [])?.length === 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const CustomSMSModal = ({
|
||||
showModal,
|
||||
onClose,
|
||||
customMessage,
|
||||
machineOptions
|
||||
sms,
|
||||
machineOptions,
|
||||
eventOptions,
|
||||
creationError,
|
||||
submit
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const [selectedEvent, setSelectedEvent] = useState(sms?.event)
|
||||
|
||||
const initialValues = {
|
||||
event: '',
|
||||
device: '',
|
||||
message: ''
|
||||
event: !R.isNil(sms) ? sms.event : '',
|
||||
device: !R.isNil(sms)
|
||||
? !R.isNil(sms.deviceId)
|
||||
? sms.deviceId
|
||||
: 'ALL_MACHINES'
|
||||
: '',
|
||||
message: !R.isNil(sms) ? sms.message : ''
|
||||
}
|
||||
|
||||
const validationSchema = {
|
||||
const validationSchema = Yup.object().shape({
|
||||
event: Yup.string().required('An event is required!'),
|
||||
device: Yup.string(),
|
||||
message: Yup.string()
|
||||
.required('The message content is required!')
|
||||
.trim()
|
||||
device: Yup.string().required('A machine is required!'),
|
||||
message:
|
||||
prefill[selectedEvent]?.validator ??
|
||||
Yup.string()
|
||||
.required('The message content is required!')
|
||||
.trim()
|
||||
})
|
||||
|
||||
const handleSubmit = values => {
|
||||
sms
|
||||
? submit({
|
||||
variables: {
|
||||
id: sms.id,
|
||||
event: values.event,
|
||||
deviceId: values.device,
|
||||
message: values.message
|
||||
}
|
||||
})
|
||||
: submit({
|
||||
variables: {
|
||||
event: values.event,
|
||||
deviceId: values.device,
|
||||
message: values.message
|
||||
}
|
||||
})
|
||||
onClose()
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{showModal && (
|
||||
<Modal
|
||||
title="Add custom SMS"
|
||||
title={!R.isNil(sms) ? `Edit custom SMS` : `Add custom SMS`}
|
||||
closeOnBackdropClick={true}
|
||||
width={600}
|
||||
height={500}
|
||||
|
|
@ -44,25 +132,54 @@ const CustomSMSModal = ({
|
|||
validateOnBlur={false}
|
||||
validateOnChange={false}
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}>
|
||||
<Form id="custom-sms">
|
||||
<Field
|
||||
name="event"
|
||||
fullWidth
|
||||
options={EVENT_OPTIONS}
|
||||
labelProp="display"
|
||||
valueProp="code"
|
||||
component={Autocomplete}
|
||||
/>
|
||||
<Field
|
||||
name="device"
|
||||
fullWidth
|
||||
options={machineOptions}
|
||||
labelProp="display"
|
||||
valueProp="code"
|
||||
component={Autocomplete}
|
||||
/>
|
||||
</Form>
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={(values, errors, touched) =>
|
||||
handleSubmit(values, errors, touched)
|
||||
}>
|
||||
{({ values, errors, touched }) => (
|
||||
<Form id="custom-sms" className={classes.form}>
|
||||
<Field
|
||||
name="event"
|
||||
label="Event"
|
||||
fullWidth
|
||||
onChange={setSelectedEvent(values.event)}
|
||||
options={eventOptions}
|
||||
labelProp="display"
|
||||
valueProp="code"
|
||||
component={Autocomplete}
|
||||
/>
|
||||
<Field
|
||||
name="device"
|
||||
label="Machine"
|
||||
fullWidth
|
||||
options={[ALL_MACHINES].concat(machineOptions)}
|
||||
labelProp="display"
|
||||
valueProp="code"
|
||||
component={Autocomplete}
|
||||
/>
|
||||
<Field
|
||||
name="message"
|
||||
label="Message content"
|
||||
fullWidth
|
||||
multiline={true}
|
||||
rows={6}
|
||||
component={TextInput}
|
||||
/>
|
||||
<div className={classes.footer}>
|
||||
{getErrorMsg(errors, touched, creationError) && (
|
||||
<ErrorMessage>
|
||||
{getErrorMsg(errors, touched, creationError)}
|
||||
</ErrorMessage>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
form="custom-sms"
|
||||
className={classes.submit}>
|
||||
{!R.isNil(sms) ? `Confirm` : `Create SMS`}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</Modal>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue