@keycloakify/keycloak-admin-ui
Version:
Repackaged Keycloak Admin UI
90 lines • 6.2 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { NetworkError } from "@keycloak/keycloak-admin-client";
import { label, useFetch } from "../../ui-shared";
import { Button, Divider, Dropdown, DropdownGroup, DropdownItem, DropdownList, Label, MenuToggle, SearchInput, Spinner, Split, SplitItem, Stack, StackItem, } from "@patternfly/react-core";
import { AngleLeftIcon, AngleRightIcon, CheckIcon, } from "@patternfly/react-icons";
import { debounce } from "lodash-es";
import { Fragment, useCallback, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { useAdminClient } from "../../admin-client";
import { useRecentRealms } from "../../context/RecentRealms";
import { fetchAdminUI } from "../../context/auth/admin-ui-endpoint";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useWhoAmI } from "../../context/whoami/WhoAmI";
import { toDashboard } from "../../dashboard/routes/Dashboard";
import { toAddRealm } from "../../realm/routes/AddRealm";
import "./realm-selector.css";
const MAX_RESULTS = 10;
const AddRealm = ({ onClick }) => {
const { realm } = useRealm();
const { t } = useTranslation();
return (_jsx(Button, { "data-testid": "add-realm", component: (props) => _jsx(Link, { ...props, to: toAddRealm({ realm }) }), onClick: onClick, isBlock: true, children: t("createRealm") }));
};
const RealmText = ({ name, displayName, showIsRecent }) => {
const { realm } = useRealm();
const { t } = useTranslation();
return (_jsxs(Split, { children: [_jsx(SplitItem, { isFilled: true, children: _jsxs(Stack, { children: [displayName ? (_jsx(StackItem, { className: "pf-v5-u-font-weight-bold", isFilled: true, children: label(t, displayName) })) : null, _jsx(StackItem, { isFilled: true, children: name })] }) }), _jsx(SplitItem, { children: name === realm && _jsx(CheckIcon, {}) }), showIsRecent ? (_jsx(SplitItem, { children: _jsx(Label, { children: t("recent") }) })) : null] }));
};
export const RealmSelector = () => {
const { realm } = useRealm();
const { adminClient } = useAdminClient();
const { whoAmI } = useWhoAmI();
const [open, setOpen] = useState(false);
const [realms, setRealms] = useState([]);
const { t } = useTranslation();
const recentRealms = useRecentRealms();
const navigate = useNavigate();
const [search, setSearch] = useState("");
const [first, setFirst] = useState(0);
const debounceFn = useCallback(debounce((value) => {
setFirst(0);
setSearch(value);
}, 1000), []);
useFetch(async () => {
try {
return await fetchAdminUI(adminClient, "ui-ext/realms/names", { first: `${first}`, max: `${MAX_RESULTS + 1}`, search });
}
catch (error) {
if (error instanceof NetworkError && error.response.status < 500) {
return [];
}
throw error;
}
}, setRealms, [open, first, search]);
const sortedRealms = useMemo(() => [
...(first === 0 && !search
? recentRealms.reduce((acc, name) => {
const realm = realms.find((r) => r.name === name);
if (realm) {
acc.push(realm);
}
return acc;
}, [])
: []),
...realms.filter((r) => !recentRealms.includes(r.name)),
], [recentRealms, realms, first, search]);
const realmDisplayName = useMemo(() => { var _a; return (_a = realms.find((r) => r.name === realm)) === null || _a === void 0 ? void 0 : _a.displayName; }, [realm, realms]);
return (_jsx(Dropdown, { id: "realm-select", className: "keycloak__realm_selector__dropdown", isOpen: open, onOpenChange: (isOpen) => setOpen(isOpen), toggle: (ref) => (_jsx(MenuToggle, { ref: ref, "data-testid": "realmSelector", onClick: () => {
setOpen(!open);
}, isFullWidth: true, children: _jsxs(Stack, { className: "keycloak__realm_selector__dropdown", children: [realmDisplayName ? (_jsx(StackItem, { className: "pf-v5-u-font-weight-bold", isFilled: true, children: label(t, realmDisplayName) })) : null, _jsx(StackItem, { isFilled: true, children: realm })] }) })), children: _jsxs(DropdownList, { children: [(realms.length > 5 || search || first !== 0) && (_jsxs(_Fragment, { children: [_jsx(DropdownGroup, { children: _jsx(DropdownList, { children: _jsx(SearchInput, { value: search, onChange: (_, value) => debounceFn(value), onClear: () => setSearch("") }) }) }), _jsx(Divider, { component: "li" })] })), (realms.length !== 0
? [
first !== 0 ? (_jsxs(DropdownItem, { onClick: () => setFirst(first - MAX_RESULTS), children: [_jsx(AngleLeftIcon, {}), " ", t("previous")] })) : ([]),
...sortedRealms.map((realm) => (_jsx(DropdownItem, { onClick: () => {
navigate(toDashboard({ realm: realm.name }));
setOpen(false);
setSearch("");
}, children: _jsx(RealmText, { ...realm, showIsRecent: realms.length > 5 && recentRealms.includes(realm.name) }) }, realm.name))),
realms.length > MAX_RESULTS ? (_jsxs(DropdownItem, { onClick: () => setFirst(first + MAX_RESULTS), children: [_jsx(AngleRightIcon, {}), t("next")] })) : ([]),
]
: !search
? [
_jsxs(DropdownItem, { children: [_jsx(Spinner, { size: "sm" }), " ", t("loadingRealms")] }, "loader"),
]
: [
_jsx(DropdownItem, { children: t("noResultsFound") }, "no-results"),
]).concat([
_jsx(Fragment, { children: whoAmI.canCreateRealm() && (_jsxs(_Fragment, { children: [_jsx(Divider, {}, "divider"), _jsx(DropdownItem, { component: "div", children: _jsx(AddRealm, { onClick: () => setOpen(false) }) }, "add")] })) }, "add-realm"),
])] }) }));
};
//# sourceMappingURL=RealmSelector.js.map