From e363fb68b01bc2e58497c2a1be4d76b317a8b39a Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Wed, 3 Aug 2022 15:15:04 +0200 Subject: [PATCH] Add display names to contexts (#3032) --- src/App.tsx | 6 +++--- src/components/alert/Alerts.tsx | 8 ++++++-- src/components/data-loader/DataLoader.test.tsx | 6 +++--- src/components/help-enabler/HelpHeader.tsx | 7 +++++-- src/context/RealmsContext.tsx | 12 ++++-------- src/context/access/Access.tsx | 6 ++++-- src/context/auth/AdminClient.tsx | 11 ++++++----- src/context/realm-context/RealmContext.tsx | 6 ++++-- src/context/server-info/ServerInfoProvider.tsx | 9 +++++---- src/context/whoami/WhoAmI.tsx | 9 +++++++-- src/groups/SubGroupsContext.tsx | 14 +++++++++----- .../user-profile/UserProfileContext.tsx | 15 ++++++++------- src/utils/createNamedContext.ts | 11 +++++++++++ 13 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 src/utils/createNamedContext.ts diff --git a/src/App.tsx b/src/App.tsx index 79082810f7..c2c9906af4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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 = ({ adminClient, }) => ( - + @@ -51,7 +51,7 @@ const AppContexts: FunctionComponent = ({ - + ); diff --git a/src/components/alert/Alerts.tsx b/src/components/alert/Alerts.tsx index 42cbf4243f..1588e7aa6f 100644 --- a/src/components/alert/Alerts.tsx +++ b/src/components/alert/Alerts.tsx @@ -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(undefined); +export const AlertContext = createNamedContext( + "AlertContext", + undefined +); export const useAlerts = () => useRequiredContext(AlertContext); diff --git a/src/components/data-loader/DataLoader.test.tsx b/src/components/data-loader/DataLoader.test.tsx index 00d4c71ed8..2de548a44e 100644 --- a/src/components/data-loader/DataLoader.test.tsx +++ b/src/components/data-loader/DataLoader.test.tsx @@ -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 }) => { - + {children} - + ); diff --git a/src/components/help-enabler/HelpHeader.tsx b/src/components/help-enabler/HelpHeader.tsx index 2c1cb1fecd..09e4e075ba 100644 --- a/src/components/help-enabler/HelpHeader.tsx +++ b/src/components/help-enabler/HelpHeader.tsx @@ -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( +export const HelpContext = createNamedContext( + "HelpContext", undefined ); diff --git a/src/context/RealmsContext.tsx b/src/context/RealmsContext.tsx index a61a09eeee..cffb6db384 100644 --- a/src/context/RealmsContext.tsx +++ b/src/context/RealmsContext.tsx @@ -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; }; -export const RealmsContext = createContext( +export const RealmsContext = createNamedContext( + "RealmsContext", undefined ); diff --git a/src/context/access/Access.tsx b/src/context/access/Access.tsx index 39922b465e..4ce7267926 100644 --- a/src/context/access/Access.tsx +++ b/src/context/access/Access.tsx @@ -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( +export const AccessContext = createNamedContext( + "AccessContext", undefined ); diff --git a/src/context/auth/AdminClient.tsx b/src/context/auth/AdminClient.tsx index 7509a70c1a..a600f6e898 100644 --- a/src/context/auth/AdminClient.tsx +++ b/src/context/auth/AdminClient.tsx @@ -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( - 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. diff --git a/src/context/realm-context/RealmContext.tsx b/src/context/realm-context/RealmContext.tsx index c6943ac67f..90d91f6e2a 100644 --- a/src/context/realm-context/RealmContext.tsx +++ b/src/context/realm-context/RealmContext.tsx @@ -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( +export const RealmContext = createNamedContext( + "RealmContext", undefined ); diff --git a/src/context/server-info/ServerInfoProvider.tsx b/src/context/server-info/ServerInfoProvider.tsx index 994eeebb8a..1dae192d4a 100644 --- a/src/context/server-info/ServerInfoProvider.tsx +++ b/src/context/server-info/ServerInfoProvider.tsx @@ -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); diff --git a/src/context/whoami/WhoAmI.tsx b/src/context/whoami/WhoAmI.tsx index e86c1c7674..bc0cfc78d7 100644 --- a/src/context/whoami/WhoAmI.tsx +++ b/src/context/whoami/WhoAmI.tsx @@ -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(undefined); +export const WhoAmIContext = createNamedContext( + "WhoAmIContext", + undefined +); export const useWhoAmI = () => useRequiredContext(WhoAmIContext); diff --git a/src/groups/SubGroupsContext.tsx b/src/groups/SubGroupsContext.tsx index 4b45a8845d..ee0d166af6 100644 --- a/src/groups/SubGroupsContext.tsx +++ b/src/groups/SubGroupsContext.tsx @@ -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(undefined); +const SubGroupsContext = createNamedContext( + "SubGroupsContext", + undefined +); export const SubGroups: FunctionComponent = ({ children }) => { const [subGroups, setSubGroups] = useState([]); @@ -22,12 +26,12 @@ export const SubGroups: FunctionComponent = ({ children }) => { ); const currentGroup = () => subGroups[subGroups.length - 1]; return ( - {children} - + ); }; -export const useSubGroups = () => useRequiredContext(SubGroupContext); +export const useSubGroups = () => useRequiredContext(SubGroupsContext); diff --git a/src/realm-settings/user-profile/UserProfileContext.tsx b/src/realm-settings/user-profile/UserProfileContext.tsx index 0c7a0f8b05..6de82b1160 100644 --- a/src/realm-settings/user-profile/UserProfileContext.tsx +++ b/src/realm-settings/user-profile/UserProfileContext.tsx @@ -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( - 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 ( - + {children} - + ); }; -export const useUserProfile = () => useRequiredContext(UserProfile); +export const useUserProfile = () => useRequiredContext(UserProfileContext); diff --git a/src/utils/createNamedContext.ts b/src/utils/createNamedContext.ts new file mode 100644 index 0000000000..4fb436555f --- /dev/null +++ b/src/utils/createNamedContext.ts @@ -0,0 +1,11 @@ +import type { Context } from "react"; +import { createContext } from "react"; + +export type NamedContext = Context & + Required, "displayName">>; + +export function createNamedContext(displayName: string, defaultValue: T) { + const context = createContext(defaultValue); + context.displayName = displayName; + return context as NamedContext; +}