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

View File

@@ -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 && (

View File

@@ -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;
} }

View File

@@ -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`)}

View File

@@ -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,
},
}); });
}; };

View File

@@ -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`)}

View File

@@ -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) ||

View File

@@ -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;