mirror of
https://github.com/ansible/awx.git
synced 2026-05-13 12:27:37 -02:30
Merge pull request #141 from AlexSCorey/48-deleteOrgs
Add alert for org. delete.
This commit is contained in:
@@ -221,4 +221,36 @@ describe('<DataListToolbar />', () => {
|
|||||||
const upAlphaIcon = toolbar.find(upAlphaIconSelector);
|
const upAlphaIcon = toolbar.find(upAlphaIconSelector);
|
||||||
expect(upAlphaIcon.length).toBe(1);
|
expect(upAlphaIcon.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('trash can button triggers correct function', () => {
|
||||||
|
const columns = [{ name: 'Name', key: 'name', isSortable: true }];
|
||||||
|
const onOpenDeleteModal = jest.fn();
|
||||||
|
const openDeleteModalButton = 'button[aria-label="Delete"]';
|
||||||
|
const onSearch = jest.fn();
|
||||||
|
const onSort = jest.fn();
|
||||||
|
const onSelectAll = jest.fn();
|
||||||
|
const showDelete = true;
|
||||||
|
const disableTrashCanIcon = false;
|
||||||
|
|
||||||
|
toolbar = mount(
|
||||||
|
<I18nProvider>
|
||||||
|
<DataListToolbar
|
||||||
|
isAllSelected={false}
|
||||||
|
selected={() => [1, 2, 3, 4]}
|
||||||
|
sortedColumnKey="name"
|
||||||
|
sortOrder="ascending"
|
||||||
|
columns={columns}
|
||||||
|
onSearch={onSearch}
|
||||||
|
onSort={onSort}
|
||||||
|
onSelectAll={onSelectAll}
|
||||||
|
onOpenDeleteModal={onOpenDeleteModal}
|
||||||
|
showDelete={showDelete}
|
||||||
|
disableTrashCanIcon={disableTrashCanIcon}
|
||||||
|
/>
|
||||||
|
</I18nProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
toolbar.find(openDeleteModalButton).simulate('click');
|
||||||
|
expect(onOpenDeleteModal).toBeCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,45 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { I18nProvider } from '@lingui/react';
|
import { I18nProvider } from '@lingui/react';
|
||||||
import OrganizationsList from '../../../../src/pages/Organizations/screens/OrganizationsList';
|
import OrganizationsList from '../../../../src/pages/Organizations/screens/OrganizationsList';
|
||||||
|
|
||||||
|
const mockAPIOrgsList = {
|
||||||
|
data: {
|
||||||
|
results: [{
|
||||||
|
name: 'Organization 0',
|
||||||
|
id: 1,
|
||||||
|
summary_fields: {
|
||||||
|
related_field_counts: {
|
||||||
|
teams: 3,
|
||||||
|
users: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Organization 1',
|
||||||
|
id: 1,
|
||||||
|
summary_fields: {
|
||||||
|
related_field_counts: {
|
||||||
|
teams: 2,
|
||||||
|
users: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Organization 2',
|
||||||
|
id: 2,
|
||||||
|
summary_fields: {
|
||||||
|
related_field_counts: {
|
||||||
|
teams: 5,
|
||||||
|
users: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
isModalOpen: false,
|
||||||
|
warningTitle: 'title',
|
||||||
|
warningMsg: 'message'
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
describe('<OrganizationsList />', () => {
|
describe('<OrganizationsList />', () => {
|
||||||
test('initially renders succesfully', () => {
|
test('initially renders succesfully', () => {
|
||||||
mount(
|
mount(
|
||||||
@@ -17,4 +56,79 @@ describe('<OrganizationsList />', () => {
|
|||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.only('Modal closes when close button is clicked.', async (done) => {
|
||||||
|
const handleClearOrgsToDelete = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<MemoryRouter initialEntries={['/organizations']} initialIndex={0}>
|
||||||
|
<I18nProvider>
|
||||||
|
<OrganizationsList
|
||||||
|
match={{ path: '/organizations', url: '/organizations' }}
|
||||||
|
location={{ search: '', pathname: '/organizations' }}
|
||||||
|
getItems={({ data: { orgsToDelete: [{ name: 'Organization 1', id: 1 }] } })}
|
||||||
|
handleClearOrgsToDelete={handleClearOrgsToDelete()}
|
||||||
|
/>
|
||||||
|
</I18nProvider>
|
||||||
|
</MemoryRouter>
|
||||||
|
);
|
||||||
|
wrapper.find({ type: 'checkbox' }).simulate('click');
|
||||||
|
|
||||||
|
wrapper.find('DataListToolbar').prop('onOpenDeleteModal')();
|
||||||
|
expect(wrapper.find('OrganizationsList').state().isModalOpen).toEqual(true);
|
||||||
|
setImmediate(() => {
|
||||||
|
wrapper.update();
|
||||||
|
wrapper.setState({
|
||||||
|
selected: mockAPIOrgsList.data.results.map((result) => result.id),
|
||||||
|
orgsToDelete: mockAPIOrgsList.data.results.map((result) => result),
|
||||||
|
isModalOpen: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.find('button[aria-label="Close"]').simulate('click');
|
||||||
|
expect(handleClearOrgsToDelete).toBeCalled();
|
||||||
|
const list = wrapper.find('OrganizationsList');
|
||||||
|
expect(list.state().isModalOpen).toBe(false);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.only('Orgs to delete length is 0 when all orgs are selected and Delete button is called.', async (done) => {
|
||||||
|
const handleClearOrgsToDelete = jest.fn();
|
||||||
|
const handleOrgDelete = jest.fn();
|
||||||
|
const fetchOrganizations = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<MemoryRouter initialEntries={['/organizations']} initialIndex={0}>
|
||||||
|
<I18nProvider>
|
||||||
|
<OrganizationsList
|
||||||
|
match={{ path: '/organizations', url: '/organizations' }}
|
||||||
|
location={{ search: '', pathname: '/organizations' }}
|
||||||
|
getItems={({ data: { orgsToDelete: [{ name: 'Organization 1', id: 1 }] } })}
|
||||||
|
handleClearOrgsToDelete={handleClearOrgsToDelete()}
|
||||||
|
handleOrgDelete={handleOrgDelete()}
|
||||||
|
fetchOrganizations={fetchOrganizations()}
|
||||||
|
|
||||||
|
/>
|
||||||
|
</I18nProvider>
|
||||||
|
</MemoryRouter>
|
||||||
|
);
|
||||||
|
wrapper.find({ type: 'checkbox' }).simulate('click');
|
||||||
|
wrapper.find('button[aria-label="Delete"]').simulate('click');
|
||||||
|
|
||||||
|
wrapper.find('DataListToolbar').prop('onOpenDeleteModal')();
|
||||||
|
expect(wrapper.find('OrganizationsList').state().isModalOpen).toEqual(true);
|
||||||
|
setImmediate(() => {
|
||||||
|
wrapper.update();
|
||||||
|
wrapper.setState({
|
||||||
|
selected: mockAPIOrgsList.data.results.map((result) => result.id),
|
||||||
|
orgsToDelete: mockAPIOrgsList.data.results.map((result) => result),
|
||||||
|
isModalOpen: true,
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
|
const list = wrapper.find('OrganizationsList');
|
||||||
|
wrapper.find('button[aria-label="confirm-delete"]').simulate('click');
|
||||||
|
expect(list.state().orgsToDelete.length).toEqual(list.state().orgsDeleted.length);
|
||||||
|
expect(fetchOrganizations).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ class APIClient {
|
|||||||
return this.http.get(API_CONFIG);
|
return this.http.get(API_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyOrganization (id) {
|
||||||
|
const endpoint = `${API_ORGANIZATIONS}${id}/`;
|
||||||
|
return (this.http.delete(endpoint));
|
||||||
|
}
|
||||||
|
|
||||||
getOrganizations (params = {}) {
|
getOrganizations (params = {}) {
|
||||||
return this.http.get(API_ORGANIZATIONS, { params });
|
return this.http.get(API_ORGANIZATIONS, { params });
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/app.scss
13
src/app.scss
@@ -279,6 +279,17 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.orgListAlert-actionBtn{
|
||||||
|
margin:0 10px;
|
||||||
|
}
|
||||||
|
.orgListDetete-progressBar{
|
||||||
|
padding-right: 32px;
|
||||||
|
}
|
||||||
|
.orgListDelete-progressBar-noShow{
|
||||||
|
display: none;
|
||||||
|
padding-right: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.awx-c-form-action-group {
|
.awx-c-form-action-group {
|
||||||
float: right;
|
float: right;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -287,4 +298,4 @@
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,25 +28,26 @@ import VerticalSeparator from '../VerticalSeparator';
|
|||||||
class DataListToolbar extends React.Component {
|
class DataListToolbar extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
|
addUrl,
|
||||||
columns,
|
columns,
|
||||||
isAllSelected,
|
disableTrashCanIcon,
|
||||||
onSelectAll,
|
onSelectAll,
|
||||||
sortedColumnKey,
|
sortedColumnKey,
|
||||||
sortOrder,
|
sortOrder,
|
||||||
addUrl,
|
|
||||||
showDelete,
|
showDelete,
|
||||||
showSelectAll,
|
showSelectAll,
|
||||||
|
isAllSelected,
|
||||||
isLookup,
|
isLookup,
|
||||||
isCompact,
|
isCompact,
|
||||||
onSort,
|
onSort,
|
||||||
onSearch,
|
onSearch,
|
||||||
onCompact,
|
onCompact,
|
||||||
onExpand,
|
onExpand,
|
||||||
add
|
add,
|
||||||
|
onOpenDeleteModal
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const showExpandCollapse = (onCompact && onExpand);
|
const showExpandCollapse = (onCompact && onExpand);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<I18n>
|
<I18n>
|
||||||
{({ i18n }) => (
|
{({ i18n }) => (
|
||||||
@@ -115,10 +116,13 @@ class DataListToolbar extends React.Component {
|
|||||||
position="top"
|
position="top"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
className="awx-ToolBarBtn"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
aria-label={i18n._(t`Delete`)}
|
aria-label={i18n._(t`Delete`)}
|
||||||
|
onClick={onOpenDeleteModal}
|
||||||
|
isDisabled={disableTrashCanIcon}
|
||||||
>
|
>
|
||||||
<TrashAltIcon />
|
<TrashAltIcon className="awx-ToolBarTrashCanIcon" />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -80,3 +80,16 @@
|
|||||||
.awx-toolbar .pf-l-toolbar__item .pf-c-button.pf-m-plain {
|
.awx-toolbar .pf-l-toolbar__item .pf-c-button.pf-m-plain {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
.pf-c-button--disabled--BackgroundColor{
|
||||||
|
background-color: #b7b7b7;
|
||||||
|
}
|
||||||
|
.awx-ToolBarBtn{
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
.awx-ToolBarBtn:hover{
|
||||||
|
.awx-ToolBarTrashCanIcon {
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
background-color:#d9534f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,54 +11,61 @@ import {
|
|||||||
|
|
||||||
import VerticalSeparator from '../../../components/VerticalSeparator';
|
import VerticalSeparator from '../../../components/VerticalSeparator';
|
||||||
|
|
||||||
export default ({
|
class OrganizationListItem extends React.Component {
|
||||||
itemId,
|
render () {
|
||||||
name,
|
const {
|
||||||
userCount,
|
itemId,
|
||||||
teamCount,
|
name,
|
||||||
isSelected,
|
userCount,
|
||||||
onSelect,
|
teamCount,
|
||||||
detailUrl,
|
isSelected,
|
||||||
}) => (
|
onSelect,
|
||||||
<li key={itemId} className="pf-c-data-list__item" aria-labelledby="check-action-item1">
|
detailUrl,
|
||||||
<I18n>
|
} = this.props;
|
||||||
{({ i18n }) => (
|
return (
|
||||||
<Checkbox
|
<li key={itemId} className="pf-c-data-list__item" aria-labelledby="check-action-item1">
|
||||||
checked={isSelected}
|
<I18n>
|
||||||
onChange={onSelect}
|
{({ i18n }) => (
|
||||||
aria-label={i18n._(t`select organization ${itemId}`)}
|
<Checkbox
|
||||||
id={`select-organization-${itemId}`}
|
checked={isSelected}
|
||||||
/>
|
onChange={onSelect}
|
||||||
)}
|
aria-label={i18n._(t`select organization ${itemId}`)}
|
||||||
</I18n>
|
id={`select-organization-${itemId}`}
|
||||||
<VerticalSeparator />
|
/>
|
||||||
<div className="pf-c-data-list__cell">
|
)}
|
||||||
<span id="check-action-item1">
|
</I18n>
|
||||||
<Link
|
<VerticalSeparator />
|
||||||
to={`${detailUrl}`}
|
<div className="pf-c-data-list__cell">
|
||||||
>
|
<span id="check-action-item1">
|
||||||
<b>{name}</b>
|
<Link
|
||||||
</Link>
|
to={`${detailUrl}`}
|
||||||
</span>
|
>
|
||||||
</div>
|
<b>{name}</b>
|
||||||
<div className="pf-c-data-list__cell">
|
</Link>
|
||||||
<Link to={`${detailUrl}/access`}>
|
</span>
|
||||||
<Trans>Users</Trans>
|
</div>
|
||||||
</Link>
|
<div className="pf-c-data-list__cell">
|
||||||
<Badge isRead>
|
<Link to={`${detailUrl}/access`}>
|
||||||
{' '}
|
<Trans>Users</Trans>
|
||||||
{userCount}
|
</Link>
|
||||||
{' '}
|
<Badge isRead>
|
||||||
</Badge>
|
{' '}
|
||||||
<Link to={`${detailUrl}/teams`}>
|
{userCount}
|
||||||
<Trans>Teams</Trans>
|
{' '}
|
||||||
</Link>
|
</Badge>
|
||||||
<Badge isRead>
|
<Link to={`${detailUrl}/teams`}>
|
||||||
{' '}
|
<Trans>Teams</Trans>
|
||||||
{teamCount}
|
</Link>
|
||||||
{' '}
|
<Badge isRead>
|
||||||
</Badge>
|
{' '}
|
||||||
</div>
|
{teamCount}
|
||||||
<div className="pf-c-data-list__cell" />
|
{' '}
|
||||||
</li>
|
</Badge>
|
||||||
);
|
</div>
|
||||||
|
<div className="pf-c-data-list__cell" />
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default OrganizationListItem;
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,15 @@ import {
|
|||||||
EmptyState,
|
EmptyState,
|
||||||
EmptyStateIcon,
|
EmptyStateIcon,
|
||||||
EmptyStateBody,
|
EmptyStateBody,
|
||||||
|
Modal,
|
||||||
PageSection,
|
PageSection,
|
||||||
PageSectionVariants,
|
PageSectionVariants,
|
||||||
Title
|
Title,
|
||||||
|
Button,
|
||||||
|
Progress,
|
||||||
|
ProgressVariant
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
|
|
||||||
import { CubesIcon } from '@patternfly/react-icons';
|
import { CubesIcon } from '@patternfly/react-icons';
|
||||||
import DataListToolbar from '../../../components/DataListToolbar';
|
import DataListToolbar from '../../../components/DataListToolbar';
|
||||||
import OrganizationListItem from '../components/OrganizationListItem';
|
import OrganizationListItem from '../components/OrganizationListItem';
|
||||||
@@ -54,6 +59,11 @@ class OrganizationsList extends Component {
|
|||||||
loading: true,
|
loading: true,
|
||||||
results: [],
|
results: [],
|
||||||
selected: [],
|
selected: [],
|
||||||
|
isModalOpen: false,
|
||||||
|
orgsToDelete: [],
|
||||||
|
orgsDeleted: [],
|
||||||
|
deleteSuccess: false,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onSearch = this.onSearch.bind(this);
|
this.onSearch = this.onSearch.bind(this);
|
||||||
@@ -64,6 +74,9 @@ class OrganizationsList extends Component {
|
|||||||
this.onSelect = this.onSelect.bind(this);
|
this.onSelect = this.onSelect.bind(this);
|
||||||
this.updateUrl = this.updateUrl.bind(this);
|
this.updateUrl = this.updateUrl.bind(this);
|
||||||
this.fetchOrganizations = this.fetchOrganizations.bind(this);
|
this.fetchOrganizations = this.fetchOrganizations.bind(this);
|
||||||
|
this.handleOrgDelete = this.handleOrgDelete.bind(this);
|
||||||
|
this.handleOpenOrgDeleteModal = this.handleOpenOrgDeleteModal.bind(this);
|
||||||
|
this.handleClearOrgsToDelete = this.handleClearOrgsToDelete.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@@ -129,6 +142,60 @@ class OrganizationsList extends Component {
|
|||||||
return Object.assign({}, this.defaultParams, searchParams, overrides);
|
return Object.assign({}, this.defaultParams, searchParams, overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleClearOrgsToDelete () {
|
||||||
|
this.setState({
|
||||||
|
isModalOpen: false,
|
||||||
|
orgsDeleted: [],
|
||||||
|
deleteSuccess: false,
|
||||||
|
orgsToDelete: [],
|
||||||
|
deleteStarted: false
|
||||||
|
});
|
||||||
|
this.onSelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOpenOrgDeleteModal () {
|
||||||
|
const { results, selected } = this.state;
|
||||||
|
const warningTitle = i18nMark('Delete Organization');
|
||||||
|
const warningMsg = i18nMark('Are you sure you want to delete:');
|
||||||
|
|
||||||
|
const orgsToDelete = [];
|
||||||
|
results.forEach((result) => {
|
||||||
|
selected.forEach((selectedOrg) => {
|
||||||
|
if (result.id === selectedOrg) {
|
||||||
|
orgsToDelete.push({ name: result.name, id: selectedOrg });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.setState({
|
||||||
|
orgsToDelete,
|
||||||
|
isModalOpen: true,
|
||||||
|
warningTitle,
|
||||||
|
warningMsg,
|
||||||
|
loading: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleOrgDelete (event) {
|
||||||
|
const { orgsToDelete, orgsDeleted } = this.state;
|
||||||
|
const { api } = this.props;
|
||||||
|
this.setState({ deleteStarted: true });
|
||||||
|
|
||||||
|
orgsToDelete.forEach(async (org) => {
|
||||||
|
try {
|
||||||
|
const res = await api.destroyOrganization(org.id);
|
||||||
|
this.setState({
|
||||||
|
orgsDeleted: orgsDeleted.concat(res)
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
this.setState({ deleteSuccess: false });
|
||||||
|
} finally {
|
||||||
|
this.setState({ deleteSuccess: true });
|
||||||
|
const queryParams = this.getQueryParams();
|
||||||
|
this.fetchOrganizations(queryParams);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
updateUrl (queryParams) {
|
updateUrl (queryParams) {
|
||||||
const { history, location } = this.props;
|
const { history, location } = this.props;
|
||||||
const pathname = '/organizations';
|
const pathname = '/organizations';
|
||||||
@@ -194,20 +261,65 @@ class OrganizationsList extends Component {
|
|||||||
const {
|
const {
|
||||||
count,
|
count,
|
||||||
error,
|
error,
|
||||||
|
deleteSuccess,
|
||||||
|
deleteStarted,
|
||||||
loading,
|
loading,
|
||||||
noInitialResults,
|
noInitialResults,
|
||||||
|
orgsToDelete,
|
||||||
|
orgsDeleted,
|
||||||
page,
|
page,
|
||||||
pageCount,
|
pageCount,
|
||||||
page_size,
|
page_size,
|
||||||
|
selected,
|
||||||
sortedColumnKey,
|
sortedColumnKey,
|
||||||
sortOrder,
|
sortOrder,
|
||||||
results,
|
results,
|
||||||
selected,
|
isModalOpen,
|
||||||
|
warningTitle,
|
||||||
|
warningMsg,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { match } = this.props;
|
const { match } = this.props;
|
||||||
return (
|
return (
|
||||||
<PageSection variant={medium}>
|
<PageSection variant={medium}>
|
||||||
<Card>
|
<Card>
|
||||||
|
{ isModalOpen && (
|
||||||
|
<Modal
|
||||||
|
className="orgListAlert"
|
||||||
|
title={warningTitle}
|
||||||
|
isOpen={isModalOpen}
|
||||||
|
style={{ width: '1000px' }}
|
||||||
|
variant="danger"
|
||||||
|
onClose={this.handleClearOrgsToDelete}
|
||||||
|
>
|
||||||
|
{warningMsg}
|
||||||
|
<br />
|
||||||
|
{orgsToDelete.map((org) => (
|
||||||
|
<span key={org.id}>
|
||||||
|
<strong>
|
||||||
|
{org.name}
|
||||||
|
</strong>
|
||||||
|
<br />
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
<div className={deleteStarted ? 'orgListDetete-progressBar' : 'orgListDelete-progressBar-noShow'}>
|
||||||
|
<Progress
|
||||||
|
value={deleteSuccess ? 100 : 67}
|
||||||
|
variant={deleteStarted ? ProgressVariant.success : ProgressVariant.danger}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div className="awx-c-form-action-group">
|
||||||
|
{orgsDeleted.length
|
||||||
|
? <Button className="orgListAlert-actionBtn" keys="cancel" variant="primary" aria-label="close-delete" onClick={this.handleClearOrgsToDelete}>Close</Button>
|
||||||
|
: (
|
||||||
|
<span>
|
||||||
|
<Button className="orgListAlert-actionBtn" keys="cancel" variant="secondary" aria-label="cancel-delete" onClick={this.handleClearOrgsToDelete}>Cancel</Button>
|
||||||
|
<Button className="orgListAlert-actionBtn" keys="cancel" variant="danger" aria-label="confirm-delete" onClick={this.handleOrgDelete}>Delete</Button>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
{noInitialResults && (
|
{noInitialResults && (
|
||||||
<EmptyState>
|
<EmptyState>
|
||||||
<EmptyStateIcon icon={CubesIcon} />
|
<EmptyStateIcon icon={CubesIcon} />
|
||||||
@@ -229,6 +341,8 @@ class OrganizationsList extends Component {
|
|||||||
onSearch={this.onSearch}
|
onSearch={this.onSearch}
|
||||||
onSort={this.onSort}
|
onSort={this.onSort}
|
||||||
onSelectAll={this.onSelectAll}
|
onSelectAll={this.onSelectAll}
|
||||||
|
onOpenDeleteModal={this.handleOpenOrgDeleteModal}
|
||||||
|
disableTrashCanIcon={selected.length === 0}
|
||||||
showDelete
|
showDelete
|
||||||
showSelectAll
|
showSelectAll
|
||||||
/>
|
/>
|
||||||
@@ -244,7 +358,8 @@ class OrganizationsList extends Component {
|
|||||||
userCount={o.summary_fields.related_field_counts.users}
|
userCount={o.summary_fields.related_field_counts.users}
|
||||||
teamCount={o.summary_fields.related_field_counts.teams}
|
teamCount={o.summary_fields.related_field_counts.teams}
|
||||||
isSelected={selected.includes(o.id)}
|
isSelected={selected.includes(o.id)}
|
||||||
onSelect={() => this.onSelect(o.id)}
|
onSelect={() => this.onSelect(o.id, o.name)}
|
||||||
|
onOpenOrgDeleteModal={this.handleOpenOrgDeleteModal}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user