mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
Refactor to PlaybookSelect component
This commit is contained in:
parent
362339d89c
commit
61f6e3c4d2
@ -2,16 +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 { ProjectsAPI } from '@api';
|
import { ProjectsAPI } from '@api';
|
||||||
import { Project } from '@types';
|
import { Project } from '@types';
|
||||||
import Lookup from '@components/Lookup';
|
import Lookup from '@components/Lookup';
|
||||||
import styled from 'styled-components';
|
import { FieldTooltip } from '@components/FormField';
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const loadProjects = async params => ProjectsAPI.read(params);
|
const loadProjects = async params => ProjectsAPI.read(params);
|
||||||
|
|
||||||
@ -36,11 +31,7 @@ class ProjectLookup extends React.Component {
|
|||||||
isValid={isValid}
|
isValid={isValid}
|
||||||
label={i18n._(t`Project`)}
|
label={i18n._(t`Project`)}
|
||||||
>
|
>
|
||||||
{tooltip && (
|
{tooltip && <FieldTooltip content={tooltip} />}
|
||||||
<Tooltip position="right" content={tooltip}>
|
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<Lookup
|
<Lookup
|
||||||
id="project"
|
id="project"
|
||||||
lookupHeader={i18n._(t`Project`)}
|
lookupHeader={i18n._(t`Project`)}
|
@ -1,3 +1,4 @@
|
|||||||
export { default } from './Lookup';
|
export { default } from './Lookup';
|
||||||
export { default as InstanceGroupsLookup } from './InstanceGroupsLookup';
|
export { default as InstanceGroupsLookup } from './InstanceGroupsLookup';
|
||||||
export { default as InventoryLookup } from './InventoryLookup';
|
export { default as InventoryLookup } from './InventoryLookup';
|
||||||
|
export { default as ProjectLookup } from './ProjectLookup';
|
||||||
|
@ -23,9 +23,13 @@ import CollapsibleSection from '@components/CollapsibleSection';
|
|||||||
import { required } from '@util/validators';
|
import { required } from '@util/validators';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { JobTemplate } from '@types';
|
import { JobTemplate } from '@types';
|
||||||
import { InventoryLookup, InstanceGroupsLookup } from '@components/Lookup';
|
import {
|
||||||
import ProjectLookup from './ProjectLookup';
|
InventoryLookup,
|
||||||
|
InstanceGroupsLookup,
|
||||||
|
ProjectLookup,
|
||||||
|
} from '@components/Lookup';
|
||||||
import { JobTemplatesAPI, LabelsAPI, ProjectsAPI } from '@api';
|
import { JobTemplatesAPI, LabelsAPI, ProjectsAPI } from '@api';
|
||||||
|
import PlaybookSelect from './PlaybookSelect';
|
||||||
|
|
||||||
const GridFormGroup = styled(FormGroup)`
|
const GridFormGroup = styled(FormGroup)`
|
||||||
& > label {
|
& > label {
|
||||||
@ -72,7 +76,6 @@ class JobTemplateForm extends Component {
|
|||||||
removedLabels: [],
|
removedLabels: [],
|
||||||
project: props.template.summary_fields.project,
|
project: props.template.summary_fields.project,
|
||||||
inventory: props.template.summary_fields.inventory,
|
inventory: props.template.summary_fields.inventory,
|
||||||
relatedProjectPlaybooks: props.relatedProjectPlaybooks,
|
|
||||||
relatedInstanceGroups: [],
|
relatedInstanceGroups: [],
|
||||||
allowCallbacks: !!props.template.host_config_key,
|
allowCallbacks: !!props.template.host_config_key,
|
||||||
};
|
};
|
||||||
@ -81,9 +84,6 @@ class JobTemplateForm extends Component {
|
|||||||
this.removeLabel = this.removeLabel.bind(this);
|
this.removeLabel = this.removeLabel.bind(this);
|
||||||
this.handleProjectValidation = this.handleProjectValidation.bind(this);
|
this.handleProjectValidation = this.handleProjectValidation.bind(this);
|
||||||
this.loadRelatedInstanceGroups = this.loadRelatedInstanceGroups.bind(this);
|
this.loadRelatedInstanceGroups = this.loadRelatedInstanceGroups.bind(this);
|
||||||
this.loadRelatedProjectPlaybooks = this.loadRelatedProjectPlaybooks.bind(
|
|
||||||
this
|
|
||||||
);
|
|
||||||
this.handleInstanceGroupsChange = this.handleInstanceGroupsChange.bind(
|
this.handleInstanceGroupsChange = this.handleInstanceGroupsChange.bind(
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
@ -204,15 +204,6 @@ class JobTemplateForm extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadRelatedProjectPlaybooks(project) {
|
|
||||||
try {
|
|
||||||
const { data: playbooks = [] } = await ProjectsAPI.readPlaybooks(project);
|
|
||||||
this.setState({ relatedProjectPlaybooks: playbooks });
|
|
||||||
} catch (contentError) {
|
|
||||||
this.setState({ contentError });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleProjectValidation() {
|
handleProjectValidation() {
|
||||||
const { i18n, touched } = this.props;
|
const { i18n, touched } = this.props;
|
||||||
const { project } = this.state;
|
const { project } = this.state;
|
||||||
@ -258,7 +249,6 @@ class JobTemplateForm extends Component {
|
|||||||
hasContentLoading,
|
hasContentLoading,
|
||||||
inventory,
|
inventory,
|
||||||
project,
|
project,
|
||||||
relatedProjectPlaybooks = [],
|
|
||||||
relatedInstanceGroups,
|
relatedInstanceGroups,
|
||||||
allowCallbacks,
|
allowCallbacks,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
@ -284,28 +274,6 @@ class JobTemplateForm extends Component {
|
|||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const playbookOptions = relatedProjectPlaybooks
|
|
||||||
.map(playbook => {
|
|
||||||
return {
|
|
||||||
value: playbook,
|
|
||||||
key: playbook,
|
|
||||||
label: playbook,
|
|
||||||
isDisabled: false,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.reduce(
|
|
||||||
(arr, playbook) => {
|
|
||||||
return arr.concat(playbook);
|
|
||||||
},
|
|
||||||
[
|
|
||||||
{
|
|
||||||
value: '',
|
|
||||||
key: '',
|
|
||||||
label: i18n._(t`Choose a playbook`),
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
const verbosityOptions = [
|
const verbosityOptions = [
|
||||||
{ value: '0', key: '0', label: i18n._(t`0 (Normal)`) },
|
{ value: '0', key: '0', label: i18n._(t`0 (Normal)`) },
|
||||||
@ -412,7 +380,6 @@ class JobTemplateForm extends Component {
|
|||||||
tooltip={i18n._(t`Select the project containing the playbook
|
tooltip={i18n._(t`Select the project containing the playbook
|
||||||
you want this job to execute.`)}
|
you want this job to execute.`)}
|
||||||
onChange={value => {
|
onChange={value => {
|
||||||
this.loadRelatedProjectPlaybooks(value.id);
|
|
||||||
form.setFieldValue('project', value.id);
|
form.setFieldValue('project', value.id);
|
||||||
this.setState({ project: value });
|
this.setState({ project: value });
|
||||||
}}
|
}}
|
||||||
@ -439,13 +406,8 @@ class JobTemplateForm extends Component {
|
|||||||
t`Select the playbook to be executed by this job.`
|
t`Select the playbook to be executed by this job.`
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<AnsibleSelect
|
<PlaybookSelect projectId={form.values.project}
|
||||||
id="template-playbook"
|
isValid={isValid} form={form} field={field} />
|
||||||
data={playbookOptions}
|
|
||||||
isValid={isValid}
|
|
||||||
form={form}
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
51
awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx
Normal file
51
awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { number, string, oneOfType } from 'prop-types';
|
||||||
|
import { withI18n } from '@lingui/react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import AnsibleSelect from '@components/AnsibleSelect';
|
||||||
|
import { ProjectsAPI } from '@api';
|
||||||
|
|
||||||
|
function PlaybookSelect({ projectId, isValid, form, field, onError, i18n }) {
|
||||||
|
const [options, setOptions] = useState([]);
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await ProjectsAPI.readPlaybooks(projectId);
|
||||||
|
const opts = (data || []).map(playbook => ({
|
||||||
|
value: playbook,
|
||||||
|
key: playbook,
|
||||||
|
label: playbook,
|
||||||
|
isDisabled: false,
|
||||||
|
}));
|
||||||
|
opts.unshift({
|
||||||
|
value: '',
|
||||||
|
key: '',
|
||||||
|
label: i18n._(t`Choose a playbook`),
|
||||||
|
isDisabled: false,
|
||||||
|
});
|
||||||
|
setOptions(opts);
|
||||||
|
} catch (contentError) {
|
||||||
|
onError(contentError);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, [projectId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnsibleSelect
|
||||||
|
id="template-playbook"
|
||||||
|
data={options}
|
||||||
|
isValid={isValid}
|
||||||
|
form={form}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PlaybookSelect.propTypes = {
|
||||||
|
projectId: oneOfType([number, string]),
|
||||||
|
};
|
||||||
|
PlaybookSelect.defaultProps = {
|
||||||
|
projectId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export { PlaybookSelect as _PlaybookSelect };
|
||||||
|
export default withI18n()(PlaybookSelect);
|
Loading…
Reference in New Issue
Block a user