Changed the way the table is updated (#2505)

This commit is contained in:
Erik Jan de Wit 2022-04-27 10:48:32 +02:00 committed by GitHub
parent 241e97364e
commit 49086653e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 74 deletions

View file

@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { findIndex } from "lodash-es";
import { import {
Badge, Badge,
Button, Button,
@ -15,11 +14,11 @@ import {
SelectVariant, SelectVariant,
ToolbarItem, ToolbarItem,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { FilterIcon } from "@patternfly/react-icons";
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation"; import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import { KeycloakDataTable } from "../table-toolbar/KeycloakDataTable"; import { KeycloakDataTable } from "../table-toolbar/KeycloakDataTable";
import { useFetch, useAdminClient } from "../../context/auth/AdminClient"; import { useFetch, useAdminClient } from "../../context/auth/AdminClient";
import { FilterIcon } from "@patternfly/react-icons";
import { import {
castAdminClient, castAdminClient,
mapping, mapping,
@ -27,6 +26,7 @@ import {
Row, Row,
ServiceRole, ServiceRole,
} from "./RoleMapping"; } from "./RoleMapping";
import { KeycloakSpinner } from "../keycloak-spinner/KeycloakSpinner";
type AddRoleMappingModalProps = { type AddRoleMappingModalProps = {
id: string; id: string;
@ -61,12 +61,11 @@ export const AddRoleMappingModal = ({
const [clients, setClients] = useState<ClientRole[]>([]); const [clients, setClients] = useState<ClientRole[]>([]);
const [searchToggle, setSearchToggle] = useState(false); const [searchToggle, setSearchToggle] = useState(false);
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
const [selectedClients, setSelectedClients] = useState<ClientRole[]>([]); const [selectedClients, setSelectedClients] = useState<ClientRole[]>([]);
const [selectedRows, setSelectedRows] = useState<Row[]>([]); const [selectedRows, setSelectedRows] = useState<Row[]>([]);
const [data, setData] = useState<Row[]>();
const mapType = mapping.find((m) => m.resource === type)!; const mapType = mapping.find((m) => m.resource === type)!;
useFetch( useFetch(
@ -101,71 +100,77 @@ export const AddRoleMappingModal = ({
[] []
); );
useEffect(refresh, [searchToggle]); useFetch(
async () => {
const realmRolesSelected = selectedClients.some(
(client) => client.name === "realmRoles"
);
let selected = selectedClients;
if (realmRolesSelected) {
selected = selectedClients.filter(
(client) => client.name !== "realmRoles"
);
}
const availableRoles = await castAdminClient(
adminClient,
mapType.resource
)[mapType.functions.list[1]]({
id,
});
const realmRoles = availableRoles.map((role) => {
return {
id: role.id,
role,
client: undefined,
};
});
const allClients =
selectedClients.length !== 0
? selected
: await adminClient.clients.find();
const roles = (
await Promise.all(
allClients.map(async (client) => {
const clientAvailableRoles = await castAdminClient(
adminClient,
mapType.resource === "roles" ? "clients" : mapType.resource
)[mapType.functions.list[0]]({
id: mapType.resource === "roles" ? client.id : id,
client: client.id,
clientUniqueId: client.id,
});
return clientAvailableRoles.map((role) => {
return {
id: role.id,
role,
client,
};
});
})
)
).flat();
return [
...(realmRolesSelected || selected.length === 0 ? realmRoles : []),
...roles,
];
},
setData,
[selectedClients]
);
const removeClient = (client: ClientRole) => { const removeClient = (client: ClientRole) => {
setSelectedClients(selectedClients.filter((item) => item.id !== client.id)); setSelectedClients(selectedClients.filter((item) => item.id !== client.id));
}; };
const loader = async () => { if (!data) {
const realmRolesSelected = findIndex( return <KeycloakSpinner />;
selectedClients, }
(client) => client.name === "realmRoles"
);
let selected = selectedClients;
if (realmRolesSelected !== -1) {
selected = selectedClients.filter(
(client) => client.name !== "realmRoles"
);
}
const availableRoles = await castAdminClient(adminClient, mapType.resource)[
mapType.functions.list[1]
]({
id,
});
const realmRoles = availableRoles.map((role) => {
return {
id: role.id,
role,
client: undefined,
};
});
const allClients =
selectedClients.length !== 0
? selected
: await adminClient.clients.find();
const roles = (
await Promise.all(
allClients.map(async (client) => {
const clientAvailableRoles = await castAdminClient(
adminClient,
mapType.resource === "roles" ? "clients" : mapType.resource
)[mapType.functions.list[0]]({
id: mapType.resource === "roles" ? client.id : id,
client: client.id,
clientUniqueId: client.id,
});
return clientAvailableRoles.map((role) => {
return {
id: role.id,
role,
client,
};
});
})
)
).flat();
return [
...(realmRolesSelected !== -1 || selected.length === 0 ? realmRoles : []),
...roles,
];
};
const createSelectGroup = (clients: ClientRepresentation[]) => [ const createSelectGroup = (clients: ClientRepresentation[]) => [
<SelectGroup key="role" label={t("realmRoles")}> <SelectGroup key="role" label={t("realmRoles")}>
@ -215,14 +220,13 @@ export const AddRoleMappingModal = ({
]} ]}
> >
<KeycloakDataTable <KeycloakDataTable
key={key}
onSelect={(rows) => setSelectedRows([...rows])} onSelect={(rows) => setSelectedRows([...rows])}
searchPlaceholderKey="clients:searchByRoleName" searchPlaceholderKey="clients:searchByRoleName"
searchTypeComponent={ searchTypeComponent={
<ToolbarItem> <ToolbarItem>
<Select <Select
toggleId="role" toggleId="role"
onToggle={() => setSearchToggle(!searchToggle)} onToggle={setSearchToggle}
isOpen={searchToggle} isOpen={searchToggle}
variant={isRadio ? SelectVariant.single : SelectVariant.checkbox} variant={isRadio ? SelectVariant.single : SelectVariant.checkbox}
hasInlineFilter hasInlineFilter
@ -232,6 +236,7 @@ export const AddRoleMappingModal = ({
</> </>
} }
isGrouped isGrouped
isCheckboxSelectionBadgeHidden
onFilter={(evt) => { onFilter={(evt) => {
const value = evt?.target.value || ""; const value = evt?.target.value || "";
return createSelectGroup( return createSelectGroup(
@ -259,10 +264,7 @@ export const AddRoleMappingModal = ({
{selectedClients.map((client) => ( {selectedClients.map((client) => (
<Chip <Chip
key={`chip-${client.id}`} key={`chip-${client.id}`}
onClick={() => { onClick={() => removeClient(client)}
removeClient(client);
refresh();
}}
> >
{client.clientId || t("realmRoles")} {client.clientId || t("realmRoles")}
<Badge isRead={true}>{client.numberOfRoles}</Badge> <Badge isRead={true}>{client.numberOfRoles}</Badge>
@ -273,7 +275,7 @@ export const AddRoleMappingModal = ({
} }
canSelectAll canSelectAll
isRadio={isRadio} isRadio={isRadio}
loader={loader} loader={data}
ariaLabelKey="clients:roles" ariaLabelKey="clients:roles"
columns={[ columns={[
{ {

View file

@ -303,7 +303,11 @@ export function KeycloakDataTable<T>({
(data) => { (data) => {
if (!isPaginated) { if (!isPaginated) {
setUnPaginatedData(data); setUnPaginatedData(data);
data = data.slice(first, first + max + 1); if (data.length > first) {
data = data.slice(first, first + max + 1);
} else {
setFirst(0);
}
} }
const result = convertToColumns(data); const result = convertToColumns(data);