adds edit functionality

This commit is contained in:
Alex Corey
2020-10-15 15:29:58 -04:00
committed by mabashian
parent 2545f14a93
commit 60751dfa16
7 changed files with 72 additions and 48 deletions
@@ -6,6 +6,7 @@ import { t } from '@lingui/macro';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import { parseVariableField } from '../../../util/yaml';
import mergeExtraVars, { maskPasswords } from '../mergeExtraVars'; import mergeExtraVars, { maskPasswords } from '../mergeExtraVars';
import getSurveyValues from '../getSurveyValues'; import getSurveyValues from '../getSurveyValues';
import PromptDetail from '../../PromptDetail'; import PromptDetail from '../../PromptDetail';
@@ -27,11 +28,12 @@ function PreviewStep({ resource, config, survey, formErrors, i18n }) {
const { values } = useFormikContext(); const { values } = useFormikContext();
const surveyValues = getSurveyValues(values); const surveyValues = getSurveyValues(values);
const overrides = { ...values }; const overrides = {
...values,
};
if (config.ask_variables_on_launch || config.survey_enabled) { if (config.ask_variables_on_launch || config.survey_enabled) {
const initialExtraVars = config.ask_variables_on_launch const initialExtraVars =
? overrides.extra_vars || '---' config.ask_variables_on_launch && (overrides.extra_vars || '---');
: resource.extra_vars;
if (survey && survey.spec) { if (survey && survey.spec) {
const passwordFields = survey.spec const passwordFields = survey.spec
.filter(q => q.type === 'password') .filter(q => q.type === 'password')
@@ -47,8 +49,8 @@ function PreviewStep({ resource, config, survey, formErrors, i18n }) {
// Api expects extra vars to be merged with the survey data. // Api expects extra vars to be merged with the survey data.
// We put the extra_data key/value pair on the values object here // We put the extra_data key/value pair on the values object here
// so that we don't have to do this loop again inside of the NodeAddModal.jsx // so that we don't have to do this loop again inside of the NodeAddModal.jsx
values.extra_data = overrides.extra_vars; values.extra_data =
overrides.extra_vars && parseVariableField(overrides?.extra_vars);
return ( return (
<Fragment> <Fragment>
{formErrors && ( {formErrors && (
@@ -8,7 +8,13 @@ import StepName from './StepName';
const STEP_ID = 'survey'; const STEP_ID = 'survey';
export default function useSurveyStep(config, i18n, visitedSteps, resource) { export default function useSurveyStep(
config,
i18n,
visitedSteps,
resource,
nodeToEdit
) {
const { values } = useFormikContext(); const { values } = useFormikContext();
const { result: survey, request: fetchSurvey, isLoading, error } = useRequest( const { result: survey, request: fetchSurvey, isLoading, error } = useRequest(
useCallback(async () => { useCallback(async () => {
@@ -48,7 +54,7 @@ export default function useSurveyStep(config, i18n, visitedSteps, resource) {
const formError = Object.keys(validate()).length > 0; const formError = Object.keys(validate()).length > 0;
return { return {
step: getStep(config, survey, validate, i18n, visitedSteps), step: getStep(config, survey, validate, i18n, visitedSteps),
initialValues: getInitialValues(config, survey, resource), initialValues: getInitialValues(config, survey, nodeToEdit),
validate, validate,
survey, survey,
isReady: !isLoading && !!survey, isReady: !isLoading && !!survey,
@@ -113,7 +119,7 @@ function getStep(config, survey, validate, i18n, visitedSteps) {
}; };
} }
function getInitialValues(config, survey, resource) { function getInitialValues(config, survey, nodeToEdit) {
if (!config.survey_enabled || !survey) { if (!config.survey_enabled || !survey) {
return {}; return {};
} }
@@ -126,11 +132,11 @@ function getInitialValues(config, survey, resource) {
} else { } else {
values[`survey_${question.variable}`] = question.default; values[`survey_${question.variable}`] = question.default;
} }
if (resource?.extra_data) { if (nodeToEdit?.extra_data) {
Object.entries(resource?.extra_data).forEach(([key, value]) => { Object.entries(nodeToEdit?.extra_data).forEach(([key, value]) => {
if (key === question.variable) { if (key === question.variable) {
if (question.type === 'multiselect') { if (question.type === 'multiselect') {
values[`survey_${question.variable}`] = value.split('\n'); values[`survey_${question.variable}`] = value;
} else { } else {
values[`survey_${question.variable}`] = value; values[`survey_${question.variable}`] = value;
} }
@@ -143,7 +143,7 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
value={toTitleCase(overrides.job_type)} value={toTitleCase(overrides.job_type)}
/> />
)} )}
{overrides?.credentials && ( {overrides?.credentials?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
label={i18n._(t`Credentials`)} label={i18n._(t`Credentials`)}
@@ -2,17 +2,37 @@ import React, { useContext } from 'react';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { WorkflowDispatchContext } from '../../../../../contexts/Workflow'; import { WorkflowDispatchContext } from '../../../../../contexts/Workflow';
import { getAddedAndRemoved } from '../../../../../util/lists';
import NodeModal from './NodeModal'; import NodeModal from './NodeModal';
function NodeEditModal({ i18n }) { function NodeEditModal({ i18n }) {
const dispatch = useContext(WorkflowDispatchContext); const dispatch = useContext(WorkflowDispatchContext);
const updateNode = resource => { const updateNode = (values, linkType, config) => {
const { added, removed } = getAddedAndRemoved(
config?.defaults?.credentials,
values?.credentials
);
if (added?.length > 0) {
values.addedCredentals = added;
}
if (removed?.length > 0) {
values.removedCredentals = removed;
}
values.inventory = values?.inventory?.id;
delete values.linkType;
const node = {
nodeResource: values.nodeResource,
};
if (
values?.nodeType === 'job_template' ||
values?.nodeType === 'workflow_job_template'
) {
node.promptValues = values;
}
dispatch({ dispatch({
type: 'UPDATE_NODE', type: 'UPDATE_NODE',
node: { node,
nodeResource: resource,
},
}); });
}; };
@@ -49,11 +49,7 @@ function NodeModalForm({ askLinkType, i18n, onSave, title, credentialError }) {
const history = useHistory(); const history = useHistory();
const dispatch = useContext(WorkflowDispatchContext); const dispatch = useContext(WorkflowDispatchContext);
const { nodeToEdit } = useContext(WorkflowStateContext); const { nodeToEdit } = useContext(WorkflowStateContext);
const { const { values, setTouched, validateForm } = useFormikContext();
values,
setTouched,
validateForm,
} = useFormikContext();
const [triggerNext, setTriggerNext] = useState(0); const [triggerNext, setTriggerNext] = useState(0);
@@ -149,7 +145,11 @@ function NodeModalForm({ askLinkType, i18n, onSave, title, credentialError }) {
}, },
]), ]),
]; ];
const nextButtonText = activeStep =>
activeStep.id === steps[steps?.length - 1]?.id ||
activeStep.name === 'Preview'
? i18n._(t`Save`)
: i18n._(t`Next`);
const CustomFooter = ( const CustomFooter = (
<WizardFooter> <WizardFooter>
<WizardContextConsumer> <WizardContextConsumer>
@@ -158,23 +158,25 @@ function NodeModalForm({ askLinkType, i18n, onSave, title, credentialError }) {
<NodeNextButton <NodeNextButton
triggerNext={triggerNext} triggerNext={triggerNext}
activeStep={activeStep} activeStep={activeStep}
aria-label={nextButtonText(activeStep)}
onNext={onNext} onNext={onNext}
onClick={() => setTriggerNext(triggerNext + 1)} onClick={() => setTriggerNext(triggerNext + 1)}
buttonText={ buttonText={nextButtonText(activeStep)}
activeStep.id === steps[steps?.length - 1]?.id ||
activeStep.name === 'Preview'
? i18n._(t`Save`)
: i18n._(t`Next`)
}
/> />
{activeStep && activeStep.id !== steps[0]?.id && ( {activeStep && activeStep.id !== steps[0]?.id && (
<Button id="back-node-modal" variant="secondary" onClick={onBack}> <Button
id="back-node-modal"
variant="secondary"
aria-label={i18n._(t`Back`)}
onClick={onBack}
>
{i18n._(t`Back`)} {i18n._(t`Back`)}
</Button> </Button>
)} )}
<Button <Button
id="cancel-node-modal" id="cancel-node-modal"
variant="link" variant="link"
aria-label={i18n._(t`Cancel`)}
onClick={handleCancel} onClick={handleCancel}
> >
{i18n._(t`Cancel`)} {i18n._(t`Cancel`)}
@@ -5,19 +5,14 @@ import NodeTypeStep from './NodeTypeStep';
const STEP_ID = 'nodeType'; const STEP_ID = 'nodeType';
export default function useNodeTypeStep(i18n, resource, nodeToEdit) { export default function useNodeTypeStep(i18n, nodeToEdit) {
const [, meta] = useField('nodeType'); const [, meta] = useField('nodeType');
const [approvalNameField] = useField('approvalName'); const [approvalNameField] = useField('approvalName');
const [nodeTypeField, ,] = useField('nodeType'); const [nodeTypeField, ,] = useField('nodeType');
const [nodeResouceField] = useField('nodeResource'); const [nodeResouceField] = useField('nodeResource');
return { return {
step: getStep( step: getStep(i18n, nodeTypeField, approvalNameField, nodeResouceField),
i18n,
nodeTypeField,
approvalNameField,
nodeResouceField
),
initialValues: getInitialValues(nodeToEdit), initialValues: getInitialValues(nodeToEdit),
isReady: true, isReady: true,
contentError: null, contentError: null,
@@ -29,12 +24,7 @@ export default function useNodeTypeStep(i18n, resource, nodeToEdit) {
}, },
}; };
} }
function getStep( function getStep(i18n, nodeTypeField, approvalNameField, nodeResouceField) {
i18n,
nodeTypeField,
approvalNameField,
nodeResouceField
) {
const isEnabled = () => { const isEnabled = () => {
if ( if (
(nodeTypeField.value !== 'approval' && nodeResouceField.value === null) || (nodeTypeField.value !== 'approval' && nodeResouceField.value === null) ||
@@ -29,8 +29,15 @@ export default function useWorkflowNodeSteps(
), ),
useCredentialsStep(config, i18n, resource, nodeToEdit?.originalNodeObject), useCredentialsStep(config, i18n, resource, nodeToEdit?.originalNodeObject),
useOtherPromptsStep(config, i18n, resource, nodeToEdit?.originalNodeObject), useOtherPromptsStep(config, i18n, resource, nodeToEdit?.originalNodeObject),
useSurveyStep(config, i18n, visited, resource), useSurveyStep(
config,
i18n,
visited,
resource,
nodeToEdit?.originalNodeObject
),
]; ];
const { resetForm, values: formikValues } = useFormikContext(); const { resetForm, values: formikValues } = useFormikContext();
const hasErrors = steps.some(step => step.formError); const hasErrors = steps.some(step => step.formError);
const surveyStepIndex = steps.findIndex(step => step.survey); const surveyStepIndex = steps.findIndex(step => step.survey);
@@ -66,10 +73,7 @@ export default function useWorkflowNodeSteps(
}); });
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [ }, [config, isReady]);
config,
isReady,
]);
const stepWithError = steps.find(s => s.contentError); const stepWithError = steps.find(s => s.contentError);
const contentError = stepWithError ? stepWithError.contentError : null; const contentError = stepWithError ? stepWithError.contentError : null;