From a0faba0f977aab1f8e3ccb790df291d159ed1610 Mon Sep 17 00:00:00 2001 From: Eugenia <32821331+jenny-s51@users.noreply.github.com> Date: Thu, 1 Apr 2021 09:41:21 -0400 Subject: [PATCH] Fix roles pagination+filter out duplicates from associated roles list (#460) * realm roles UX review progress wip * filter realm roles on Enter key press, add filter functionality * clean up * filterChips logic now in table toolbar * fix lint and format * save with erik * remove filter chips functionality * fix check-types * fix realm roles cypress test * format * wip pagination * rebase * fix roles pagination * format * add back save * remove duplicates in associated roles table, can now paginate modal * remove logs * PR feedback from Erik * rebase and fix pagination/search * remove slice * pagination in modal and associated roles tab * show client roles * lint and format * remove unused variable * address tbody console warning, clean up log stmts * clean up log stmts * fix ts error in AliasRenderer * fix lint * lint * PR feedback from Erik * resolve conflicts and format * comment --- .../attribute-form/AttributeForm.tsx | 26 ++++++++++------- .../table-toolbar/KeycloakDataTable.tsx | 7 +---- src/realm-roles/AliasRendererComponent.tsx | 8 +++-- src/realm-roles/AssociatedRolesModal.tsx | 12 ++++++-- src/realm-roles/AssociatedRolesTab.tsx | 29 +++++++++++-------- src/realm-roles/RealmRoleTabs.tsx | 2 +- src/user/UserForm.tsx | 1 - 7 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/components/attribute-form/AttributeForm.tsx b/src/components/attribute-form/AttributeForm.tsx index 1c55ffa0d6..06a71f1481 100644 --- a/src/components/attribute-form/AttributeForm.tsx +++ b/src/components/attribute-form/AttributeForm.tsx @@ -159,17 +159,21 @@ export const AttributesForm = ({ )} ))} - + + + + + diff --git a/src/components/table-toolbar/KeycloakDataTable.tsx b/src/components/table-toolbar/KeycloakDataTable.tsx index 7cb31d97b3..a3e7e3735b 100644 --- a/src/components/table-toolbar/KeycloakDataTable.tsx +++ b/src/components/table-toolbar/KeycloakDataTable.tsx @@ -16,7 +16,6 @@ import { Spinner } from "@patternfly/react-core"; import _ from "lodash"; import { PaginatingTableToolbar } from "./PaginatingTableToolbar"; -import { TableToolbar } from "./TableToolbar"; import { asyncStateFetch } from "../../context/auth/AdminClient"; import { ListEmptyState } from "../list-empty-state/ListEmptyState"; @@ -56,11 +55,7 @@ function DataTable({ } canSelectAll={canSelectAll} cells={columns.map((column) => { - return { - ...column, - title: t(column.displayKey || column.name), - transforms: column.transforms, - }; + return { ...column, title: t(column.displayKey || column.name) }; })} rows={rows} actions={actions} diff --git a/src/realm-roles/AliasRendererComponent.tsx b/src/realm-roles/AliasRendererComponent.tsx index 105b238796..3ca8e393c2 100644 --- a/src/realm-roles/AliasRendererComponent.tsx +++ b/src/realm-roles/AliasRendererComponent.tsx @@ -20,9 +20,11 @@ export const AliasRendererComponent = ({ const [containerName, setContainerName] = useState(""); useEffect(() => { - adminClient.clients - .findOne({ id: containerId! }) - .then((client) => setContainerName(client.clientId! as string)); + if (filterType === "clients") { + adminClient.clients + .findOne({ id: containerId! }) + .then((client) => setContainerName(client.clientId! as string)); + } }, [containerId]); if (filterType === "roles" || !containerName) { diff --git a/src/realm-roles/AssociatedRolesModal.tsx b/src/realm-roles/AssociatedRolesModal.tsx index 95ad00800c..e4e1a699bc 100644 --- a/src/realm-roles/AssociatedRolesModal.tsx +++ b/src/realm-roles/AssociatedRolesModal.tsx @@ -44,14 +44,20 @@ export const AssociatedRolesModal = (props: AssociatedRolesModalProps) => { }; const loader = async () => { - const allRoles = await adminClient.roles.find(); + const roles = await adminClient.roles.find(); const existingAdditionalRoles = await adminClient.roles.getCompositeRoles({ id, }); + const allRoles = [...roles, ...existingAdditionalRoles]; - return alphabetize(allRoles).filter((role: RoleRepresentation) => { + const filterDupes = allRoles.filter( + (thing, index, self) => + index === self.findIndex((t) => t.name === thing.name) + ); + + return alphabetize(filterDupes).filter((role: RoleRepresentation) => { return ( - existingAdditionalRoles.find( + props.existingCompositeRoles.find( (existing: RoleRepresentation) => existing.name === role.name ) === undefined && role.name !== name ); diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index 6fdaec8454..b431a29f39 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -22,7 +22,6 @@ import { RoleFormType } from "./RealmRoleTabs"; import ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation"; import { AliasRendererComponent } from "./AliasRendererComponent"; import _ from "lodash"; -import { cellWidth } from "@patternfly/react-table"; type AssociatedRolesTabProps = { additionalRoles: RoleRepresentation[]; @@ -47,6 +46,7 @@ export const AssociatedRolesTab = ({ const [selectedRows, setSelectedRows] = useState([]); const [isInheritedHidden, setIsInheritedHidden] = useState(false); + const [allRoles, setAllRoles] = useState([]); const [open, setOpen] = useState(false); @@ -85,12 +85,12 @@ export const AssociatedRolesTab = ({ return newRoles; }; - const alphabetize = (rolesList: RoleRepresentation[]) => { - return _.sortBy(rolesList, (role) => role.name?.toUpperCase()); - }; - const loader = async () => { + const alphabetize = (rolesList: RoleRepresentation[]) => { + return _.sortBy(rolesList, (role) => role.name?.toUpperCase()); + }; if (isInheritedHidden) { + setAllRoles(additionalRoles); return alphabetize(additionalRoles); } @@ -106,7 +106,13 @@ export const AssociatedRolesTab = ({ ); return fetchedRoles.then((results: RoleRepresentation[]) => { - return alphabetize(results); + const filterDupes = results.filter( + (thing, index, self) => + index === self.findIndex((t) => t.name === thing.name) + ); + setAllRoles(filterDupes); + + return alphabetize(filterDupes); }); }; @@ -136,11 +142,12 @@ export const AssociatedRolesTab = ({ const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: "roles:roleRemoveAssociatedRoleConfirm", messageKey: t("roles:roleRemoveAssociatedText"), - continueButtonLabel: t("common:remove"), + continueButtonLabel: "common:delete", continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { try { await adminClient.roles.delCompositeRoles({ id }, selectedRows); + onRemove(selectedRows); setSelectedRows([]); addAlert(t("associatedRolesRemoved"), AlertVariant.success); @@ -158,11 +165,11 @@ export const AssociatedRolesTab = ({ messageKey: t("roles:removeAllAssociatedRolesConfirmDialog", { name: parentRole?.name || t("createRole"), }), - continueButtonLabel: "common:remove", + continueButtonLabel: "common:delete", continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { try { - if (selectedRows.length === additionalRoles.length) { + if (selectedRows.length === allRoles.length) { onRemove(selectedRows); const loc = url.replace(/\/AssociatedRoles/g, "/details"); history.push(loc); @@ -170,6 +177,7 @@ export const AssociatedRolesTab = ({ onRemove(selectedRows); await adminClient.roles.delCompositeRoles({ id }, selectedRows); addAlert(t("associatedRolesRemoved"), AlertVariant.success); + refresh(); } catch (error) { addAlert(`${t("roleDeleteError")} ${error}`, AlertVariant.danger); } @@ -246,20 +254,17 @@ export const AssociatedRolesTab = ({ displayKey: "roles:roleName", cellRenderer: AliasRenderer, cellFormatters: [formattedLinkTableCell(), emptyFormatter()], - transforms: [cellWidth(40)], }, { name: "containerId", displayKey: "roles:inheritedFrom", cellRenderer: InheritedRoleName, cellFormatters: [emptyFormatter()], - transforms: [cellWidth(30)], }, { name: "description", displayKey: "common:description", cellFormatters: [emptyFormatter()], - transforms: [cellWidth(30)], }, ]} emptyState={ diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index 075817c2af..5d1a7b8dd0 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -57,6 +57,7 @@ export const RealmRoleTabs = () => { const [additionalRoles, setAdditionalRoles] = useState( [] ); + const { addAlert } = useAlerts(); const [open, setOpen] = useState(false); @@ -321,7 +322,6 @@ export const RealmRoleTabs = () => { addComposites={addComposites} parentRole={role!} onRemove={() => refresh()} - // client={client!} /> ) : null} diff --git a/src/user/UserForm.tsx b/src/user/UserForm.tsx index 8eebabceea..bb8e4e2f4a 100644 --- a/src/user/UserForm.tsx +++ b/src/user/UserForm.tsx @@ -61,7 +61,6 @@ export const UserForm = ({ const setupForm = (user: UserRepresentation) => { reset(); Object.entries(user).map((entry) => { - console.log(entry[0], entry[1]); if (entry[0] == "createdTimestamp") { setTimestamp(entry[1]); } else {