@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
167 lines • 10 kB
JavaScript
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