1
import { NetworkError } from "@keycloak/keycloak-admin-client";
2
import { PropsWithChildren, useCallback, useMemo, useState } from "react";
3
import { createNamedContext, useRequiredContext, label } from "ui-shared";
5
import { keycloak } from "../keycloak";
6
import { useFetch } from "../utils/useFetch";
7
import { fetchAdminUI } from "./auth/admin-ui-endpoint";
8
import useLocaleSort from "../utils/useLocaleSort";
9
import { useTranslation } from "react-i18next";
11
type RealmsContextProps = {
12
/** A list of all the realms. */
13
realms: RealmNameRepresentation[];
14
/** Refreshes the realms with the latest information. */
15
refresh: () => Promise<void>;
18
export interface RealmNameRepresentation {
23
export const RealmsContext = createNamedContext<RealmsContextProps | undefined>(
28
export const RealmsProvider = ({ children }: PropsWithChildren) => {
29
const [realms, setRealms] = useState<RealmNameRepresentation[]>([]);
30
const [refreshCount, setRefreshCount] = useState(0);
31
const localeSort = useLocaleSort();
32
const { t } = useTranslation();
34
function updateRealms(realms: RealmNameRepresentation[]) {
35
setRealms(localeSort(realms, (r) => label(t, r.displayName, r.name)));
41
return await fetchAdminUI<RealmNameRepresentation[]>(
42
"ui-ext/realms/names",
46
if (error instanceof NetworkError && error.response.status < 500) {
53
(realms) => updateRealms(realms),
57
const refresh = useCallback(async () => {
58
//this is needed otherwise the realm find function will not return
59
//new or renamed realms because of the cached realms in the token (perhaps?)
60
await keycloak.updateToken(Number.MAX_VALUE);
61
setRefreshCount((count) => count + 1);
64
const value = useMemo<RealmsContextProps>(
65
() => ({ realms, refresh }),
70
<RealmsContext.Provider value={value}>{children}</RealmsContext.Provider>
74
export const useRealms = () => useRequiredContext(RealmsContext);