diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.jsx index 81478eb9a4..be61a0ee43 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateEdit/WorkflowJobTemplateEdit.jsx @@ -19,7 +19,7 @@ function WorkflowJobTemplateEdit({ template }) { webhook_key, ...templatePayload } = values; - templatePayload.inventory = inventory?.id; + templatePayload.inventory = inventory?.id || null; templatePayload.organization = organization?.id; templatePayload.webhook_credential = webhook_credential?.id || null; diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx index 50aca155b6..8306b849cf 100644 --- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx +++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx @@ -1,13 +1,13 @@ import React, { useState } from 'react'; import { t } from '@lingui/macro'; - import PropTypes, { shape } from 'prop-types'; import { withI18n } from '@lingui/react'; import { useField, withFormik } from 'formik'; -import { Form, FormGroup, Checkbox } from '@patternfly/react-core'; +import { Form, FormGroup, Checkbox, TextInput } from '@patternfly/react-core'; import { required } from '../../../util/validators'; +import FieldWithPrompt from '../../../components/FieldWithPrompt'; import FormField, { FieldTooltip, FormSubmitError, @@ -36,19 +36,20 @@ function WorkflowJobTemplateForm({ i18n, submitError, }) { - const [hasContentError, setContentError] = useState(null); - - const [organizationField, organizationMeta, organizationHelpers] = useField( - 'organization' + const [enableWebhooks, setEnableWebhooks] = useState( + Boolean(template.webhook_service) ); + const [hasContentError, setContentError] = useState(null); + const [askInventoryOnLaunchField] = useField('ask_inventory_on_launch'); const [inventoryField, inventoryMeta, inventoryHelpers] = useField( 'inventory' ); const [labelsField, , labelsHelpers] = useField('labels'); - - const [enableWebhooks, setEnableWebhooks] = useState( - Boolean(template.webhook_service) + const [limitField, limitMeta, limitHelpers] = useField('limit'); + const [organizationField, organizationMeta, organizationHelpers] = useField( + 'organization' ); + const [scmField, , scmHelpers] = useField('scm_branch'); if (hasContentError) { return ; @@ -79,39 +80,74 @@ function WorkflowJobTemplateForm({ value={organizationField.value} isValid={!organizationMeta.error} /> - - + + inventoryHelpers.setTouched()} onChange={value => { - inventoryHelpers.setValue(value || null); + inventoryHelpers.setValue(value); + }} + required={askInventoryOnLaunchField.value} + touched={inventoryMeta.touched} + error={inventoryMeta.error} + /> + {(inventoryMeta.touched || askInventoryOnLaunchField.value) && + inventoryMeta.error && ( +
+ {inventoryMeta.error} +
+ )} +
+ + + { + limitHelpers.setValue(value); }} /> -
- - + + + > + { + scmHelpers.setValue(value); + }} + /> + @@ -133,6 +169,7 @@ function WorkflowJobTemplateForm({ id="wfjt-variables" name="extra_vars" label={i18n._(t`Variables`)} + promptId="template-ask-variables-on-launch" tooltip={i18n._( t`Pass extra command line variables to the playbook. This is the -e or --extra-vars command line parameter for ansible-playbook. Provide key/value pairs using either YAML or JSON. Refer to the Ansible Tower documentation for example syntax.` )} diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx index 4cddaec8e7..f572c320c4 100644 --- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx +++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx @@ -114,9 +114,9 @@ describe('', () => { 'FormField[name="name"]', 'FormField[name="description"]', 'FormGroup[label="Organization"]', - 'FormGroup[label="Inventory"]', - 'FormField[name="limit"]', - 'FormField[name="scm_branch"]', + 'FieldWithPrompt[label="Inventory"]', + 'FieldWithPrompt[label="Limit"]', + 'FieldWithPrompt[label="Source control branch"]', 'FormGroup[label="Labels"]', 'VariablesField', ]; @@ -137,11 +137,6 @@ describe('', () => { element: 'wfjt-description', value: { value: 'new bar', name: 'description' }, }, - { element: 'wfjt-limit', value: { value: 1234567890, name: 'limit' } }, - { - element: 'wfjt-scm_branch', - value: { value: 'new branch', name: 'scm_branch' }, - }, ]; const changeInputs = async ({ element, value }) => { wrapper.find(`input#${element}`).simulate('change', { @@ -177,6 +172,26 @@ describe('', () => { inputsToChange.map(input => assertChanges(input)); }); + test('test changes in FieldWithPrompt', async () => { + await act(async () => { + wrapper.find('TextInputBase#text-wfjt-scm-branch').prop('onChange')( + 'main' + ); + wrapper.find('TextInputBase#text-wfjt-limit').prop('onChange')( + 1234567890 + ); + }); + + wrapper.update(); + + expect(wrapper.find('input#text-wfjt-scm-branch').prop('value')).toEqual( + 'main' + ); + expect(wrapper.find('input#text-wfjt-limit').prop('value')).toEqual( + 1234567890 + ); + }); + test('webhooks and enable concurrent jobs functions properly', async () => { act(() => { wrapper.find('Checkbox[aria-label="Enable Webhook"]').invoke('onChange')(