([1, 2, 3, 4])}
+ selected={() => [1, 2, 3, 4]}
sortedColumnKey="name"
sortOrder="ascending"
columns={columns}
diff --git a/__tests__/pages/Organizations/screens/OrganizationsList.test.jsx b/__tests__/pages/Organizations/screens/OrganizationsList.test.jsx
index 6b7f49646d..6b62d9343f 100644
--- a/__tests__/pages/Organizations/screens/OrganizationsList.test.jsx
+++ b/__tests__/pages/Organizations/screens/OrganizationsList.test.jsx
@@ -4,6 +4,45 @@ import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
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('', () => {
test('initially renders succesfully', () => {
mount(
@@ -17,4 +56,81 @@ describe('', () => {
);
});
+
+ test.only('Modal closes when close button is clicked.', async (done) => {
+ const handleClearOrgsToDelete = jest.fn();
+ const wrapper = mount(
+
+
+
+
+
+ );
+ 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.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(
+
+
+
+
+
+ );
+ 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();
+ expect(list.state().results).toHaveLength(0);
+ done();
+ });
+ });
});
diff --git a/src/app.scss b/src/app.scss
index 6a6ef32afe..b8606fd856 100644
--- a/src/app.scss
+++ b/src/app.scss
@@ -282,6 +282,13 @@
.orgListAlert-actionBtn{
margin:0 10px;
}
+.orgListDetete-progressBar{
+ padding-right: 32px;
+}
+.orgListDelete-progressBar-noShow{
+ display: none;
+ padding-right: 32px;
+}
.awx-c-form-action-group {
float: right;
diff --git a/src/pages/Organizations/components/OrganizationListItem.jsx b/src/pages/Organizations/components/OrganizationListItem.jsx
index 55eea410d9..4a8309ba11 100644
--- a/src/pages/Organizations/components/OrganizationListItem.jsx
+++ b/src/pages/Organizations/components/OrganizationListItem.jsx
@@ -4,11 +4,7 @@ import { Trans, t } from '@lingui/macro';
import {
Badge,
Checkbox,
- Button,
} from '@patternfly/react-core';
-import {
- TrashAltIcon,
-} from '@patternfly/react-icons';
import {
Link
} from 'react-router-dom';
diff --git a/src/pages/Organizations/screens/OrganizationsList.jsx b/src/pages/Organizations/screens/OrganizationsList.jsx
index 9da3b1f85e..0ed9ce0d3d 100644
--- a/src/pages/Organizations/screens/OrganizationsList.jsx
+++ b/src/pages/Organizations/screens/OrganizationsList.jsx
@@ -16,8 +16,11 @@ import {
PageSection,
PageSectionVariants,
Title,
- Button
+ Button,
+ Progress,
+ ProgressVariant
} from '@patternfly/react-core';
+
import { CubesIcon } from '@patternfly/react-icons';
import DataListToolbar from '../../../components/DataListToolbar';
import OrganizationListItem from '../components/OrganizationListItem';
@@ -57,7 +60,10 @@ class OrganizationsList extends Component {
results: [],
selected: [],
isModalOpen: false,
- orgsToDelete: []
+ orgsToDelete: [],
+ orgsDeleted: [],
+ deleteSuccess: false,
+
};
this.onSearch = this.onSearch.bind(this);
@@ -137,7 +143,12 @@ class OrganizationsList extends Component {
}
handleClearOrgsToDelete () {
- this.setState(({ isModalOpen }) => ({ isModalOpen: !isModalOpen, orgsToDelete: [] }));
+ this.setState({
+ isModalOpen: false,
+ orgsDeleted: [],
+ deleteSuccess: false,
+ orgsToDelete: []
+ });
this.onSelectAll();
}
@@ -163,20 +174,24 @@ class OrganizationsList extends Component {
}
async handleOrgDelete (event) {
- const { orgsToDelete } = this.state;
+ const { orgsToDelete, orgsDeleted } = this.state;
const { api } = this.props;
- try {
- const deleteOrgsApiCalls = [];
+ this.setState({ deleteStarted: true });
- orgsToDelete.forEach((org) => {
- deleteOrgsApiCalls.push(api.destroyOrganization(org.id));
- });
- await Promise.all(deleteOrgsApiCalls);
- } finally {
- this.handleClearOrgsToDelete();
- const queryParams = this.getQueryParams();
- this.fetchOrganizations(queryParams);
- }
+ 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();
}
@@ -245,9 +260,12 @@ class OrganizationsList extends Component {
const {
count,
error,
+ deleteSuccess,
+ deleteStarted,
loading,
noInitialResults,
orgsToDelete,
+ orgsDeleted,
page,
pageCount,
page_size,
@@ -266,7 +284,6 @@ class OrganizationsList extends Component {
{ isModalOpen && (
{orgsToDelete.map((org) => (
-
- {org.name}
+
+
+ {org.name}
+
-
+
))}
+
-
-
-
-
+
+ {orgsDeleted.length
+ ?
+ : (
+
+
+
+
+ )}
+
)}
{noInitialResults && (