add multiple group delete functionality (#185)

* add multiple group delete functionality

* fix the deleting bug and deleting during filering

* fix stans comment

* format files

* fix lint

* fix lint

* fix messages

* fix modal

* fix error mark found
This commit is contained in:
Christie Molloy 2020-10-27 19:45:35 -04:00 committed by GitHub
parent aea12169f4
commit 889f8078d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 22 deletions

View file

@ -48,9 +48,9 @@ export const GroupsCreateModal = ({
await httpClient.doPost(`/admin/realms/${realm}/groups`, {
name: createGroupName,
});
refresh();
setIsCreateModalOpen(false);
setCreateGroupName("");
refresh();
addAlert(t("groupCreated"), AlertVariant.success);
} catch (error) {
addAlert(

View file

@ -16,6 +16,8 @@ import { useAlerts } from "../components/alert/Alerts";
export type GroupsListProps = {
list?: GroupRepresentation[];
refresh: () => void;
tableRowSelectedArray: number[];
setTableRowSelectedArray: (tableRowSelectedArray: number[]) => void;
};
type FormattedData = {
@ -23,7 +25,12 @@ type FormattedData = {
selected: boolean;
};
export const GroupsList = ({ list, refresh }: GroupsListProps) => {
export const GroupsList = ({
list,
refresh,
tableRowSelectedArray,
setTableRowSelectedArray,
}: GroupsListProps) => {
const { t } = useTranslation("groups");
const httpClient = useContext(HttpClientContext)!;
const columnGroupName: keyof GroupRepresentation = "name";
@ -67,7 +74,22 @@ export const GroupsList = ({ list, refresh }: GroupsListProps) => {
});
} else {
localRow = [...formattedData];
localRow[rowId].selected = isSelected;
const localTableRow = [...tableRowSelectedArray];
if (localRow[rowId].selected !== isSelected) {
localRow[rowId].selected = isSelected;
}
if (localTableRow.includes(rowId)) {
const index = localTableRow.indexOf(rowId);
if (index === 0) {
localTableRow.shift();
} else {
localTableRow.splice(index, 1);
}
setTableRowSelectedArray(localTableRow);
} else {
setTableRowSelectedArray([rowId, ...tableRowSelectedArray]);
}
setFormattedData(localRow);
}
}
@ -89,6 +111,7 @@ export const GroupsList = ({ list, refresh }: GroupsListProps) => {
`/admin/realms/${realm}/groups/${list![rowId].id}`
);
refresh();
setTableRowSelectedArray([]);
addAlert(t("Group deleted"), AlertVariant.success);
} catch (error) {
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);

View file

@ -11,6 +11,8 @@ import {
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
import { RealmContext } from "../context/realm-context/RealmContext";
import { useAlerts } from "../components/alert/Alerts";
import {
Button,
Dropdown,
@ -20,6 +22,7 @@ import {
PageSectionVariants,
Spinner,
ToolbarItem,
AlertVariant,
} from "@patternfly/react-core";
import "./GroupsSection.css";
@ -27,24 +30,28 @@ export const GroupsSection = () => {
const { t } = useTranslation("groups");
const httpClient = useContext(HttpClientContext)!;
const [rawData, setRawData] = useState<{ [key: string]: any }[]>();
const [filteredData, setFilteredData] = useState<object[]>();
const [filteredData, setFilteredData] = useState<{ [key: string]: any }[]>();
const [isKebabOpen, setIsKebabOpen] = useState(false);
const [createGroupName, setCreateGroupName] = useState("");
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [tableRowSelectedArray, setTableRowSelectedArray] = useState<
Array<number>
>([]);
const columnID: keyof GroupRepresentation = "id";
const membersLength: keyof GroupRepresentation = "membersLength";
const columnGroupName: keyof GroupRepresentation = "name";
const { addAlert } = useAlerts();
const { realm } = useContext(RealmContext);
const loader = async () => {
const groups = await httpClient.doGet<ServerGroupsArrayRepresentation[]>(
"/admin/realms/master/groups"
`/admin/realms/${realm}/groups`
);
const groupsData = groups.data!;
const getMembers = async (id: number) => {
const response = await httpClient.doGet<
ServerGroupMembersRepresentation[]
>(`/admin/realms/master/groups/${id}/members`);
>(`/admin/realms/${realm}/groups/${id}/members`);
const responseData = response.data!;
return responseData.length;
};
@ -60,7 +67,7 @@ export const GroupsSection = () => {
return object;
}
);
setFilteredData(updatedObject);
setRawData(updatedObject);
};
@ -90,6 +97,31 @@ export const GroupsSection = () => {
setIsCreateModalOpen(!isCreateModalOpen);
};
const multiDelete = async () => {
if (tableRowSelectedArray.length !== 0) {
const deleteGroup = async (rowId: number) => {
try {
await httpClient.doDelete(
`/admin/realms/${realm}/groups/${
filteredData ? filteredData![rowId].id : rawData![rowId].id
}`
);
loader();
} catch (error) {
addAlert(`${t("groupDeleteError")} ${error}`, AlertVariant.danger);
}
};
const chainedPromises = tableRowSelectedArray.map((rowId: number) => {
deleteGroup(rowId);
});
await Promise.all(chainedPromises)
.then(() => addAlert(t("groupsDeleted"), AlertVariant.success))
.then(() => setTableRowSelectedArray([]));
}
};
return (
<>
<ViewHeader titleKey="groups:groups" subKey="groups:groupsDescription" />
@ -122,8 +154,12 @@ export const GroupsSection = () => {
isOpen={isKebabOpen}
isPlain
dropdownItems={[
<DropdownItem key="action" component="button">
{t("delete")}
<DropdownItem
key="action"
component="button"
onClick={() => multiDelete()}
>
{t("common:Delete")}
</DropdownItem>,
]}
/>
@ -135,6 +171,8 @@ export const GroupsSection = () => {
<GroupsList
list={filteredData ? filteredData : rawData}
refresh={loader}
tableRowSelectedArray={tableRowSelectedArray}
setTableRowSelectedArray={setTableRowSelectedArray}
/>
)}
{filteredData && filteredData.length === 0 && (
@ -146,14 +184,6 @@ export const GroupsSection = () => {
/>
)}
</TableToolbar>
<GroupsCreateModal
isCreateModalOpen={isCreateModalOpen}
handleModalToggle={handleModalToggle}
setIsCreateModalOpen={setIsCreateModalOpen}
createGroupName={createGroupName}
setCreateGroupName={setCreateGroupName}
refresh={loader}
/>
</>
) : (
<ListEmptyState
@ -161,8 +191,17 @@ export const GroupsSection = () => {
message={t("noGroupsInThisRealm")}
instructions={t("noGroupsInThisRealmInstructions")}
primaryActionText={t("createGroup")}
onPrimaryAction={() => handleModalToggle()}
/>
)}
<GroupsCreateModal
isCreateModalOpen={isCreateModalOpen}
handleModalToggle={handleModalToggle}
setIsCreateModalOpen={setIsCreateModalOpen}
createGroupName={createGroupName}
setCreateGroupName={setCreateGroupName}
refresh={loader}
/>
</PageSection>
</>
);

View file

@ -8,7 +8,6 @@
"search": "Search",
"members": "Members",
"moveTo": "Move to",
"delete": "Delete",
"tableOfGroups": "Table of groups",
"name": "Name",
"groupsDescription": "Description goes here",
@ -17,8 +16,10 @@
"createAGroup": "Create a group",
"create": "Create",
"noSearchResults": "No search results",
"noSearchResultsInstructions" : "Click on the search bar above to search for groups",
"noGroupsInThisRealm" : "No groups in this Realm",
"noGroupsInThisRealmInstructions" : "You haven't created any groups in this realm. Create a group to get started."
"noSearchResultsInstructions": "Click on the search bar above to search for groups",
"noGroupsInThisRealm": "No groups in this realm",
"noGroupsInThisRealmInstructions": "You haven't created any groups in this realm. Create a group to get started.",
"groupsDeleted": "Groups deleted",
"groupDeleteError": "Error deleting group"
}
}