set fields touched when steps marked as visited

This commit is contained in:
Keith Grant 2020-05-07 16:36:34 -07:00
parent 59e3306a3c
commit 0b207e02ab
7 changed files with 70 additions and 53 deletions

View File

@ -45,14 +45,14 @@ function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
return (
<Formik initialValues={initialValues} onSubmit={submit} validate={validate}>
{({ validateForm, handleSubmit }) => (
{({ validateForm, setTouched, handleSubmit }) => (
<Wizard
isOpen
onClose={onCancel}
onSave={handleSubmit}
onNext={async (nextStep, prevStep) => {
if (nextStep.id === 'preview') {
visitAllSteps();
visitAllSteps(setTouched);
} else {
visitStep(prevStep.prevId);
}
@ -60,7 +60,7 @@ function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
}}
onGoToStep={async (newStep, prevStep) => {
if (newStep.id === 'preview') {
visitAllSteps();
visitAllSteps(setTouched);
} else {
visitStep(prevStep.prevId);
}

View File

@ -20,6 +20,11 @@ export default function useCredentialsStep(
validate,
isReady: true,
error: null,
setTouched: setFieldsTouched => {
setFieldsTouched({
credentials: true,
});
},
};
}

View File

@ -25,6 +25,11 @@ export default function useInventoryStep(config, resource, visitedSteps, i18n) {
validate,
isReady: true,
error: null,
setTouched: setFieldsTouched => {
setFieldsTouched({
inventory: true,
});
},
};
}

View File

@ -25,6 +25,17 @@ export default function useOtherPrompt(config, resource, visitedSteps, i18n) {
validate,
isReady: true,
error: null,
setTouched: setFieldsTouched => {
setFieldsTouched({
job_type: true,
limit: true,
verbosity: true,
diff_mode: true,
job_tags: true,
skip_tags: true,
extra_vars: true,
});
},
};
}

View File

@ -27,7 +27,9 @@ export default function usePreviewStep(
nextButtonText: i18n._(t`Launch`),
},
initialValues: {},
validate: () => ({}),
isReady: true,
error: null,
setTouched: () => {},
};
}

View File

@ -55,6 +55,16 @@ export default function useSurveyStep(config, resource, visitedSteps, i18n) {
survey,
isReady: !isLoading && !!survey,
error,
setTouched: setFieldsTouched => {
if (!survey) {
return;
}
const fields = {};
survey.spec.forEach(question => {
fields[`survey_${question.variable}`] = true;
});
setFieldsTouched(fields);
},
};
}

View File

@ -7,70 +7,53 @@ import usePreviewStep from './steps/usePreviewStep';
export default function useSteps(config, resource, i18n) {
const [visited, setVisited] = useState({});
const inventory = useInventoryStep(config, resource, visited, i18n);
const credentials = useCredentialsStep(config, resource, visited, i18n);
const otherPrompts = useOtherPromptsStep(config, resource, visited, i18n);
const survey = useSurveyStep(config, resource, visited, i18n);
const preview = usePreviewStep(
config,
resource,
survey.survey,
{}, // TODO: formErrors ?
i18n
const steps = [
useInventoryStep(config, resource, visited, i18n),
useCredentialsStep(config, resource, visited, i18n),
useOtherPromptsStep(config, resource, visited, i18n),
useSurveyStep(config, resource, visited, i18n),
];
steps.push(
usePreviewStep(
config,
resource,
steps[3].survey,
{}, // TODO: formErrors ?
i18n
)
);
// TODO useState for steps to track dynamic steps (credentialPasswords)?
const steps = [
inventory.step,
credentials.step,
otherPrompts.step,
survey.step,
preview.step,
].filter(step => step !== null);
const initialValues = {
...inventory.initialValues,
...credentials.initialValues,
...otherPrompts.initialValues,
...survey.initialValues,
};
const isReady =
inventory.isReady &&
credentials.isReady &&
otherPrompts.isReady &&
survey.isReady &&
preview.isReady;
const contentError =
inventory.error ||
credentials.error ||
otherPrompts.error ||
survey.error ||
preview.error;
// TODO: store error state in each step's hook.
// but continue to return values here (async?) so form errors can be returned
// out and set into Formik
const validate = values => {
const errors = {
...inventory.validate(values),
...credentials.validate(values),
...otherPrompts.validate(values),
...survey.validate(values),
const pfSteps = steps.map(s => s.step).filter(s => s != null);
const initialValues = steps.reduce((acc, cur) => {
return {
...acc,
...cur.initialValues,
};
// setFormErrors(errors);
}, {});
const isReady = !steps.some(s => !s.isReady);
const stepWithError = steps.find(s => s.error);
const contentError = stepWithError ? stepWithError.error : null;
const validate = values => {
const errors = steps.reduce((acc, cur) => {
return {
...acc,
...cur.validate(values),
};
}, {});
if (Object.keys(errors).length) {
return errors;
}
return false;
};
// TODO move visited flags into each step hook
return {
steps,
steps: pfSteps,
initialValues,
isReady,
validate,
visitStep: stepId => setVisited({ ...visited, [stepId]: true }),
visitAllSteps: () => {
visitAllSteps: setFieldsTouched => {
setVisited({
inventory: true,
credentials: true,
@ -78,6 +61,7 @@ export default function useSteps(config, resource, i18n) {
survey: true,
preview: true,
});
steps.forEach(s => s.setTouched(setFieldsTouched));
},
contentError,
};