mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 06:51:10 +03:00
Adds formik hook functionality to wfjt form
This commit is contained in:
parent
dbe949a2c2
commit
8b69b08991
@ -12,7 +12,19 @@ function WorkflowJobTemplateAdd() {
|
||||
const [formSubmitError, setFormSubmitError] = useState(null);
|
||||
|
||||
const handleSubmit = async values => {
|
||||
const { labels, organizationId, ...remainingValues } = values;
|
||||
const {
|
||||
labels,
|
||||
inventory,
|
||||
organization,
|
||||
webhook_credential,
|
||||
webhookKey,
|
||||
...remainingValues
|
||||
} = values;
|
||||
remainingValues.inventory = inventory?.id;
|
||||
remainingValues.organization = organization?.id;
|
||||
remainingValues.webhook_credential = webhook_credential?.id;
|
||||
const organizationId =
|
||||
organization?.id || inventory?.summary_fields?.organization.id || null;
|
||||
try {
|
||||
const {
|
||||
data: { id },
|
||||
|
@ -11,10 +11,23 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
|
||||
const [formSubmitError, setFormSubmitError] = useState(null);
|
||||
|
||||
const handleSubmit = async values => {
|
||||
const { labels, ...remainingValues } = values;
|
||||
const {
|
||||
labels,
|
||||
inventory,
|
||||
organization,
|
||||
webhook_credential,
|
||||
webhookKey,
|
||||
...remainingValues
|
||||
} = values;
|
||||
remainingValues.inventory = inventory?.id;
|
||||
remainingValues.organization = organization?.id;
|
||||
remainingValues.webhook_credential = webhook_credential?.id || null;
|
||||
|
||||
const formOrgId =
|
||||
organization?.id || inventory?.summary_fields?.organization.id || null;
|
||||
try {
|
||||
await Promise.all(
|
||||
await submitLabels(labels, values.organization, template.organization)
|
||||
await submitLabels(labels, formOrgId, template.organization)
|
||||
);
|
||||
await WorkflowJobTemplatesAPI.update(template.id, remainingValues);
|
||||
history.push(`/templates/workflow_job_template/${template.id}/details`);
|
||||
@ -60,7 +73,7 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
|
||||
handleSubmit={handleSubmit}
|
||||
handleCancel={handleCancel}
|
||||
template={template}
|
||||
webhook_key={webhook_key}
|
||||
webhookKey={webhook_key}
|
||||
submitError={formSubmitError}
|
||||
/>
|
||||
</CardBody>
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { useRouteMatch, useParams } from 'react-router-dom';
|
||||
import { useRouteMatch, useParams, withRouter } from 'react-router-dom';
|
||||
|
||||
import { func, shape } from 'prop-types';
|
||||
import PropTypes, { shape } from 'prop-types';
|
||||
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { Formik, Field } from 'formik';
|
||||
import { useField, withFormik } from 'formik';
|
||||
import {
|
||||
Form,
|
||||
FormGroup,
|
||||
@ -40,38 +40,49 @@ import ContentError from '@components/ContentError';
|
||||
import CheckboxField from '@components/FormField/CheckboxField';
|
||||
import LabelSelect from './LabelSelect';
|
||||
|
||||
const urlOrigin = window.location.origin;
|
||||
function WorkflowJobTemplateForm({
|
||||
handleSubmit,
|
||||
handleCancel,
|
||||
i18n,
|
||||
template = {},
|
||||
webhook_key,
|
||||
submitError,
|
||||
}) {
|
||||
const urlOrigin = window.location.origin;
|
||||
const { id } = useParams();
|
||||
const wfjtAddMatch = useRouteMatch('/templates/workflow_job_template/add');
|
||||
|
||||
const [hasContentError, setContentError] = useState(null);
|
||||
const [webhook_url, setWebhookUrl] = useState(
|
||||
template?.related?.webhook_receiver
|
||||
? `${urlOrigin}${template.related.webhook_receiver}`
|
||||
: ''
|
||||
|
||||
const [organizationField, organizationMeta, organizationHelpers] = useField(
|
||||
'organization'
|
||||
);
|
||||
const [inventory, setInventory] = useState(
|
||||
template?.summary_fields?.inventory || null
|
||||
const [inventoryField, inventoryMeta, inventoryHelpers] = useField(
|
||||
'inventory'
|
||||
);
|
||||
const [organization, setOrganization] = useState(
|
||||
template?.summary_fields?.organization || null
|
||||
const [labelsField, , labelsHelpers] = useField('labels');
|
||||
|
||||
const [
|
||||
webhookServiceField,
|
||||
webhookServiceMeta,
|
||||
webhookServiceHelpers,
|
||||
] = useField('webhook_service');
|
||||
|
||||
const [webhookKeyField, webhookKeyMeta, webhookKeyHelpers] = useField(
|
||||
'webhookKey'
|
||||
);
|
||||
const [webhookCredential, setWebhookCredential] = useState(
|
||||
template?.summary_fields?.webhook_credential || null
|
||||
|
||||
const [hasWebhooks, setHasWebhooks] = useState(
|
||||
Boolean(webhookServiceField.value)
|
||||
);
|
||||
const [webhookKey, setWebHookKey] = useState(webhook_key);
|
||||
const [webhookService, setWebHookService] = useState(
|
||||
template.webhook_service || ''
|
||||
|
||||
const [
|
||||
webhookCredentialField,
|
||||
webhookCredentialMeta,
|
||||
webhookCredentialHelpers,
|
||||
] = useField('webhook_credential');
|
||||
|
||||
const [webhookUrlField, webhookUrlMeta, webhookUrlHelpers] = useField(
|
||||
'webhook_url'
|
||||
);
|
||||
const [hasWebhooks, setHasWebhooks] = useState(Boolean(webhookService));
|
||||
|
||||
const webhookServiceOptions = [
|
||||
{
|
||||
@ -93,6 +104,38 @@ function WorkflowJobTemplateForm({
|
||||
isDisabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const storeWebhookValues = webhookServiceValue => {
|
||||
if (
|
||||
webhookServiceValue === webhookServiceMeta.initialValue ||
|
||||
webhookServiceValue === ''
|
||||
) {
|
||||
webhookCredentialHelpers.setValue(webhookCredentialMeta.initialValue);
|
||||
webhookUrlHelpers.setValue(webhookUrlMeta.initialValue);
|
||||
webhookServiceHelpers.setValue(webhookServiceMeta.initialValue);
|
||||
webhookKeyHelpers.setValue(webhookKeyMeta.initialValue);
|
||||
} else {
|
||||
webhookCredentialHelpers.setValue(null);
|
||||
webhookUrlHelpers.setValue(
|
||||
`${urlOrigin}/api/v2/workflow_job_templates/${id}/${webhookServiceValue}/`
|
||||
);
|
||||
webhookKeyHelpers.setValue(
|
||||
i18n._(t`a new webhook key will be generated on save.`).toUpperCase()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleWebhookEnablement = (enabledWebhooks, webhookServiceValue) => {
|
||||
if (!enabledWebhooks) {
|
||||
webhookCredentialHelpers.setValue(null);
|
||||
webhookServiceHelpers.setValue('');
|
||||
webhookUrlHelpers.setValue('');
|
||||
webhookKeyHelpers.setValue('');
|
||||
} else {
|
||||
storeWebhookValues(webhookServiceValue);
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
request: loadCredentialType,
|
||||
error: contentError,
|
||||
@ -101,15 +144,15 @@ function WorkflowJobTemplateForm({
|
||||
} = useRequest(
|
||||
useCallback(async () => {
|
||||
let results;
|
||||
if (webhookService) {
|
||||
if (webhookServiceField.value) {
|
||||
results = await CredentialTypesAPI.read({
|
||||
namespace: `${webhookService}_token`,
|
||||
namespace: `${webhookServiceField.value}_token`,
|
||||
});
|
||||
// TODO: Consider how to handle the situation where the results returns
|
||||
// and empty array, or any of the other values is undefined or null (data, results, id)
|
||||
}
|
||||
return results?.data?.results[0]?.id;
|
||||
}, [webhookService])
|
||||
}, [webhookServiceField.value])
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -124,66 +167,12 @@ function WorkflowJobTemplateForm({
|
||||
const {
|
||||
data: { webhook_key: key },
|
||||
} = await WorkflowJobTemplatesAPI.updateWebhookKey(id);
|
||||
setWebHookKey(key);
|
||||
webhookKeyHelpers.setValue(key);
|
||||
} catch (err) {
|
||||
setContentError(err);
|
||||
}
|
||||
};
|
||||
|
||||
let initialWebhookKey = webhook_key;
|
||||
const initialWebhookCredential = template?.summary_fields?.webhook_credential;
|
||||
|
||||
const storeWebhookValues = (form, webhookServiceValue) => {
|
||||
if (
|
||||
webhookServiceValue === form.initialValues.webhook_service ||
|
||||
webhookServiceValue === ''
|
||||
) {
|
||||
form.setFieldValue(
|
||||
'webhook_credential',
|
||||
form.initialValues.webhook_credential
|
||||
);
|
||||
setWebhookCredential(initialWebhookCredential);
|
||||
|
||||
setWebhookUrl(
|
||||
template?.related?.webhook_receiver
|
||||
? `${urlOrigin}${template.related.webhook_receiver}`
|
||||
: ''
|
||||
);
|
||||
form.setFieldValue('webhook_service', form.initialValues.webhook_service);
|
||||
setWebHookService(form.initialValues.webhook_service);
|
||||
|
||||
setWebHookKey(initialWebhookKey);
|
||||
} else {
|
||||
form.setFieldValue('webhook_credential', null);
|
||||
setWebhookCredential(null);
|
||||
|
||||
setWebhookUrl(
|
||||
`${urlOrigin}/api/v2/workflow_job_templates/${template.id}/${webhookServiceValue}/`
|
||||
);
|
||||
|
||||
setWebHookKey(
|
||||
i18n._(t`a new webhook key will be generated on save.`).toUpperCase()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleWebhookEnablement = (
|
||||
form,
|
||||
enabledWebhooks,
|
||||
webhookServiceValue
|
||||
) => {
|
||||
if (!enabledWebhooks) {
|
||||
initialWebhookKey = webhookKey;
|
||||
form.setFieldValue('webhook_credential', null);
|
||||
form.setFieldValue('webhook_service', '');
|
||||
setWebhookUrl('');
|
||||
setWebHookService('');
|
||||
setWebHookKey('');
|
||||
} else {
|
||||
storeWebhookValues(form, webhookServiceValue);
|
||||
}
|
||||
};
|
||||
|
||||
if (hasContentError || contentError) {
|
||||
return <ContentError error={contentError || hasContentError} />;
|
||||
}
|
||||
@ -193,312 +182,213 @@ function WorkflowJobTemplateForm({
|
||||
}
|
||||
|
||||
return (
|
||||
<Formik
|
||||
onSubmit={values => {
|
||||
if (values.webhook_service === '') {
|
||||
values.webhook_credential = '';
|
||||
}
|
||||
return handleSubmit(values);
|
||||
}}
|
||||
initialValues={{
|
||||
name: template.name || '',
|
||||
description: template.description || '',
|
||||
inventory: template?.summary_fields?.inventory?.id || null,
|
||||
organization: template?.summary_fields?.organization?.id || null,
|
||||
labels: template.summary_fields?.labels?.results || [],
|
||||
extra_vars: template.extra_vars || '---',
|
||||
limit: template.limit || '',
|
||||
scm_branch: template.scm_branch || '',
|
||||
allow_simultaneous: template.allow_simultaneous || false,
|
||||
webhook_credential:
|
||||
template?.summary_fields?.webhook_credential?.id || null,
|
||||
webhook_service: template.webhook_service || '',
|
||||
ask_limit_on_launch: template.ask_limit_on_launch || false,
|
||||
ask_inventory_on_launch: template.ask_inventory_on_launch || false,
|
||||
ask_variables_on_launch: template.ask_variables_on_launch || false,
|
||||
ask_scm_branch_on_launch: template.ask_scm_branch_on_launch || false,
|
||||
}}
|
||||
>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormColumnLayout>
|
||||
<FormField
|
||||
id="wfjt-name"
|
||||
name="name"
|
||||
type="text"
|
||||
label={i18n._(t`Name`)}
|
||||
validate={required(null, i18n)}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="wfjt-description"
|
||||
name="description"
|
||||
type="text"
|
||||
label={i18n._(t`Description`)}
|
||||
/>
|
||||
<Field
|
||||
id="wfjt-organization"
|
||||
label={i18n._(t`Organization`)}
|
||||
name="organization"
|
||||
>
|
||||
{({ form }) => (
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={form.errors.organization}
|
||||
onChange={value => {
|
||||
form.setFieldValue('organization', value?.id || null);
|
||||
setOrganization(value);
|
||||
}}
|
||||
value={organization}
|
||||
isValid={!form.errors.organization}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Field name="inventory">
|
||||
{({ form }) => (
|
||||
<FormGroup
|
||||
label={i18n._(t`Inventory`)}
|
||||
fieldId="wfjt-inventory"
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Select an inventory for the workflow. This inventory is applied to all job template nodes that prompt for an inventory.`
|
||||
)}
|
||||
/>
|
||||
<InventoryLookup
|
||||
value={inventory}
|
||||
isValid={!form.errors.inventory}
|
||||
helperTextInvalid={form.errors.inventory}
|
||||
onChange={value => {
|
||||
form.setFieldValue('inventory', value?.id || null);
|
||||
setInventory(value);
|
||||
form.setFieldValue('organizationId', value?.organization);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FormField
|
||||
type="text"
|
||||
name="limit"
|
||||
id="wfjt-limit"
|
||||
label={i18n._(t`Limit`)}
|
||||
tooltip={i18n._(
|
||||
t`Provide a host pattern to further constrain the list of hosts that will be managed or affected by the workflow. This limit is applied to all job template nodes that prompt for a limit. Refer to Ansible documentation for more information and examples on patterns.`
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
type="text"
|
||||
label={i18n._(t`Source Control Branch`)}
|
||||
tooltip={i18n._(
|
||||
t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch.`
|
||||
)}
|
||||
id="wfjt-scm_branch"
|
||||
name="scm_branch"
|
||||
/>
|
||||
</FormColumnLayout>
|
||||
<FormFullWidthLayout>
|
||||
<Field name="labels">
|
||||
{({ form, field }) => (
|
||||
<FormGroup
|
||||
label={i18n._(t`Labels`)}
|
||||
helperTextInvalid={form.errors.webhook_service}
|
||||
isValid={!(form.touched.labels || form.errors.labels)}
|
||||
name="wfjt-labels"
|
||||
fieldId="wfjt-labels"
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(t`Optional labels that describe this job template,
|
||||
<Form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<FormColumnLayout>
|
||||
<FormField
|
||||
id="wfjt-name"
|
||||
name="name"
|
||||
type="text"
|
||||
label={i18n._(t`Name`)}
|
||||
validate={required(null, i18n)}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="wfjt-description"
|
||||
name="description"
|
||||
type="text"
|
||||
label={i18n._(t`Description`)}
|
||||
/>
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={organizationMeta.error}
|
||||
onChange={value => {
|
||||
organizationHelpers.setValue(value || null);
|
||||
}}
|
||||
value={organizationField.value}
|
||||
isValid={!organizationMeta.error}
|
||||
/>
|
||||
<FormGroup label={i18n._(t`Inventory`)} fieldId="wfjt-inventory">
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Select an inventory for the workflow. This inventory is applied to all job template nodes that prompt for an inventory.`
|
||||
)}
|
||||
/>
|
||||
<InventoryLookup
|
||||
value={inventoryField.value}
|
||||
isValid={!inventoryMeta.error}
|
||||
helperTextInvalid={inventoryMeta.error}
|
||||
onChange={value => {
|
||||
inventoryHelpers.setValue(value || null);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormField
|
||||
type="text"
|
||||
name="limit"
|
||||
id="wfjt-limit"
|
||||
label={i18n._(t`Limit`)}
|
||||
tooltip={i18n._(
|
||||
t`Provide a host pattern to further constrain the list of hosts that will be managed or affected by the workflow. This limit is applied to all job template nodes that prompt for a limit. Refer to Ansible documentation for more information and examples on patterns.`
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
type="text"
|
||||
label={i18n._(t`SCM Branch`)}
|
||||
tooltip={i18n._(
|
||||
t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch.`
|
||||
)}
|
||||
id="wfjt-scm_branch"
|
||||
name="scm_branch"
|
||||
/>
|
||||
</FormColumnLayout>
|
||||
<FormFullWidthLayout>
|
||||
<FormGroup label={i18n._(t`Labels`)} fieldId="template-labels">
|
||||
<FieldTooltip
|
||||
content={i18n._(t`Optional labels that describe this job template,
|
||||
such as 'dev' or 'test'. Labels can be used to group and filter
|
||||
job templates and completed jobs.`)}
|
||||
/>
|
||||
<LabelSelect
|
||||
value={field.value}
|
||||
onChange={labels => form.setFieldValue('labels', labels)}
|
||||
onError={err => setContentError(err)}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</FormFullWidthLayout>
|
||||
<FormFullWidthLayout>
|
||||
<VariablesField
|
||||
id="wfjt-variables"
|
||||
name="extra_vars"
|
||||
label={i18n._(t`Variables`)}
|
||||
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.`
|
||||
)}
|
||||
/>
|
||||
</FormFullWidthLayout>
|
||||
<FormCheckboxLayout
|
||||
fieldId="options"
|
||||
isInline
|
||||
label={i18n._(t`Options`)}
|
||||
>
|
||||
<Field id="wfjt-webhooks" name="hasWebhooks">
|
||||
{({ form }) => (
|
||||
<Checkbox
|
||||
aria-label={i18n._(t`Enable Webhooks`)}
|
||||
label={
|
||||
<span>
|
||||
{i18n._(t`Enable Webhooks`)}
|
||||
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Enable webhooks for this workflow job template.`
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
id="wfjt-enabled-webhooks"
|
||||
isChecked={
|
||||
Boolean(form.values.webhook_service) || hasWebhooks
|
||||
}
|
||||
onChange={checked => {
|
||||
setHasWebhooks(checked);
|
||||
handleWebhookEnablement(form, checked, webhookService);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
<CheckboxField
|
||||
name="allow_simultaneous"
|
||||
id="allow_simultaneous"
|
||||
tooltip={i18n._(
|
||||
t`If enabled, simultaneous runs of this workflow job template will be allowed.`
|
||||
)}
|
||||
label={i18n._(t`Enable Concurrent Jobs`)}
|
||||
/>
|
||||
</FormCheckboxLayout>
|
||||
{hasWebhooks && (
|
||||
<FormColumnLayout>
|
||||
<Field name="webhook_service">
|
||||
{({ form, field }) => (
|
||||
<FormGroup
|
||||
name="webhook_service"
|
||||
fieldId="webhook_service"
|
||||
helperTextInvalid={form.errors.webhook_service}
|
||||
isValid={
|
||||
!(
|
||||
form.touched.webhook_service ||
|
||||
form.errors.webhook_service
|
||||
)
|
||||
}
|
||||
label={i18n._(t`Webhook Service`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(t`Select a webhook service`)}
|
||||
/>
|
||||
<AnsibleSelect
|
||||
id="webhook_service"
|
||||
data={webhookServiceOptions}
|
||||
value={field.value}
|
||||
onChange={(event, val) => {
|
||||
setWebHookService(val);
|
||||
storeWebhookValues(form, val);
|
||||
|
||||
form.setFieldValue('webhook_service', val);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
{!wfjtAddMatch && (
|
||||
<>
|
||||
<FormGroup
|
||||
type="text"
|
||||
fieldId="wfjt-webhookURL"
|
||||
label={i18n._(t`Webhook URL`)}
|
||||
id="wfjt-webhook-url"
|
||||
name="webhook_url"
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Webhook services can launch jobs with this workflow job template by making a POST request to this URL.`
|
||||
)}
|
||||
/>
|
||||
<TextInput
|
||||
aria-label={i18n._(t`Webhook URL`)}
|
||||
value={webhook_url}
|
||||
isReadOnly
|
||||
/>
|
||||
</FormGroup>
|
||||
<Field>
|
||||
{({ form }) => (
|
||||
<FormGroup
|
||||
fieldId="wfjt-webhook-key"
|
||||
type="text"
|
||||
id="wfjt-webhook-key"
|
||||
name="webhook_key"
|
||||
isValid={
|
||||
!(form.touched.webhook_key || form.errors.webhook_key)
|
||||
}
|
||||
helperTextInvalid={form.errors.webhook_service}
|
||||
label={i18n._(t`Webhook Key`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Webhook services can use this as a shared secret.`
|
||||
)}
|
||||
/>
|
||||
<InputGroup>
|
||||
<TextInput
|
||||
isReadOnly
|
||||
aria-label="wfjt-webhook-key"
|
||||
value={webhookKey}
|
||||
/>
|
||||
<Button variant="tertiary" onClick={changeWebhookKey}>
|
||||
<SyncAltIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</>
|
||||
)}
|
||||
{credTypeId && (
|
||||
// TODO: Consider how to handle the situation where the results returns
|
||||
// an empty array, or any of the other values is undefined or null
|
||||
// (data, results, id)
|
||||
<Field name="webhook_credential">
|
||||
{({ form }) => (
|
||||
<CredentialLookup
|
||||
label={i18n._(t`Webhook Credential`)}
|
||||
tooltip={i18n._(
|
||||
t`Optionally select the credential to use to send status updates back to the webhook service.`
|
||||
)}
|
||||
credentialTypeId={credTypeId}
|
||||
onChange={value => {
|
||||
form.setFieldValue(
|
||||
'webhook_credential',
|
||||
value?.id || null
|
||||
);
|
||||
setWebhookCredential(value);
|
||||
}}
|
||||
isValid={!form.errors.webhook_credential}
|
||||
helperTextInvalid={form.errors.webhook_credential}
|
||||
value={webhookCredential}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
</FormColumnLayout>
|
||||
)}
|
||||
{submitError && <FormSubmitError error={submitError} />}
|
||||
<FormActionGroup
|
||||
onCancel={handleCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
/>
|
||||
</Form>
|
||||
<LabelSelect
|
||||
value={labelsField.value}
|
||||
onChange={labels => labelsHelpers.setValue(labels)}
|
||||
onError={setContentError}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormFullWidthLayout>
|
||||
<FormFullWidthLayout>
|
||||
<VariablesField
|
||||
id="wfjt-variables"
|
||||
name="extra_vars"
|
||||
label={i18n._(t`Variables`)}
|
||||
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.`
|
||||
)}
|
||||
/>
|
||||
</FormFullWidthLayout>
|
||||
<FormCheckboxLayout fieldId="options" isInline label={i18n._(t`Options`)}>
|
||||
<Checkbox
|
||||
aria-label={i18n._(t`Enable Webhook`)}
|
||||
label={
|
||||
<span>
|
||||
{i18n._(t`Enable Webhook`)}
|
||||
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Enable webhook for this workflow job template.`
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
id="wfjt-enabled-webhooks"
|
||||
isChecked={Boolean(webhookServiceField.value) || hasWebhooks}
|
||||
onChange={checked => {
|
||||
setHasWebhooks(checked);
|
||||
handleWebhookEnablement(checked, webhookServiceField.value);
|
||||
}}
|
||||
/>
|
||||
<CheckboxField
|
||||
name="allow_simultaneous"
|
||||
id="allow_simultaneous"
|
||||
tooltip={i18n._(
|
||||
t`If enabled, simultaneous runs of this workflow job template will be allowed.`
|
||||
)}
|
||||
label={i18n._(t`Enable Concurrent Jobs`)}
|
||||
/>
|
||||
</FormCheckboxLayout>
|
||||
{hasWebhooks && (
|
||||
<FormColumnLayout>
|
||||
<FormGroup
|
||||
name="webhook_service"
|
||||
fieldId="webhook_service"
|
||||
helperTextInvalid={webhookServiceMeta.error}
|
||||
isValid={!(webhookServiceMeta.touched || webhookServiceMeta.error)}
|
||||
label={i18n._(t`Webhook Service`)}
|
||||
>
|
||||
<FieldTooltip content={i18n._(t`Select a webhook service`)} />
|
||||
<AnsibleSelect
|
||||
id="webhook_service"
|
||||
data={webhookServiceOptions}
|
||||
value={webhookServiceField.value}
|
||||
onChange={(event, val) => {
|
||||
storeWebhookValues(val);
|
||||
|
||||
webhookServiceHelpers.setValue(val);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
{!wfjtAddMatch && (
|
||||
<>
|
||||
<FormGroup
|
||||
type="text"
|
||||
fieldId="wfjt-webhookURL"
|
||||
label={i18n._(t`Webhook URL`)}
|
||||
id="wfjt-webhook-url"
|
||||
name="webhook_url"
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Webhook services can launch jobs with this workflow job template by making a POST request to this URL.`
|
||||
)}
|
||||
/>
|
||||
<TextInput
|
||||
aria-label={i18n._(t`Webhook URL`)}
|
||||
value={webhookUrlField.value}
|
||||
isReadOnly
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
fieldId="wfjt-webhook-key"
|
||||
type="text"
|
||||
id="wfjt-webhook-key"
|
||||
name="webhookKey"
|
||||
label={i18n._(t`Webhook Key`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Webhook services can use this as a shared secret.`
|
||||
)}
|
||||
/>
|
||||
<InputGroup>
|
||||
<TextInput
|
||||
isReadOnly
|
||||
aria-label="wfjt-webhook-key"
|
||||
value={webhookKeyField.value}
|
||||
/>
|
||||
<Button variant="tertiary" onClick={changeWebhookKey}>
|
||||
<SyncAltIcon />
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</>
|
||||
)}
|
||||
{credTypeId && (
|
||||
// TODO: Consider how to handle the situation where the results returns
|
||||
// an empty array, or any of the other values is undefined or null
|
||||
// (data, results, id)
|
||||
<CredentialLookup
|
||||
label={i18n._(t`Webhook Credential`)}
|
||||
tooltip={i18n._(
|
||||
t`Optionally select the credential to use to send status updates back to the webhook service.`
|
||||
)}
|
||||
credentialTypeId={credTypeId}
|
||||
onChange={value => {
|
||||
webhookCredentialHelpers.setValue(value || null);
|
||||
}}
|
||||
isValid={!webhookCredentialMeta.error}
|
||||
helperTextInvalid={webhookCredentialMeta.error}
|
||||
value={webhookCredentialField.value}
|
||||
/>
|
||||
)}
|
||||
</FormColumnLayout>
|
||||
)}
|
||||
</Formik>
|
||||
{submitError && <FormSubmitError error={submitError} />}
|
||||
<FormActionGroup onCancel={handleCancel} onSubmit={handleSubmit} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
WorkflowJobTemplateForm.propTypes = {
|
||||
handleSubmit: func.isRequired,
|
||||
handleCancel: func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
handleCancel: PropTypes.func.isRequired,
|
||||
submitError: shape({}),
|
||||
};
|
||||
|
||||
@ -506,4 +396,38 @@ WorkflowJobTemplateForm.defaultProps = {
|
||||
submitError: null,
|
||||
};
|
||||
|
||||
export default withI18n()(WorkflowJobTemplateForm);
|
||||
const FormikApp = withFormik({
|
||||
mapPropsToValues({ template = {}, webhookKey }) {
|
||||
return {
|
||||
name: template.name || '',
|
||||
description: template.description || '',
|
||||
inventory: template?.summary_fields?.inventory || null,
|
||||
organization: template?.summary_fields?.organization || null,
|
||||
labels: template.summary_fields?.labels?.results || [],
|
||||
extra_vars: template.extra_vars || '---',
|
||||
limit: template.limit || '',
|
||||
scm_branch: template.scm_branch || '',
|
||||
allow_simultaneous: template.allow_simultaneous || false,
|
||||
webhook_credential: template?.summary_fields?.webhook_credential || null,
|
||||
webhook_service: template.webhook_service || '',
|
||||
ask_limit_on_launch: template.ask_limit_on_launch || false,
|
||||
ask_inventory_on_launch: template.ask_inventory_on_launch || false,
|
||||
ask_variables_on_launch: template.ask_variables_on_launch || false,
|
||||
ask_scm_branch_on_launch: template.ask_scm_branch_on_launch || false,
|
||||
webhook_url: template?.related?.webhook_receiver
|
||||
? `${urlOrigin}${template.related.webhook_receiver}`
|
||||
: '',
|
||||
webhookKey: webhookKey || null,
|
||||
};
|
||||
},
|
||||
handleSubmit: async (values, { props, setErrors }) => {
|
||||
try {
|
||||
await props.handleSubmit(values);
|
||||
} catch (errors) {
|
||||
setErrors(errors);
|
||||
}
|
||||
},
|
||||
})(WorkflowJobTemplateForm);
|
||||
|
||||
export { WorkflowJobTemplateForm as _WorkflowJobTemplateForm };
|
||||
export default withI18n()(withRouter(FormikApp));
|
||||
|
Loading…
Reference in New Issue
Block a user