mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 09:57:35 -02:30
add FieldTooltip component, some JobTemplateForm cleanup
This commit is contained in:
26
awx/ui_next/src/components/FormField/FieldTooltip.jsx
Normal file
26
awx/ui_next/src/components/FormField/FieldTooltip.jsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { node } from 'prop-types';
|
||||||
|
import { Tooltip } from '@patternfly/react-core';
|
||||||
|
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
||||||
|
margin-left: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function FieldTooltip({ content }) {
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
position="right"
|
||||||
|
content={content}
|
||||||
|
trigger="click mouseenter focus"
|
||||||
|
>
|
||||||
|
<QuestionCircleIcon />
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FieldTooltip.propTypes = {
|
||||||
|
content: node.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FieldTooltip;
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export { default } from './FormField';
|
export { default } from './FormField';
|
||||||
export { default as CheckboxField } from './CheckboxField';
|
export { default as CheckboxField } from './CheckboxField';
|
||||||
|
export { default as FieldTooltip } from './FieldTooltip';
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ class ListHeader extends React.Component {
|
|||||||
columns,
|
columns,
|
||||||
onSearch: this.handleSearch,
|
onSearch: this.handleSearch,
|
||||||
onSort: this.handleSort,
|
onSort: this.handleSort,
|
||||||
|
qsConfig,
|
||||||
})}
|
})}
|
||||||
<FilterTags
|
<FilterTags
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
|
|||||||
@@ -2,17 +2,11 @@ import React from 'react';
|
|||||||
import { string, func, bool } from 'prop-types';
|
import { string, func, bool } from 'prop-types';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { FormGroup, Tooltip } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
import { InventoriesAPI } from '@api';
|
import { InventoriesAPI } from '@api';
|
||||||
import { Inventory } from '@types';
|
import { Inventory } from '@types';
|
||||||
import Lookup from '@components/Lookup';
|
import Lookup from '@components/Lookup';
|
||||||
|
import { FieldTooltip } from '@components/FormField';
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const getInventories = async params => InventoriesAPI.read(params);
|
const getInventories = async params => InventoriesAPI.read(params);
|
||||||
|
|
||||||
@@ -26,11 +20,7 @@ class InventoryLookup extends React.Component {
|
|||||||
isRequired={required}
|
isRequired={required}
|
||||||
fieldId="inventory-lookup"
|
fieldId="inventory-lookup"
|
||||||
>
|
>
|
||||||
{tooltip && (
|
{tooltip && <FieldTooltip content={tooltip} />}
|
||||||
<Tooltip position="right" content={tooltip}>
|
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<Lookup
|
<Lookup
|
||||||
id="inventory-lookup"
|
id="inventory-lookup"
|
||||||
lookupHeader={i18n._(t`Inventory`)}
|
lookupHeader={i18n._(t`Inventory`)}
|
||||||
|
|||||||
@@ -383,6 +383,24 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
|
|||||||
}
|
}
|
||||||
onSearch={[Function]}
|
onSearch={[Function]}
|
||||||
onSort={[Function]}
|
onSort={[Function]}
|
||||||
|
qsConfig={
|
||||||
|
Object {
|
||||||
|
"dateFields": Array [
|
||||||
|
"modified",
|
||||||
|
"created",
|
||||||
|
],
|
||||||
|
"defaultParams": Object {
|
||||||
|
"order_by": "name",
|
||||||
|
"page": 1,
|
||||||
|
"page_size": 5,
|
||||||
|
},
|
||||||
|
"integerFields": Array [
|
||||||
|
"page",
|
||||||
|
"page_size",
|
||||||
|
],
|
||||||
|
"namespace": "notification",
|
||||||
|
}
|
||||||
|
}
|
||||||
sortOrder="ascending"
|
sortOrder="ascending"
|
||||||
sortedColumnKey="name"
|
sortedColumnKey="name"
|
||||||
>
|
>
|
||||||
@@ -423,6 +441,24 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
|
|||||||
onSearch={[Function]}
|
onSearch={[Function]}
|
||||||
onSelectAll={null}
|
onSelectAll={null}
|
||||||
onSort={[Function]}
|
onSort={[Function]}
|
||||||
|
qsConfig={
|
||||||
|
Object {
|
||||||
|
"dateFields": Array [
|
||||||
|
"modified",
|
||||||
|
"created",
|
||||||
|
],
|
||||||
|
"defaultParams": Object {
|
||||||
|
"order_by": "name",
|
||||||
|
"page": 1,
|
||||||
|
"page_size": 5,
|
||||||
|
},
|
||||||
|
"integerFields": Array [
|
||||||
|
"page",
|
||||||
|
"page_size",
|
||||||
|
],
|
||||||
|
"namespace": "notification",
|
||||||
|
}
|
||||||
|
}
|
||||||
showSelectAll={false}
|
showSelectAll={false}
|
||||||
sortOrder="ascending"
|
sortOrder="ascending"
|
||||||
sortedColumnKey="name"
|
sortedColumnKey="name"
|
||||||
@@ -590,6 +626,24 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
onSearch={[Function]}
|
onSearch={[Function]}
|
||||||
|
qsConfig={
|
||||||
|
Object {
|
||||||
|
"dateFields": Array [
|
||||||
|
"modified",
|
||||||
|
"created",
|
||||||
|
],
|
||||||
|
"defaultParams": Object {
|
||||||
|
"order_by": "name",
|
||||||
|
"page": 1,
|
||||||
|
"page_size": 5,
|
||||||
|
},
|
||||||
|
"integerFields": Array [
|
||||||
|
"page",
|
||||||
|
"page_size",
|
||||||
|
],
|
||||||
|
"namespace": "notification",
|
||||||
|
}
|
||||||
|
}
|
||||||
sortedColumnKey="name"
|
sortedColumnKey="name"
|
||||||
>
|
>
|
||||||
<I18n
|
<I18n
|
||||||
@@ -621,6 +675,24 @@ exports[`<OrganizationNotifications /> initially renders succesfully 1`] = `
|
|||||||
}
|
}
|
||||||
i18n={"/i18n/"}
|
i18n={"/i18n/"}
|
||||||
onSearch={[Function]}
|
onSearch={[Function]}
|
||||||
|
qsConfig={
|
||||||
|
Object {
|
||||||
|
"dateFields": Array [
|
||||||
|
"modified",
|
||||||
|
"created",
|
||||||
|
],
|
||||||
|
"defaultParams": Object {
|
||||||
|
"order_by": "name",
|
||||||
|
"page": 1,
|
||||||
|
"page_size": 5,
|
||||||
|
},
|
||||||
|
"integerFields": Array [
|
||||||
|
"page",
|
||||||
|
"page_size",
|
||||||
|
],
|
||||||
|
"namespace": "notification",
|
||||||
|
}
|
||||||
|
}
|
||||||
sortedColumnKey="name"
|
sortedColumnKey="name"
|
||||||
>
|
>
|
||||||
<Form
|
<Form
|
||||||
|
|||||||
@@ -7,19 +7,17 @@ import { withFormik, Field } from 'formik';
|
|||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
Tooltip,
|
|
||||||
Card,
|
Card,
|
||||||
Switch,
|
Switch,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import ContentError from '@components/ContentError';
|
import ContentError from '@components/ContentError';
|
||||||
import ContentLoading from '@components/ContentLoading';
|
import ContentLoading from '@components/ContentLoading';
|
||||||
import AnsibleSelect from '@components/AnsibleSelect';
|
import AnsibleSelect from '@components/AnsibleSelect';
|
||||||
import MultiSelect, { TagMultiSelect } from '@components/MultiSelect';
|
import MultiSelect, { TagMultiSelect } from '@components/MultiSelect';
|
||||||
import FormActionGroup from '@components/FormActionGroup';
|
import FormActionGroup from '@components/FormActionGroup';
|
||||||
import FormField, { CheckboxField } from '@components/FormField';
|
import FormField, { CheckboxField, FieldTooltip } from '@components/FormField';
|
||||||
import FormRow from '@components/FormRow';
|
import FormRow from '@components/FormRow';
|
||||||
import CollapsibleSection from '@components/CollapsibleSection';
|
import CollapsibleSection from '@components/CollapsibleSection';
|
||||||
import { required } from '@util/validators';
|
import { required } from '@util/validators';
|
||||||
@@ -29,10 +27,6 @@ import { InventoryLookup, InstanceGroupsLookup } from '@components/Lookup';
|
|||||||
import ProjectLookup from './ProjectLookup';
|
import ProjectLookup from './ProjectLookup';
|
||||||
import { JobTemplatesAPI, LabelsAPI, ProjectsAPI } from '@api';
|
import { JobTemplatesAPI, LabelsAPI, ProjectsAPI } from '@api';
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const GridFormGroup = styled(FormGroup)`
|
const GridFormGroup = styled(FormGroup)`
|
||||||
& > label {
|
& > label {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
@@ -374,15 +368,12 @@ class JobTemplateForm extends Component {
|
|||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
label={i18n._(t`Job Type`)}
|
label={i18n._(t`Job Type`)}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(t`For job templates, select run to execute
|
content={i18n._(t`For job templates, select run to execute
|
||||||
the playbook. Select check to only check playbook syntax,
|
the playbook. Select check to only check playbook syntax,
|
||||||
test environment setup, and report problems without
|
test environment setup, and report problems without
|
||||||
executing the playbook.`)}
|
executing the playbook.`)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
id="template-job-type"
|
id="template-job-type"
|
||||||
@@ -443,14 +434,11 @@ class JobTemplateForm extends Component {
|
|||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
label={i18n._(t`Playbook`)}
|
label={i18n._(t`Playbook`)}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Select the playbook to be executed by this job.`
|
t`Select the playbook to be executed by this job.`
|
||||||
)}
|
)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
id="template-playbook"
|
id="template-playbook"
|
||||||
data={playbookOptions}
|
data={playbookOptions}
|
||||||
@@ -465,14 +453,11 @@ class JobTemplateForm extends Component {
|
|||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow>
|
<FormRow>
|
||||||
<FormGroup label={i18n._(t`Labels`)} fieldId="template-labels">
|
<FormGroup label={i18n._(t`Labels`)} fieldId="template-labels">
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(
|
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.`
|
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.`
|
||||||
)}
|
)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
onAddNewItem={this.handleNewLabel}
|
onAddNewItem={this.handleNewLabel}
|
||||||
onRemoveItem={this.removeLabel}
|
onRemoveItem={this.removeLabel}
|
||||||
@@ -519,13 +504,10 @@ class JobTemplateForm extends Component {
|
|||||||
fieldId="template-verbosity"
|
fieldId="template-verbosity"
|
||||||
label={i18n._(t`Verbosity`)}
|
label={i18n._(t`Verbosity`)}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(t`Control the level of output ansible will
|
content={i18n._(t`Control the level of output ansible will
|
||||||
produce as the playbook executes.`)}
|
produce as the playbook executes.`)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
id="template-verbosity"
|
id="template-verbosity"
|
||||||
data={verbosityOptions}
|
data={verbosityOptions}
|
||||||
@@ -561,14 +543,11 @@ class JobTemplateForm extends Component {
|
|||||||
fieldId="template-show-changes"
|
fieldId="template-show-changes"
|
||||||
label={i18n._(t`Show Changes`)}
|
label={i18n._(t`Show Changes`)}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(t`If enabled, show the changes made by
|
content={i18n._(t`If enabled, show the changes made by
|
||||||
Ansible tasks, where supported. This is equivalent
|
Ansible tasks, where supported. This is equivalent
|
||||||
to Ansible’s --diff mode.`)}
|
to Ansible’s --diff mode.`)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<div>
|
<div>
|
||||||
<Switch
|
<Switch
|
||||||
id="template-show-changes"
|
id="template-show-changes"
|
||||||
@@ -599,16 +578,13 @@ class JobTemplateForm extends Component {
|
|||||||
css="margin-top: 20px"
|
css="margin-top: 20px"
|
||||||
fieldId="template-job-tags"
|
fieldId="template-job-tags"
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(t`Tags are useful when you have a large
|
content={i18n._(t`Tags are useful when you have a large
|
||||||
playbook, and you want to run a specific part of a
|
playbook, and you want to run a specific part of a
|
||||||
play or task. Use commas to separate multiple tags.
|
play or task. Use commas to separate multiple tags.
|
||||||
Refer to Ansible Tower documentation for details on
|
Refer to Ansible Tower documentation for details on
|
||||||
the usage of tags.`)}
|
the usage of tags.`)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<TagMultiSelect
|
<TagMultiSelect
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={value => form.setFieldValue(field.name, value)}
|
onChange={value => form.setFieldValue(field.name, value)}
|
||||||
@@ -624,16 +600,13 @@ class JobTemplateForm extends Component {
|
|||||||
css="margin-top: 20px"
|
css="margin-top: 20px"
|
||||||
fieldId="template-skip-tags"
|
fieldId="template-skip-tags"
|
||||||
>
|
>
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(t`Skip tags are useful when you have a
|
content={i18n._(t`Skip tags are useful when you have a
|
||||||
large playbook, and you want to skip specific parts of a
|
large playbook, and you want to skip specific parts of a
|
||||||
play or task. Use commas to separate multiple tags. Refer
|
play or task. Use commas to separate multiple tags. Refer
|
||||||
to Ansible Tower documentation for details on the usage
|
to Ansible Tower documentation for details on the usage
|
||||||
of tags.`)}
|
of tags.`)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
<TagMultiSelect
|
<TagMultiSelect
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={value => form.setFieldValue(field.name, value)}
|
onChange={value => form.setFieldValue(field.name, value)}
|
||||||
@@ -661,16 +634,13 @@ class JobTemplateForm extends Component {
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Provisioning Callbacks`)}
|
{i18n._(t`Provisioning Callbacks`)}
|
||||||
|
|
||||||
<Tooltip
|
<FieldTooltip
|
||||||
position="right"
|
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Enables creation of a provisioning callback URL. Using
|
t`Enables creation of a provisioning callback URL. Using
|
||||||
the URL a host can contact BRAND_NAME and request a
|
the URL a host can contact BRAND_NAME and request a
|
||||||
configuration update using this job template.`
|
configuration update using this job template.`
|
||||||
)}
|
)}
|
||||||
>
|
/>
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
id="option-callbacks"
|
id="option-callbacks"
|
||||||
@@ -735,50 +705,29 @@ class JobTemplateForm extends Component {
|
|||||||
const FormikApp = withFormik({
|
const FormikApp = withFormik({
|
||||||
mapPropsToValues(props) {
|
mapPropsToValues(props) {
|
||||||
const { template = {} } = props;
|
const { template = {} } = props;
|
||||||
const {
|
const { summary_fields = { labels: { results: [] } } } = template;
|
||||||
name = '',
|
|
||||||
description = '',
|
|
||||||
job_type = 'run',
|
|
||||||
inventory = '',
|
|
||||||
project = '',
|
|
||||||
playbook = '',
|
|
||||||
forks,
|
|
||||||
limit,
|
|
||||||
verbosity,
|
|
||||||
job_slice_count,
|
|
||||||
timeout,
|
|
||||||
diff_mode,
|
|
||||||
job_tags,
|
|
||||||
skip_tags,
|
|
||||||
become_enabled,
|
|
||||||
allow_callbacks,
|
|
||||||
allow_simultaneous,
|
|
||||||
use_fact_cache,
|
|
||||||
host_config_key,
|
|
||||||
summary_fields = { labels: { results: [] } },
|
|
||||||
} = { ...template };
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: name || '',
|
name: template.name || '',
|
||||||
description: description || '',
|
description: template.description || '',
|
||||||
job_type: job_type || '',
|
job_type: template.job_type || 'run',
|
||||||
inventory: inventory || '',
|
inventory: template.inventory || '',
|
||||||
project: project || '',
|
project: template.project || '',
|
||||||
playbook: playbook || '',
|
playbook: template.playbook || '',
|
||||||
labels: summary_fields.labels.results,
|
labels: summary_fields.labels.results,
|
||||||
forks: forks || 0,
|
forks: template.forks || 0,
|
||||||
limit: limit || '',
|
limit: template.limit || '',
|
||||||
verbosity: verbosity || '0',
|
verbosity: template.verbosity || '0',
|
||||||
job_slice_count: job_slice_count || 1,
|
job_slice_count: template.job_slice_count || 1,
|
||||||
timeout: timeout || 0,
|
timeout: template.timeout || 0,
|
||||||
diff_mode: diff_mode || false,
|
diff_mode: template.diff_mode || false,
|
||||||
job_tags: job_tags || '',
|
job_tags: template.job_tags || '',
|
||||||
skip_tags: skip_tags || '',
|
skip_tags: template.skip_tags || '',
|
||||||
become_enabled: become_enabled || false,
|
become_enabled: template.become_enabled || false,
|
||||||
allow_callbacks: allow_callbacks || false,
|
allow_callbacks: template.allow_callbacks || false,
|
||||||
allow_simultaneous: allow_simultaneous || false,
|
allow_simultaneous: template.allow_simultaneous || false,
|
||||||
use_fact_cache: use_fact_cache || false,
|
use_fact_cache: template.use_fact_cache || false,
|
||||||
host_config_key: host_config_key || '',
|
host_config_key: template.host_config_key || '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSubmit: (values, bag) => bag.props.handleSubmit(values),
|
handleSubmit: (values, bag) => bag.props.handleSubmit(values),
|
||||||
|
|||||||
Reference in New Issue
Block a user