keycloak-scim/apps/admin-ui/src/context/RecentRealms.tsx

56 lines
1.7 KiB
TypeScript

import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
import { PropsWithChildren, useEffect, useMemo } from "react";
import { createNamedContext } from "../utils/createNamedContext";
import useRequiredContext from "../utils/useRequiredContext";
import { useStoredState } from "../utils/useStoredState";
import { useRealm } from "./realm-context/RealmContext";
import { useRealms } from "./RealmsContext";
const MAX_REALMS = 4;
export const RecentRealmsContext = createNamedContext<string[] | undefined>(
"RecentRealmsContext",
undefined
);
export const RecentRealmsProvider = ({
children,
}: PropsWithChildren<unknown>) => {
const { realms } = useRealms();
const { realm } = useRealm();
const [storedRealms, setStoredRealms] = useStoredState(
localStorage,
"recentRealms",
[realm]
);
const recentRealms = useMemo(
() => filterRealmNames(realms, storedRealms),
[realms, storedRealms]
);
useEffect(() => {
const newRealms = [...new Set([realm, ...recentRealms])];
setStoredRealms(newRealms.slice(0, MAX_REALMS));
}, [realm]);
return (
<RecentRealmsContext.Provider value={recentRealms}>
{children}
</RecentRealmsContext.Provider>
);
};
export const useRecentRealms = () => useRequiredContext(RecentRealmsContext);
function filterRealmNames(realms: RealmRepresentation[], realmNames: string[]) {
// If no realms have been set yet we can't filter out any non-existent realm names.
if (realms.length === 0) {
return realmNames;
}
// Only keep realm names that actually still exist.
const exisingRealmNames = realms.map(({ realm }) => realm!);
return realmNames.filter((realm) => exisingRealmNames.includes(realm));
}