mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 06:51:10 +03:00
Merge pull request #4305 from catjones9/jobTemplateAddButton
Adds Job Template Add Button to TemplatesList with link to add form Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
commit
2f658a4e5d
@ -1,18 +1,23 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withRouter, Link } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Card, PageSection, PageSectionVariants } from '@patternfly/react-core';
|
||||
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
JobTemplatesAPI,
|
||||
UnifiedJobTemplatesAPI,
|
||||
WorkflowJobTemplatesAPI,
|
||||
} from '@api';
|
||||
Card,
|
||||
PageSection,
|
||||
PageSectionVariants,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownPosition,
|
||||
} from '@patternfly/react-core';
|
||||
|
||||
import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
|
||||
import AlertModal from '@components/AlertModal';
|
||||
import DatalistToolbar from '@components/DataListToolbar';
|
||||
import PaginatedDataList, {
|
||||
ToolbarDeleteButton,
|
||||
ToolbarAddButton,
|
||||
} from '@components/PaginatedDataList';
|
||||
import { getQSConfig, parseQueryString } from '@util/qs';
|
||||
|
||||
@ -38,12 +43,15 @@ class TemplatesList extends Component {
|
||||
selected: [],
|
||||
templates: [],
|
||||
itemCount: 0,
|
||||
isAddOpen: false,
|
||||
};
|
||||
|
||||
this.loadTemplates = this.loadTemplates.bind(this);
|
||||
this.handleSelectAll = this.handleSelectAll.bind(this);
|
||||
this.handleSelect = this.handleSelect.bind(this);
|
||||
this.handleTemplateDelete = this.handleTemplateDelete.bind(this);
|
||||
this.handleDeleteErrorClose = this.handleDeleteErrorClose.bind(this);
|
||||
this.handleAddToggle = this.handleAddToggle.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -76,8 +84,13 @@ class TemplatesList extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleAddToggle() {
|
||||
const { isAddOpen } = this.state;
|
||||
this.setState({ isAddOpen: !isAddOpen });
|
||||
}
|
||||
|
||||
async handleTemplateDelete() {
|
||||
const { selected } = this.state;
|
||||
const { selected, itemCount } = this.state;
|
||||
|
||||
this.setState({ hasContentLoading: true, hasDeletionError: false });
|
||||
try {
|
||||
@ -92,6 +105,7 @@ class TemplatesList extends Component {
|
||||
return deletePromise;
|
||||
})
|
||||
);
|
||||
this.setState({ itemCount: itemCount - selected.length });
|
||||
} catch (err) {
|
||||
this.setState({ hasDeletionError: true });
|
||||
} finally {
|
||||
@ -101,14 +115,35 @@ class TemplatesList extends Component {
|
||||
|
||||
async loadTemplates() {
|
||||
const { location } = this.props;
|
||||
const { actions: cachedActions } = this.state;
|
||||
const params = parseQueryString(QS_CONFIG, location.search);
|
||||
|
||||
let optionsPromise;
|
||||
if (cachedActions) {
|
||||
optionsPromise = Promise.resolve({ data: { actions: cachedActions } });
|
||||
} else {
|
||||
optionsPromise = JobTemplatesAPI.readOptions();
|
||||
}
|
||||
|
||||
const promises = Promise.all([
|
||||
JobTemplatesAPI.read(params),
|
||||
optionsPromise,
|
||||
]);
|
||||
|
||||
this.setState({ contentError: null, hasContentLoading: true });
|
||||
|
||||
try {
|
||||
const {
|
||||
data: { count, results },
|
||||
} = await UnifiedJobTemplatesAPI.read(params);
|
||||
const [
|
||||
{
|
||||
data: { count, results },
|
||||
},
|
||||
{
|
||||
data: { actions },
|
||||
},
|
||||
] = await promises;
|
||||
|
||||
this.setState({
|
||||
actions,
|
||||
itemCount: count,
|
||||
templates: results,
|
||||
selected: [],
|
||||
@ -128,8 +163,12 @@ class TemplatesList extends Component {
|
||||
templates,
|
||||
itemCount,
|
||||
selected,
|
||||
isAddOpen,
|
||||
actions,
|
||||
} = this.state;
|
||||
const { match, i18n } = this.props;
|
||||
const canAdd =
|
||||
actions && Object.prototype.hasOwnProperty.call(actions, 'POST');
|
||||
const isAllSelected = selected.length === templates.length;
|
||||
const { medium } = PageSectionVariants;
|
||||
return (
|
||||
@ -176,6 +215,34 @@ class TemplatesList extends Component {
|
||||
itemsToDelete={selected}
|
||||
itemName={i18n._(t`Template`)}
|
||||
/>,
|
||||
canAdd && (
|
||||
<Dropdown
|
||||
key="add"
|
||||
isPlain
|
||||
isOpen={isAddOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleAddSelect}
|
||||
toggle={
|
||||
<ToolbarAddButton onClick={this.handleAddToggle} />
|
||||
}
|
||||
dropdownItems={[
|
||||
<DropdownItem
|
||||
key="job"
|
||||
component={Link}
|
||||
to={`${match.url}/job_template/add`}
|
||||
>
|
||||
{i18n._(t`Job Template`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="workflow"
|
||||
component={Link}
|
||||
to={`${match.url}/add`}
|
||||
>
|
||||
{i18n._(t`Workflow Template`)}
|
||||
</DropdownItem>,
|
||||
]}
|
||||
/>
|
||||
),
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
@ -189,6 +256,34 @@ class TemplatesList extends Component {
|
||||
isSelected={selected.some(row => row.id === template.id)}
|
||||
/>
|
||||
)}
|
||||
emptyStateControls={
|
||||
canAdd && (
|
||||
<Dropdown
|
||||
key="add"
|
||||
isPlain
|
||||
isOpen={isAddOpen}
|
||||
position={DropdownPosition.right}
|
||||
onSelect={this.handleAddSelect}
|
||||
toggle={<ToolbarAddButton onClick={this.handleAddToggle} />}
|
||||
dropdownItems={[
|
||||
<DropdownItem
|
||||
key="job"
|
||||
component={Link}
|
||||
to={`${match.url}/job_template/add/`}
|
||||
>
|
||||
{i18n._(t`Job Template`)}
|
||||
</DropdownItem>,
|
||||
<DropdownItem
|
||||
key="workflow"
|
||||
component={Link}
|
||||
to={`${match.url}_workflow/add/`}
|
||||
>
|
||||
{i18n._(t`Workflow Template`)}
|
||||
</DropdownItem>,
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
<AlertModal
|
||||
|
@ -76,6 +76,12 @@ describe('<TemplatesList />', () => {
|
||||
results: mockTemplates,
|
||||
},
|
||||
});
|
||||
|
||||
UnifiedJobTemplatesAPI.readOptions.mockResolvedValue({
|
||||
data: {
|
||||
actions: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@ -116,7 +122,7 @@ describe('<TemplatesList />', () => {
|
||||
'TemplatesList',
|
||||
el => el.state('hasContentLoading') === false
|
||||
);
|
||||
wrapper
|
||||
await wrapper
|
||||
.find('DataListCheck#select-jobTemplate-1')
|
||||
.props()
|
||||
.onChange();
|
||||
|
Loading…
Reference in New Issue
Block a user