Chore: Add basic screen and toggle
Chore: form skeleton Feat: wizard step 1 and 2 Feat: toggle button group for formik Feat: select input type Form and styling Feat: text entry page Feat: Choice list and CSS Fix: scroll to bottom on Add choice button click Feat: format data at end of wizard Feat: wizard toggle button and background blur Feat: data table for custom info requests Feat: editing and deleting custom info request Feat: add icons Fix: Wizard changes Feat: custom requests migrations Feat: fetch custom info requests Feat: add mutations Feat: add custom request option in trigger wizard Feat: show customrequests on table Feat: Triggers page code refactor Feat: integrate custom info requests on Customer graphql type Feat: Show custom info requests on user page Fix: use normal table instead of datatable Feat: modal for custom information request details Feat: poller returns custom request information details Feat: send customer custom info requests to machine Chore: add field CustomInfoRequestsData on customer updates Feat: customer custom info request data saving Chore: variable name changes and lots of fixes Feat: remove default value in query, sort request on customer profile Signed-off-by: csrapr <26280794+csrapr@users.noreply.github.com> Fix: return promise when array of ids is empty Feat: TitleSection can receive more than one button
This commit is contained in:
parent
3de2bb3d86
commit
ba8cac60f8
48 changed files with 2424 additions and 146 deletions
|
|
@ -0,0 +1,244 @@
|
|||
import { makeStyles } from '@material-ui/core'
|
||||
import { Form, Formik } from 'formik'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import Modal from 'src/components/Modal'
|
||||
import Stepper from 'src/components/Stepper'
|
||||
import { Button } from 'src/components/buttons'
|
||||
|
||||
import ChooseType, {
|
||||
validationSchema as chooseTypeSchema,
|
||||
defaultValues as chooseTypeDefaults
|
||||
} from './Forms/ChooseType'
|
||||
import NameOfRequirement, {
|
||||
validationSchema as nameOfReqSchema,
|
||||
defaultValues as nameOfReqDefaults
|
||||
} from './Forms/NameOfRequirement'
|
||||
import Screen1Information, {
|
||||
validationSchema as screen1InfoSchema,
|
||||
defaultValues as screen1InfoDefaults
|
||||
} from './Forms/Screen1Information'
|
||||
import Screen2Information, {
|
||||
validationSchema as screen2InfoSchema,
|
||||
defaultValues as screen2InfoDefaults
|
||||
} from './Forms/Screen2Information'
|
||||
import TypeFields, {
|
||||
defaultValues as typeFieldsDefaults,
|
||||
validationSchema as typeFieldsValidationSchema
|
||||
} from './Forms/TypeFields'
|
||||
import WizardSplash from './WizardSplash'
|
||||
|
||||
const LAST_STEP = 5
|
||||
|
||||
const styles = {
|
||||
stepper: {
|
||||
margin: [[16, 0, 14, 0]]
|
||||
},
|
||||
submit: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
margin: [['auto', 0, 24]]
|
||||
},
|
||||
button: {
|
||||
marginLeft: 'auto'
|
||||
},
|
||||
form: {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const getStep = step => {
|
||||
switch (step) {
|
||||
case 1:
|
||||
return {
|
||||
schema: nameOfReqSchema,
|
||||
Component: NameOfRequirement
|
||||
}
|
||||
case 2:
|
||||
return {
|
||||
schema: screen1InfoSchema,
|
||||
Component: Screen1Information
|
||||
}
|
||||
case 3:
|
||||
return { schema: chooseTypeSchema, Component: ChooseType }
|
||||
case 4:
|
||||
return {
|
||||
schema: screen2InfoSchema,
|
||||
Component: Screen2Information
|
||||
}
|
||||
case 5:
|
||||
return {
|
||||
schema: typeFieldsValidationSchema,
|
||||
Component: TypeFields
|
||||
}
|
||||
default:
|
||||
return {
|
||||
schema: {},
|
||||
Component: () => {
|
||||
return <h1>Default component step</h1>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nonEmptyStr = obj => obj.text && obj.text.length
|
||||
|
||||
const formatValues = (values, isEditing) => {
|
||||
const isChoiceList = values.inputType === 'choiceList'
|
||||
const choices = isChoiceList
|
||||
? isEditing
|
||||
? R.path(['listChoices'])(values)
|
||||
: R.map(o => o.text)(R.filter(nonEmptyStr)(values.listChoices) ?? [])
|
||||
: []
|
||||
|
||||
const hasInputLength = values.constraintType === 'length'
|
||||
const inputLength = hasInputLength ? values.inputLength : ''
|
||||
|
||||
let resObj = {
|
||||
name: values.requirementName,
|
||||
screen1: {
|
||||
text: values.screen1Text,
|
||||
title: values.screen1Title
|
||||
},
|
||||
screen2: {
|
||||
title: values.screen2Title,
|
||||
text: values.screen2Text
|
||||
},
|
||||
input: {
|
||||
type: values.inputType,
|
||||
constraintType: values.constraintType
|
||||
}
|
||||
}
|
||||
|
||||
if (isChoiceList) {
|
||||
resObj = R.assocPath(['input', 'choiceList'], choices, resObj)
|
||||
}
|
||||
|
||||
if (hasInputLength) {
|
||||
resObj = R.assocPath(['input', 'numDigits'], inputLength, resObj)
|
||||
}
|
||||
|
||||
if (values.inputLabel1) {
|
||||
resObj = R.assocPath(['input', 'label1'], values.inputLabel1, resObj)
|
||||
}
|
||||
|
||||
if (values.inputLabel2) {
|
||||
resObj = R.assocPath(['input', 'label2'], values.inputLabel2, resObj)
|
||||
}
|
||||
|
||||
if (isEditing) {
|
||||
resObj = R.assocPath(['id'], values.id, resObj)
|
||||
}
|
||||
|
||||
return resObj
|
||||
}
|
||||
|
||||
const makeEditingValues = it => {
|
||||
const { customRequest } = it
|
||||
return {
|
||||
id: it.id,
|
||||
requirementName: customRequest.name,
|
||||
screen1Title: customRequest.screen1.title,
|
||||
screen1Text: customRequest.screen1.text,
|
||||
screen2Title: customRequest.screen2.title,
|
||||
screen2Text: customRequest.screen2.text,
|
||||
inputType: customRequest.input.type,
|
||||
inputLabel1: customRequest.input.label1,
|
||||
inputLabel2: customRequest.input.label2,
|
||||
listChoices: customRequest.input.choiceList,
|
||||
constraintType: customRequest.input.constraintType,
|
||||
inputLength: customRequest.input.numDigits
|
||||
}
|
||||
}
|
||||
|
||||
const chooseNotNull = (a, b) => {
|
||||
if (!R.isNil(b)) return b
|
||||
return a
|
||||
}
|
||||
|
||||
const Wizard = ({ onClose, error = false, toBeEdited, onSave, hasError }) => {
|
||||
const classes = useStyles()
|
||||
const isEditing = !R.isNil(toBeEdited)
|
||||
const [step, setStep] = useState(isEditing ? 1 : 0)
|
||||
const stepOptions = getStep(step)
|
||||
const isLastStep = step === LAST_STEP
|
||||
|
||||
const onContinue = (values, actions) => {
|
||||
const showScreen2 =
|
||||
values.inputType === 'numerical' || values.inputType === 'choiceList'
|
||||
if (isEditing && step === 2) {
|
||||
return showScreen2
|
||||
? setStep(4)
|
||||
: onSave(formatValues(values, isEditing), isEditing)
|
||||
}
|
||||
if (isEditing && step === 4) {
|
||||
return onSave(formatValues(values, isEditing), isEditing)
|
||||
}
|
||||
if (step === 3) {
|
||||
return showScreen2 ? setStep(step + 1) : setStep(step + 2)
|
||||
}
|
||||
if (!isLastStep) {
|
||||
return setStep(step + 1)
|
||||
}
|
||||
return onSave(formatValues(values, isEditing), isEditing)
|
||||
}
|
||||
|
||||
const editingValues = isEditing ? makeEditingValues(toBeEdited) : {}
|
||||
const wizardTitle = isEditing
|
||||
? 'Editing custom requirement'
|
||||
: 'New custom requirement'
|
||||
return (
|
||||
<Modal
|
||||
title={step > 0 ? wizardTitle : ''}
|
||||
handleClose={onClose}
|
||||
width={520}
|
||||
height={620}
|
||||
open={true}>
|
||||
{step > 0 && (
|
||||
<Stepper
|
||||
className={classes.stepper}
|
||||
steps={LAST_STEP}
|
||||
currentStep={step}
|
||||
/>
|
||||
)}
|
||||
{step === 0 && !isEditing && <WizardSplash onContinue={onContinue} />}
|
||||
{step > 0 && (
|
||||
<Formik
|
||||
validateOnBlur={false}
|
||||
validateOnChange={false}
|
||||
enableReinitialize={true}
|
||||
onSubmit={onContinue}
|
||||
initialValues={R.mergeWith(
|
||||
chooseNotNull,
|
||||
{
|
||||
...nameOfReqDefaults,
|
||||
...screen1InfoDefaults,
|
||||
...screen2InfoDefaults,
|
||||
...chooseTypeDefaults,
|
||||
...typeFieldsDefaults
|
||||
},
|
||||
editingValues
|
||||
)}
|
||||
validationSchema={stepOptions.schema}>
|
||||
<Form className={classes.form} id={'custom-requirement-form'}>
|
||||
<stepOptions.Component />
|
||||
<div className={classes.submit}>
|
||||
{hasError && <ErrorMessage>Failed to save</ErrorMessage>}
|
||||
<Button className={classes.button} type="submit">
|
||||
{isLastStep ? 'Save' : 'Next'}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Formik>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default Wizard
|
||||
Loading…
Add table
Add a link
Reference in a new issue