Add display names to contexts (#3032)
This commit is contained in:
parent
a6fd2cabfa
commit
e363fb68b0
13 changed files with 75 additions and 45 deletions
|
@ -21,7 +21,7 @@ import { SubGroups } from "./groups/SubGroupsContext";
|
|||
import { RealmsProvider } from "./context/RealmsContext";
|
||||
import { RealmContextProvider } from "./context/realm-context/RealmContext";
|
||||
import { ErrorRenderer } from "./components/error/ErrorRenderer";
|
||||
import { AdminClient } from "./context/auth/AdminClient";
|
||||
import { AdminClientContext } from "./context/auth/AdminClient";
|
||||
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
|
||||
|
||||
export const mainPageContentId = "kc-main-content-page-container";
|
||||
|
@ -37,7 +37,7 @@ const AppContexts: FunctionComponent<AdminClientProps> = ({
|
|||
adminClient,
|
||||
}) => (
|
||||
<Router>
|
||||
<AdminClient.Provider value={{ keycloak, adminClient }}>
|
||||
<AdminClientContext.Provider value={{ keycloak, adminClient }}>
|
||||
<WhoAmIContextProvider>
|
||||
<RealmsProvider>
|
||||
<RealmContextProvider>
|
||||
|
@ -51,7 +51,7 @@ const AppContexts: FunctionComponent<AdminClientProps> = ({
|
|||
</RealmContextProvider>
|
||||
</RealmsProvider>
|
||||
</WhoAmIContextProvider>
|
||||
</AdminClient.Provider>
|
||||
</AdminClientContext.Provider>
|
||||
</Router>
|
||||
);
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { createContext, FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { AlertVariant } from "@patternfly/react-core";
|
||||
import axios from "axios";
|
||||
import type { AxiosError } from "axios";
|
||||
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
import { AlertPanel } from "./AlertPanel";
|
||||
|
||||
|
@ -20,7 +21,10 @@ type AlertProps = {
|
|||
addError: AddErrorFunction;
|
||||
};
|
||||
|
||||
export const AlertContext = createContext<AlertProps | undefined>(undefined);
|
||||
export const AlertContext = createNamedContext<AlertProps | undefined>(
|
||||
"AlertContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
export const useAlerts = () => useRequiredContext(AlertContext);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { FunctionComponent } from "react";
|
|||
import { HashRouter } from "react-router-dom";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { AccessContextProvider } from "../../context/access/Access";
|
||||
import { AdminClient } from "../../context/auth/AdminClient";
|
||||
import { AdminClientContext } from "../../context/auth/AdminClient";
|
||||
import { RealmContext } from "../../context/realm-context/RealmContext";
|
||||
import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider";
|
||||
import serverInfo from "../../context/server-info/__tests__/mock.json";
|
||||
|
@ -31,13 +31,13 @@ const MockAdminClient: FunctionComponent = ({ children }) => {
|
|||
<ServerInfoContext.Provider
|
||||
value={serverInfo as unknown as ServerInfoRepresentation}
|
||||
>
|
||||
<AdminClient.Provider value={{ keycloak, adminClient }}>
|
||||
<AdminClientContext.Provider value={{ keycloak, adminClient }}>
|
||||
<WhoAmIContextProvider>
|
||||
<RealmContext.Provider value={{ realm: "master" }}>
|
||||
<AccessContextProvider>{children}</AccessContextProvider>
|
||||
</RealmContext.Provider>
|
||||
</WhoAmIContextProvider>
|
||||
</AdminClient.Provider>
|
||||
</AdminClientContext.Provider>
|
||||
</ServerInfoContext.Provider>
|
||||
</HashRouter>
|
||||
);
|
||||
|
|
|
@ -9,8 +9,10 @@ import {
|
|||
TextContent,
|
||||
} from "@patternfly/react-core";
|
||||
import { ExternalLinkAltIcon, HelpIcon } from "@patternfly/react-icons";
|
||||
import { createContext, FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
import helpUrls from "../../help-urls";
|
||||
|
||||
|
@ -21,7 +23,8 @@ type HelpContextProps = {
|
|||
toggleHelp: () => void;
|
||||
};
|
||||
|
||||
export const HelpContext = createContext<HelpContextProps | undefined>(
|
||||
export const HelpContext = createNamedContext<HelpContextProps | undefined>(
|
||||
"HelpContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||
import { sortBy } from "lodash-es";
|
||||
import {
|
||||
createContext,
|
||||
FunctionComponent,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import { FunctionComponent, useCallback, useMemo, useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
import { RecentUsed } from "../components/realm-selector/recent-used";
|
||||
import { createNamedContext } from "../utils/createNamedContext";
|
||||
import useRequiredContext from "../utils/useRequiredContext";
|
||||
import { useAdminClient, useFetch } from "./auth/AdminClient";
|
||||
|
||||
|
@ -20,7 +15,8 @@ type RealmsContextProps = {
|
|||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
export const RealmsContext = createContext<RealmsContextProps | undefined>(
|
||||
export const RealmsContext = createNamedContext<RealmsContextProps | undefined>(
|
||||
"RealmsContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import type { AccessType } from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
||||
import { createContext, FunctionComponent, useEffect, useState } from "react";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useWhoAmI } from "../../context/whoami/WhoAmI";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
|
||||
type AccessContextProps = {
|
||||
|
@ -9,7 +10,8 @@ type AccessContextProps = {
|
|||
hasSomeAccess: (...types: AccessType[]) => boolean;
|
||||
};
|
||||
|
||||
export const AccessContext = createContext<AccessContextProps | undefined>(
|
||||
export const AccessContext = createNamedContext<AccessContextProps | undefined>(
|
||||
"AccessContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import axios from "axios";
|
||||
import Keycloak from "keycloak-js";
|
||||
import { createContext, DependencyList, useEffect } from "react";
|
||||
import { DependencyList, useEffect } from "react";
|
||||
import { useErrorHandler } from "react-error-boundary";
|
||||
|
||||
import environment from "../../environment";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
|
||||
export type AdminClientProps = {
|
||||
|
@ -12,11 +13,11 @@ export type AdminClientProps = {
|
|||
adminClient: KeycloakAdminClient;
|
||||
};
|
||||
|
||||
export const AdminClient = createContext<AdminClientProps | undefined>(
|
||||
undefined
|
||||
);
|
||||
export const AdminClientContext = createNamedContext<
|
||||
AdminClientProps | undefined
|
||||
>("AdminClientContext", undefined);
|
||||
|
||||
export const useAdminClient = () => useRequiredContext(AdminClient);
|
||||
export const useAdminClient = () => useRequiredContext(AdminClientContext);
|
||||
|
||||
/**
|
||||
* Util function to only set the state when the component is still mounted.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { createContext, FunctionComponent, useEffect, useMemo } from "react";
|
||||
import { FunctionComponent, useEffect, useMemo } from "react";
|
||||
import { useRouteMatch } from "react-router-dom";
|
||||
import { RecentUsed } from "../../components/realm-selector/recent-used";
|
||||
import {
|
||||
|
@ -6,6 +6,7 @@ import {
|
|||
DashboardRoute,
|
||||
} from "../../dashboard/routes/Dashboard";
|
||||
import environment from "../../environment";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
import { useAdminClient } from "../auth/AdminClient";
|
||||
|
||||
|
@ -13,7 +14,8 @@ type RealmContextType = {
|
|||
realm: string;
|
||||
};
|
||||
|
||||
export const RealmContext = createContext<RealmContextType | undefined>(
|
||||
export const RealmContext = createNamedContext<RealmContextType | undefined>(
|
||||
"RealmContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { createContext, FunctionComponent, useState } from "react";
|
||||
|
||||
import { FunctionComponent, useState } from "react";
|
||||
import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
|
||||
|
||||
import { sortProviders } from "../../util";
|
||||
import { useAdminClient, useFetch } from "../auth/AdminClient";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
|
||||
export const ServerInfoContext = createContext<
|
||||
export const ServerInfoContext = createNamedContext<
|
||||
ServerInfoRepresentation | undefined
|
||||
>(undefined);
|
||||
>("ServerInfoContext", undefined);
|
||||
|
||||
export const useServerInfo = () => useRequiredContext(ServerInfoContext);
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
||||
import type { AccessType } from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
|
||||
import { createContext, FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
|
||||
import environment from "../../environment";
|
||||
import i18n, { DEFAULT_LOCALE } from "../../i18n";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
import { useAdminClient, useFetch } from "../auth/AdminClient";
|
||||
|
||||
|
@ -53,7 +55,10 @@ type WhoAmIProps = {
|
|||
whoAmI: WhoAmI;
|
||||
};
|
||||
|
||||
export const WhoAmIContext = createContext<WhoAmIProps | undefined>(undefined);
|
||||
export const WhoAmIContext = createNamedContext<WhoAmIProps | undefined>(
|
||||
"WhoAmIContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
export const useWhoAmI = () => useRequiredContext(WhoAmIContext);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
|
||||
import { createContext, FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
import { createNamedContext } from "../utils/createNamedContext";
|
||||
import useRequiredContext from "../utils/useRequiredContext";
|
||||
|
||||
type SubGroupsProps = {
|
||||
|
@ -10,7 +11,10 @@ type SubGroupsProps = {
|
|||
currentGroup: () => GroupRepresentation | undefined;
|
||||
};
|
||||
|
||||
const SubGroupContext = createContext<SubGroupsProps | undefined>(undefined);
|
||||
const SubGroupsContext = createNamedContext<SubGroupsProps | undefined>(
|
||||
"SubGroupsContext",
|
||||
undefined
|
||||
);
|
||||
|
||||
export const SubGroups: FunctionComponent = ({ children }) => {
|
||||
const [subGroups, setSubGroups] = useState<GroupRepresentation[]>([]);
|
||||
|
@ -22,12 +26,12 @@ export const SubGroups: FunctionComponent = ({ children }) => {
|
|||
);
|
||||
const currentGroup = () => subGroups[subGroups.length - 1];
|
||||
return (
|
||||
<SubGroupContext.Provider
|
||||
<SubGroupsContext.Provider
|
||||
value={{ subGroups, setSubGroups, clear, remove, currentGroup }}
|
||||
>
|
||||
{children}
|
||||
</SubGroupContext.Provider>
|
||||
</SubGroupsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useSubGroups = () => useRequiredContext(SubGroupContext);
|
||||
export const useSubGroups = () => useRequiredContext(SubGroupsContext);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import type UserProfileConfig from "@keycloak/keycloak-admin-client/lib/defs/userProfileConfig";
|
||||
import { AlertVariant } from "@patternfly/react-core";
|
||||
import { createContext, FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { createNamedContext } from "../../utils/createNamedContext";
|
||||
import useRequiredContext from "../../utils/useRequiredContext";
|
||||
|
||||
type UserProfileProps = {
|
||||
|
@ -23,9 +24,9 @@ export type SaveOptions = {
|
|||
errorMessageKey?: string;
|
||||
};
|
||||
|
||||
export const UserProfile = createContext<UserProfileProps | undefined>(
|
||||
undefined
|
||||
);
|
||||
export const UserProfileContext = createNamedContext<
|
||||
UserProfileProps | undefined
|
||||
>("UserProfileContext", undefined);
|
||||
|
||||
export const UserProfileProvider: FunctionComponent = ({ children }) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
@ -71,10 +72,10 @@ export const UserProfileProvider: FunctionComponent = ({ children }) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<UserProfile.Provider value={{ config, save, isSaving }}>
|
||||
<UserProfileContext.Provider value={{ config, save, isSaving }}>
|
||||
{children}
|
||||
</UserProfile.Provider>
|
||||
</UserProfileContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useUserProfile = () => useRequiredContext(UserProfile);
|
||||
export const useUserProfile = () => useRequiredContext(UserProfileContext);
|
||||
|
|
11
src/utils/createNamedContext.ts
Normal file
11
src/utils/createNamedContext.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import type { Context } from "react";
|
||||
import { createContext } from "react";
|
||||
|
||||
export type NamedContext<T> = Context<T> &
|
||||
Required<Pick<Context<T>, "displayName">>;
|
||||
|
||||
export function createNamedContext<T>(displayName: string, defaultValue: T) {
|
||||
const context = createContext(defaultValue);
|
||||
context.displayName = displayName;
|
||||
return context as NamedContext<T>;
|
||||
}
|
Loading…
Reference in a new issue