{({ i18n }) => (
@@ -115,10 +117,13 @@ class DataListToolbar extends React.Component {
position="top"
>
)}
diff --git a/src/components/DataListToolbar/styles.scss b/src/components/DataListToolbar/styles.scss
index e8d989da3c..c91bdb727c 100644
--- a/src/components/DataListToolbar/styles.scss
+++ b/src/components/DataListToolbar/styles.scss
@@ -80,3 +80,16 @@
.awx-toolbar .pf-l-toolbar__item .pf-c-button.pf-m-plain {
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;
+}
+
diff --git a/src/pages/Organizations/components/OrganizationListItem.jsx b/src/pages/Organizations/components/OrganizationListItem.jsx
index 19adbd98df..55eea410d9 100644
--- a/src/pages/Organizations/components/OrganizationListItem.jsx
+++ b/src/pages/Organizations/components/OrganizationListItem.jsx
@@ -4,61 +4,72 @@ 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';
import VerticalSeparator from '../../../components/VerticalSeparator';
-export default ({
- itemId,
- name,
- userCount,
- teamCount,
- isSelected,
- onSelect,
- detailUrl,
-}) => (
-
-
- {({ i18n }) => (
-
- )}
-
-
-
-
-
- {name}
-
-
-
-
-
- Users
-
-
- {' '}
- {userCount}
- {' '}
-
-
- Teams
-
-
- {' '}
- {teamCount}
- {' '}
-
-
-
-
-);
+class OrganizationListItem extends React.Component {
+ render () {
+ const {
+ itemId,
+ name,
+ userCount,
+ teamCount,
+ isSelected,
+ onSelect,
+ detailUrl,
+ } = this.props;
+ return (
+
+
+ {({ i18n }) => (
+
+ )}
+
+
+
+
+
+ {name}
+
+
+
+
+
+ Users
+
+
+ {' '}
+ {userCount}
+ {' '}
+
+
+ Teams
+
+
+ {' '}
+ {teamCount}
+ {' '}
+
+
+
+
+ );
+ }
+}
+export default OrganizationListItem;
+
diff --git a/src/pages/Organizations/screens/OrganizationsList.jsx b/src/pages/Organizations/screens/OrganizationsList.jsx
index 19c553aa67..9da3b1f85e 100644
--- a/src/pages/Organizations/screens/OrganizationsList.jsx
+++ b/src/pages/Organizations/screens/OrganizationsList.jsx
@@ -12,9 +12,11 @@ import {
EmptyState,
EmptyStateIcon,
EmptyStateBody,
+ Modal,
PageSection,
PageSectionVariants,
- Title
+ Title,
+ Button
} from '@patternfly/react-core';
import { CubesIcon } from '@patternfly/react-icons';
import DataListToolbar from '../../../components/DataListToolbar';
@@ -54,6 +56,8 @@ class OrganizationsList extends Component {
loading: true,
results: [],
selected: [],
+ isModalOpen: false,
+ orgsToDelete: []
};
this.onSearch = this.onSearch.bind(this);
@@ -64,6 +68,9 @@ class OrganizationsList extends Component {
this.onSelect = this.onSelect.bind(this);
this.updateUrl = this.updateUrl.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 () {
@@ -129,6 +136,50 @@ class OrganizationsList extends Component {
return Object.assign({}, this.defaultParams, searchParams, overrides);
}
+ handleClearOrgsToDelete () {
+ this.setState(({ isModalOpen }) => ({ isModalOpen: !isModalOpen, orgsToDelete: [] }));
+ 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 } = this.state;
+ const { api } = this.props;
+ try {
+ const deleteOrgsApiCalls = [];
+
+ orgsToDelete.forEach((org) => {
+ deleteOrgsApiCalls.push(api.destroyOrganization(org.id));
+ });
+ await Promise.all(deleteOrgsApiCalls);
+ } finally {
+ this.handleClearOrgsToDelete();
+ const queryParams = this.getQueryParams();
+ this.fetchOrganizations(queryParams);
+ }
+ event.preventDefault();
+ }
+
updateUrl (queryParams) {
const { history, location } = this.props;
const pathname = '/organizations';
@@ -196,18 +247,47 @@ class OrganizationsList extends Component {
error,
loading,
noInitialResults,
+ orgsToDelete,
page,
pageCount,
page_size,
+ selected,
sortedColumnKey,
sortOrder,
results,
- selected,
+ isModalOpen,
+ warningTitle,
+ warningMsg,
} = this.state;
const { match } = this.props;
return (
+ { isModalOpen && (
+
+ {warningMsg}
+
+ {orgsToDelete.map((org) => (
+
+ {org.name}
+
+
+ ))}
+
+
+
+
+
+
+ )}
{noInitialResults && (
@@ -229,6 +309,8 @@ class OrganizationsList extends Component {
onSearch={this.onSearch}
onSort={this.onSort}
onSelectAll={this.onSelectAll}
+ onOpenDeleteModal={this.handleOpenOrgDeleteModal}
+ disableTrashCanIcon={selected.length === 0}
showDelete
showSelectAll
/>
@@ -244,7 +326,8 @@ class OrganizationsList extends Component {
userCount={o.summary_fields.related_field_counts.users}
teamCount={o.summary_fields.related_field_counts.teams}
isSelected={selected.includes(o.id)}
- onSelect={() => this.onSelect(o.id)}
+ onSelect={() => this.onSelect(o.id, o.name)}
+ onOpenOrgDeleteModal={this.handleOpenOrgDeleteModal}
/>
))}