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:
parent
aea12169f4
commit
889f8078d2
4 changed files with 85 additions and 22 deletions
|
@ -48,9 +48,9 @@ export const GroupsCreateModal = ({
|
||||||
await httpClient.doPost(`/admin/realms/${realm}/groups`, {
|
await httpClient.doPost(`/admin/realms/${realm}/groups`, {
|
||||||
name: createGroupName,
|
name: createGroupName,
|
||||||
});
|
});
|
||||||
|
refresh();
|
||||||
setIsCreateModalOpen(false);
|
setIsCreateModalOpen(false);
|
||||||
setCreateGroupName("");
|
setCreateGroupName("");
|
||||||
refresh();
|
|
||||||
addAlert(t("groupCreated"), AlertVariant.success);
|
addAlert(t("groupCreated"), AlertVariant.success);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addAlert(
|
addAlert(
|
||||||
|
|
|
@ -16,6 +16,8 @@ import { useAlerts } from "../components/alert/Alerts";
|
||||||
export type GroupsListProps = {
|
export type GroupsListProps = {
|
||||||
list?: GroupRepresentation[];
|
list?: GroupRepresentation[];
|
||||||
refresh: () => void;
|
refresh: () => void;
|
||||||
|
tableRowSelectedArray: number[];
|
||||||
|
setTableRowSelectedArray: (tableRowSelectedArray: number[]) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FormattedData = {
|
type FormattedData = {
|
||||||
|
@ -23,7 +25,12 @@ type FormattedData = {
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const GroupsList = ({ list, refresh }: GroupsListProps) => {
|
export const GroupsList = ({
|
||||||
|
list,
|
||||||
|
refresh,
|
||||||
|
tableRowSelectedArray,
|
||||||
|
setTableRowSelectedArray,
|
||||||
|
}: GroupsListProps) => {
|
||||||
const { t } = useTranslation("groups");
|
const { t } = useTranslation("groups");
|
||||||
const httpClient = useContext(HttpClientContext)!;
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
const columnGroupName: keyof GroupRepresentation = "name";
|
const columnGroupName: keyof GroupRepresentation = "name";
|
||||||
|
@ -67,7 +74,22 @@ export const GroupsList = ({ list, refresh }: GroupsListProps) => {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
localRow = [...formattedData];
|
localRow = [...formattedData];
|
||||||
|
const localTableRow = [...tableRowSelectedArray];
|
||||||
|
if (localRow[rowId].selected !== isSelected) {
|
||||||
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);
|
setFormattedData(localRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +111,7 @@ export const GroupsList = ({ list, refresh }: GroupsListProps) => {
|
||||||
`/admin/realms/${realm}/groups/${list![rowId].id}`
|
`/admin/realms/${realm}/groups/${list![rowId].id}`
|
||||||
);
|
);
|
||||||
refresh();
|
refresh();
|
||||||
|
setTableRowSelectedArray([]);
|
||||||
addAlert(t("Group deleted"), AlertVariant.success);
|
addAlert(t("Group deleted"), AlertVariant.success);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
|
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
|
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
|
import { RealmContext } from "../context/realm-context/RealmContext";
|
||||||
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
@ -20,6 +22,7 @@ import {
|
||||||
PageSectionVariants,
|
PageSectionVariants,
|
||||||
Spinner,
|
Spinner,
|
||||||
ToolbarItem,
|
ToolbarItem,
|
||||||
|
AlertVariant,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import "./GroupsSection.css";
|
import "./GroupsSection.css";
|
||||||
|
|
||||||
|
@ -27,24 +30,28 @@ export const GroupsSection = () => {
|
||||||
const { t } = useTranslation("groups");
|
const { t } = useTranslation("groups");
|
||||||
const httpClient = useContext(HttpClientContext)!;
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
const [rawData, setRawData] = useState<{ [key: string]: any }[]>();
|
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 [isKebabOpen, setIsKebabOpen] = useState(false);
|
||||||
const [createGroupName, setCreateGroupName] = useState("");
|
const [createGroupName, setCreateGroupName] = useState("");
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
|
const [tableRowSelectedArray, setTableRowSelectedArray] = useState<
|
||||||
|
Array<number>
|
||||||
|
>([]);
|
||||||
const columnID: keyof GroupRepresentation = "id";
|
const columnID: keyof GroupRepresentation = "id";
|
||||||
const membersLength: keyof GroupRepresentation = "membersLength";
|
const membersLength: keyof GroupRepresentation = "membersLength";
|
||||||
const columnGroupName: keyof GroupRepresentation = "name";
|
const columnGroupName: keyof GroupRepresentation = "name";
|
||||||
|
const { addAlert } = useAlerts();
|
||||||
|
const { realm } = useContext(RealmContext);
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
const groups = await httpClient.doGet<ServerGroupsArrayRepresentation[]>(
|
const groups = await httpClient.doGet<ServerGroupsArrayRepresentation[]>(
|
||||||
"/admin/realms/master/groups"
|
`/admin/realms/${realm}/groups`
|
||||||
);
|
);
|
||||||
const groupsData = groups.data!;
|
const groupsData = groups.data!;
|
||||||
|
|
||||||
const getMembers = async (id: number) => {
|
const getMembers = async (id: number) => {
|
||||||
const response = await httpClient.doGet<
|
const response = await httpClient.doGet<
|
||||||
ServerGroupMembersRepresentation[]
|
ServerGroupMembersRepresentation[]
|
||||||
>(`/admin/realms/master/groups/${id}/members`);
|
>(`/admin/realms/${realm}/groups/${id}/members`);
|
||||||
const responseData = response.data!;
|
const responseData = response.data!;
|
||||||
return responseData.length;
|
return responseData.length;
|
||||||
};
|
};
|
||||||
|
@ -60,7 +67,7 @@ export const GroupsSection = () => {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
setFilteredData(updatedObject);
|
||||||
setRawData(updatedObject);
|
setRawData(updatedObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,6 +97,31 @@ export const GroupsSection = () => {
|
||||||
setIsCreateModalOpen(!isCreateModalOpen);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewHeader titleKey="groups:groups" subKey="groups:groupsDescription" />
|
<ViewHeader titleKey="groups:groups" subKey="groups:groupsDescription" />
|
||||||
|
@ -122,8 +154,12 @@ export const GroupsSection = () => {
|
||||||
isOpen={isKebabOpen}
|
isOpen={isKebabOpen}
|
||||||
isPlain
|
isPlain
|
||||||
dropdownItems={[
|
dropdownItems={[
|
||||||
<DropdownItem key="action" component="button">
|
<DropdownItem
|
||||||
{t("delete")}
|
key="action"
|
||||||
|
component="button"
|
||||||
|
onClick={() => multiDelete()}
|
||||||
|
>
|
||||||
|
{t("common:Delete")}
|
||||||
</DropdownItem>,
|
</DropdownItem>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -135,6 +171,8 @@ export const GroupsSection = () => {
|
||||||
<GroupsList
|
<GroupsList
|
||||||
list={filteredData ? filteredData : rawData}
|
list={filteredData ? filteredData : rawData}
|
||||||
refresh={loader}
|
refresh={loader}
|
||||||
|
tableRowSelectedArray={tableRowSelectedArray}
|
||||||
|
setTableRowSelectedArray={setTableRowSelectedArray}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{filteredData && filteredData.length === 0 && (
|
{filteredData && filteredData.length === 0 && (
|
||||||
|
@ -146,6 +184,16 @@ export const GroupsSection = () => {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</TableToolbar>
|
</TableToolbar>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<ListEmptyState
|
||||||
|
hasIcon={true}
|
||||||
|
message={t("noGroupsInThisRealm")}
|
||||||
|
instructions={t("noGroupsInThisRealmInstructions")}
|
||||||
|
primaryActionText={t("createGroup")}
|
||||||
|
onPrimaryAction={() => handleModalToggle()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<GroupsCreateModal
|
<GroupsCreateModal
|
||||||
isCreateModalOpen={isCreateModalOpen}
|
isCreateModalOpen={isCreateModalOpen}
|
||||||
handleModalToggle={handleModalToggle}
|
handleModalToggle={handleModalToggle}
|
||||||
|
@ -154,15 +202,6 @@ export const GroupsSection = () => {
|
||||||
setCreateGroupName={setCreateGroupName}
|
setCreateGroupName={setCreateGroupName}
|
||||||
refresh={loader}
|
refresh={loader}
|
||||||
/>
|
/>
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<ListEmptyState
|
|
||||||
hasIcon={true}
|
|
||||||
message={t("noGroupsInThisRealm")}
|
|
||||||
instructions={t("noGroupsInThisRealmInstructions")}
|
|
||||||
primaryActionText={t("createGroup")}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</PageSection>
|
</PageSection>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"members": "Members",
|
"members": "Members",
|
||||||
"moveTo": "Move to",
|
"moveTo": "Move to",
|
||||||
"delete": "Delete",
|
|
||||||
"tableOfGroups": "Table of groups",
|
"tableOfGroups": "Table of groups",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"groupsDescription": "Description goes here",
|
"groupsDescription": "Description goes here",
|
||||||
|
@ -18,7 +17,9 @@
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
"noSearchResults": "No search results",
|
"noSearchResults": "No search results",
|
||||||
"noSearchResultsInstructions": "Click on the search bar above to search for groups",
|
"noSearchResultsInstructions": "Click on the search bar above to search for groups",
|
||||||
"noGroupsInThisRealm" : "No groups in this Realm",
|
"noGroupsInThisRealm": "No groups in this realm",
|
||||||
"noGroupsInThisRealmInstructions" : "You haven't created any groups in this realm. Create a group to get started."
|
"noGroupsInThisRealmInstructions": "You haven't created any groups in this realm. Create a group to get started.",
|
||||||
|
"groupsDeleted": "Groups deleted",
|
||||||
|
"groupDeleteError": "Error deleting group"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue