UNPKG

@keycloakify/keycloak-admin-ui

Version:
167 lines 10 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { AlertVariant, Button, ButtonVariant, Dropdown, DropdownItem, DropdownList, MenuToggle, PageSection, ToolbarItem, } from "@patternfly/react-core"; import { EllipsisVIcon } from "@patternfly/react-icons"; import { cellWidth } from "@patternfly/react-table"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { useAdminClient } from "../admin-client"; import { getProtocolName } from "../clients/utils"; import { useAlerts } from "../ui-shared"; import { AllClientScopes, CellDropdown, ClientScope, changeScope, removeScope, } from "../components/client-scope/ClientScopeTypes"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; import { KeycloakDataTable } from "../ui-shared"; import { ViewHeader } from "../components/view-header/ViewHeader"; import { useRealm } from "../context/realm-context/RealmContext"; import helpUrls from "../help-urls"; import { emptyFormatter } from "../util"; import useLocaleSort, { mapByKey } from "../utils/useLocaleSort"; import { ChangeTypeDropdown } from "../client-scopes/ChangeTypeDropdown"; import { SearchDropdown, SearchToolbar, nameFilter, protocolFilter, typeFilter, } from "../client-scopes/details/SearchFilter"; import { toClientScope } from "../client-scopes/routes/ClientScope"; import { toNewClientScope } from "../client-scopes/routes/NewClientScope"; const TypeSelector = (scope) => { const { adminClient } = useAdminClient(); const { t } = useTranslation(); const { addAlert, addError } = useAlerts(); return (_jsx(CellDropdown, { clientScope: scope, type: scope.type, all: true, onSelect: async (value) => { try { await changeScope(adminClient, scope, value); addAlert(t("clientScopeSuccess"), AlertVariant.success); scope.refresh(); } catch (error) { addError("clientScopeError", error); } } })); }; const ClientScopeDetailLink = ({ id, name, }) => { const { realm } = useRealm(); return (_jsx(Link, { to: toClientScope({ realm, id: id, tab: "settings" }), children: name }, id)); }; export default function ClientScopesSection() { var _a; const { adminClient } = useAdminClient(); const { realm } = useRealm(); const { t } = useTranslation(); const { addAlert, addError } = useAlerts(); const [kebabOpen, setKebabOpen] = useState(false); const [selectedScopes, setSelectedScopes] = useState([]); const [searchType, setSearchType] = useState("name"); const [searchTypeType, setSearchTypeType] = useState(AllClientScopes.none); const [searchProtocol, setSearchProtocol] = useState("all"); const localeSort = useLocaleSort(); const [key, setKey] = useState(0); const refresh = () => { setSelectedScopes([]); setKey(key + 1); }; const loader = async (first, max, search) => { const defaultScopes = await adminClient.clientScopes.listDefaultClientScopes(); const optionalScopes = await adminClient.clientScopes.listDefaultOptionalClientScopes(); const clientScopes = await adminClient.clientScopes.find(); const filter = searchType === "name" ? nameFilter(search) : searchType === "type" ? typeFilter(searchTypeType) : protocolFilter(searchProtocol); const transformed = clientScopes .map((scope) => { const row = { ...scope, type: defaultScopes.find((defaultScope) => defaultScope.name === scope.name) ? ClientScope.default : optionalScopes.find((optionalScope) => optionalScope.name === scope.name) ? ClientScope.optional : AllClientScopes.none, }; return row; }) .filter(filter); return localeSort(transformed, mapByKey("name")).slice(first, Number(first) + Number(max)); }; const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ titleKey: t("deleteClientScope", { count: selectedScopes.length, name: (_a = selectedScopes[0]) === null || _a === void 0 ? void 0 : _a.name, }), messageKey: "deleteConfirmClientScopes", continueButtonLabel: "delete", continueButtonVariant: ButtonVariant.danger, onConfirm: async () => { var _a, _b; const clientScopes = await adminClient.clientScopes.find(); const clientScopeLength = Object.keys(clientScopes).length; if (clientScopeLength - selectedScopes.length > 0) { try { for (const scope of selectedScopes) { try { await removeScope(adminClient, scope); } catch (error) { console.warn("could not remove scope", ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errorMessage) || error); } await adminClient.clientScopes.del({ id: scope.id }); } addAlert(t("deletedSuccessClientScope"), AlertVariant.success); refresh(); } catch (error) { addError("deleteErrorClientScope", error); } } else { addAlert(t("notAllowedToDeleteAllClientScopes"), AlertVariant.danger); } }, }); return (_jsxs(_Fragment, { children: [_jsx(DeleteConfirm, {}), _jsx(ViewHeader, { titleKey: "clientScopes", subKey: "clientScopeExplain", helpUrl: helpUrls.clientScopesUrl }), _jsx(PageSection, { variant: "light", className: "pf-v5-u-p-0", children: _jsx(KeycloakDataTable, { loader: loader, ariaLabelKey: "clientScopeList", searchPlaceholderKey: searchType === "name" ? "searchForClientScope" : undefined, isSearching: searchType !== "name", searchTypeComponent: _jsx(SearchDropdown, { searchType: searchType, onSelect: (searchType) => setSearchType(searchType), withProtocol: true }), isPaginated: true, onSelect: (clientScopes) => setSelectedScopes([...clientScopes]), canSelectAll: true, toolbarItem: _jsxs(_Fragment, { children: [_jsx(SearchToolbar, { searchType: searchType, type: searchTypeType, onSelect: (searchType) => { setSearchType(searchType); setSearchProtocol("all"); setSearchTypeType(AllClientScopes.none); refresh(); }, onType: (value) => { setSearchTypeType(value); setSearchProtocol("all"); refresh(); }, protocol: searchProtocol, onProtocol: (protocol) => { setSearchProtocol(protocol); setSearchTypeType(AllClientScopes.none); refresh(); } }), _jsx(ToolbarItem, { children: _jsx(Button, { component: (props) => (_jsx(Link, { ...props, to: toNewClientScope({ realm }) })), children: t("createClientScope") }) }), _jsx(ToolbarItem, { children: _jsx(ChangeTypeDropdown, { selectedRows: selectedScopes, refresh: refresh }) }), _jsx(ToolbarItem, { children: _jsx(Dropdown, { shouldFocusToggleOnSelect: true, onOpenChange: (isOpen) => setKebabOpen(isOpen), toggle: (ref) => (_jsx(MenuToggle, { "data-testid": "kebab", "aria-label": "Kebab toggle", ref: ref, onClick: () => setKebabOpen(!kebabOpen), variant: "plain", children: _jsx(EllipsisVIcon, {}) })), isOpen: kebabOpen, children: _jsx(DropdownList, { children: _jsx(DropdownItem, { "data-testid": "delete", isDisabled: selectedScopes.length === 0, onClick: () => { toggleDeleteDialog(); setKebabOpen(false); }, children: t("delete") }) }) }) })] }), actions: [ { title: t("delete"), onRowClick: (clientScope) => { setSelectedScopes([clientScope]); toggleDeleteDialog(); }, }, ], columns: [ { name: "name", cellRenderer: ClientScopeDetailLink, }, { name: "type", displayKey: "assignedType", cellRenderer: (row) => (_jsx(TypeSelector, { ...row, refresh: refresh })), }, { name: "protocol", displayKey: "protocol", cellRenderer: (client) => { var _a; return getProtocolName(t, (_a = client.protocol) !== null && _a !== void 0 ? _a : "openid-connect"); }, transforms: [cellWidth(15)], }, { name: "attributes['gui.order']", displayKey: "displayOrder", cellFormatters: [emptyFormatter()], transforms: [cellWidth(15)], }, { name: "description", cellFormatters: [emptyFormatter()] }, ] }, key) })] })); } //# sourceMappingURL=ClientScopesSection.js.map