import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation"; import type ResourceServerRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceServerRepresentation"; import { Alert, AlertVariant, Button, PageSection, ToolbarItem, } from "@patternfly/react-core"; import { ExpandableRowContent, TableComposable, Tbody, Td, Th, Thead, Tr, } from "@patternfly/react-table"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Link, useNavigate } from "react-router-dom"; import { adminClient } from "../../admin-client"; import { useAlerts } from "../../components/alert/Alerts"; import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog"; import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner"; import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState"; import { PaginatingTableToolbar } from "../../components/table-toolbar/PaginatingTableToolbar"; import { useRealm } from "../../context/realm-context/RealmContext"; import { useFetch } from "../../utils/useFetch"; import { toNewPermission } from "../routes/NewPermission"; import { toCreateResource } from "../routes/NewResource"; import { toResourceDetails } from "../routes/Resource"; import { DetailCell } from "./DetailCell"; import { MoreLabel } from "./MoreLabel"; import { SearchDropdown, SearchForm } from "./SearchDropdown"; type ResourcesProps = { clientId: string; }; type ExpandableResourceRepresentation = ResourceRepresentation & { isExpanded: boolean; }; const UriRenderer = ({ row }: { row: ResourceRepresentation }) => ( <> {row.uris?.[0]} > ); export const AuthorizationResources = ({ clientId }: ResourcesProps) => { const { t } = useTranslation(); const navigate = useNavigate(); const { addAlert, addError } = useAlerts(); const { realm } = useRealm(); const [resources, setResources] = useState(); const [selectedResource, setSelectedResource] = useState(); const [permissions, setPermission] = useState(); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); const [max, setMax] = useState(10); const [first, setFirst] = useState(0); const [search, setSearch] = useState({}); useFetch( () => { const params = { first, max: max + 1, deep: false, ...search, }; return adminClient.clients.listResources({ ...params, id: clientId, }); }, (resources) => setResources( resources.map((resource) => ({ ...resource, isExpanded: false })), ), [key, search, first, max], ); const fetchPermissions = async (id: string) => { return adminClient.clients.listPermissionsByResource({ id: clientId, resourceId: id, }); }; const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: "deleteResource", children: ( <> {t("deleteResourceConfirm")} {permissions?.length && ( {permissions.map((permission) => ( {permission.name} ))} )} > ), continueButtonLabel: "confirm", onConfirm: async () => { try { await adminClient.clients.delResource({ id: clientId, resourceId: selectedResource?._id!, }); addAlert(t("resourceDeletedSuccess"), AlertVariant.success); refresh(); } catch (error) { addError("resourceDeletedError", error); } }, }); if (!resources) { return ; } const noData = resources.length === 0; const searching = Object.keys(search).length !== 0; return ( {(!noData || searching) && ( { setFirst(first); setMax(max); }} toolbarItem={ <> ( )} > {t("createResource")} > } > {!noData && ( {t("common:name")} {t("displayName")} {t("common:type")} {t("owner")} {t("uris")} {resources.map((resource, rowIndex) => ( { const rows = resources.map((resource, index) => index === rowIndex ? { ...resource, isExpanded: !resource.isExpanded, } : resource, ); setResources(rows); }, }} /> {resource.name} {resource.displayName} {resource.type} {resource.owner?.name} ( )} > {t("createPermission")} { setSelectedResource(resource); setPermission( await fetchPermissions(resource._id!), ); toggleDeleteDialog(); }, }, ], }} /> {resource.isExpanded && ( )} ))} )} )} {noData && searching && ( )} {noData && !searching && ( navigate(toCreateResource({ realm, id: clientId })) } /> )} ); };
{permissions.map((permission) => ( {permission.name} ))}