Fix realm intialization (#990)

This commit is contained in:
Jon Koops 2021-08-11 13:23:59 +02:00 committed by GitHub
parent 15a87b7d2e
commit a6d38096b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 92 deletions

View file

@ -1,11 +1,6 @@
import React, { FunctionComponent, useEffect } from "react";
import React, { FunctionComponent } from "react";
import { Page } from "@patternfly/react-core";
import {
HashRouter as Router,
Route,
Switch,
useParams,
} from "react-router-dom";
import { HashRouter as Router, Route, Switch } from "react-router-dom";
import { ErrorBoundary } from "react-error-boundary";
import { Header } from "./PageHeader";
@ -20,34 +15,41 @@ import { routes, RouteDef } from "./route-config";
import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs";
import { ForbiddenSection } from "./ForbiddenSection";
import { SubGroups } from "./groups/SubGroupsContext";
import { useRealm } from "./context/realm-context/RealmContext";
import { RealmContextProvider } from "./context/realm-context/RealmContext";
import { ErrorRenderer } from "./components/error/ErrorRenderer";
import { AdminClient } from "./context/auth/AdminClient";
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
import type KeycloakAdminClient from "keycloak-admin";
export const mainPageContentId = "kc-main-content-page-container";
const AppContexts: FunctionComponent = ({ children }) => (
<AccessContextProvider>
<Help>
<AlertProvider>
<ServerInfoProvider>
<SubGroups>{children}</SubGroups>
</ServerInfoProvider>
</AlertProvider>
</Help>
</AccessContextProvider>
);
// set the realm form the path
const RealmPathSelector: FunctionComponent = ({ children }) => {
const { setRealm } = useRealm();
const { realm } = useParams<{ realm: string }>();
useEffect(() => {
if (realm) setRealm(realm);
}, []);
return <>{children}</>;
export type AdminClientProps = {
adminClient: KeycloakAdminClient;
};
const AppContexts: FunctionComponent<AdminClientProps> = ({
children,
adminClient,
}) => (
<Router>
<AdminClient.Provider value={adminClient}>
<WhoAmIContextProvider>
<RealmContextProvider>
<AccessContextProvider>
<Help>
<AlertProvider>
<ServerInfoProvider>
<SubGroups>{children}</SubGroups>
</ServerInfoProvider>
</AlertProvider>
</Help>
</AccessContextProvider>
</RealmContextProvider>
</WhoAmIContextProvider>
</AdminClient.Provider>
</Router>
);
// If someone tries to go directly to a route they don't
// have access to, show forbidden page.
type SecuredRouteProps = { route: RouteDef };
@ -63,38 +65,32 @@ const SecuredRoute = ({ route }: SecuredRouteProps) => {
return <ForbiddenSection />;
};
export const App = () => {
export const App = ({ adminClient }: AdminClientProps) => {
return (
<AppContexts>
<Router>
<Page
header={<Header />}
isManagedSidebar
sidebar={<PageNav />}
breadcrumb={<PageBreadCrumbs />}
mainContainerId={mainPageContentId}
<AppContexts adminClient={adminClient}>
<Page
header={<Header />}
isManagedSidebar
sidebar={<PageNav />}
breadcrumb={<PageBreadCrumbs />}
mainContainerId={mainPageContentId}
>
<ErrorBoundary
FallbackComponent={ErrorRenderer}
onReset={() => window.location.reload()}
>
<ErrorBoundary
FallbackComponent={ErrorRenderer}
onReset={() => window.location.reload()}
>
<Switch>
{routes.map((route, i) => (
<Route
exact={route.matchOptions?.exact ?? true}
key={i}
path={route.path}
component={() => (
<RealmPathSelector>
<SecuredRoute route={route} />
</RealmPathSelector>
)}
/>
))}
</Switch>
</ErrorBoundary>
</Page>
</Router>
<Switch>
{routes.map((route, i) => (
<Route
exact={route.matchOptions?.exact ?? true}
key={i}
path={route.path}
component={() => <SecuredRoute route={route} />}
/>
))}
</Switch>
</ErrorBoundary>
</Page>
</AppContexts>
);
};

View file

@ -1,25 +0,0 @@
import React from "react";
import type KeycloakAdminClient from "keycloak-admin";
import { AdminClient } from "./context/auth/AdminClient";
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
import { RealmContextProvider } from "./context/realm-context/RealmContext";
import { App } from "./App";
export type KeycloakAdminConsoleProps = {
adminClient: KeycloakAdminClient;
};
export const KeycloakAdminConsole = ({
adminClient,
}: KeycloakAdminConsoleProps) => {
return (
<AdminClient.Provider value={adminClient}>
<WhoAmIContextProvider>
<RealmContextProvider>
<App />
</RealmContextProvider>
</WhoAmIContextProvider>
</AdminClient.Provider>
);
};

View file

@ -1,7 +1,12 @@
import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation";
import _ from "lodash";
import React, { FunctionComponent, useState } from "react";
import React, { FunctionComponent, useEffect, useState } from "react";
import { useRouteMatch } from "react-router-dom";
import { RecentUsed } from "../../components/realm-selector/recent-used";
import {
DashboardParams,
DashboardRoute,
} from "../../dashboard/routes/Dashboard";
import environment from "../../environment";
import useRequiredContext from "../../utils/useRequiredContext";
import { useAdminClient, useFetch } from "../auth/AdminClient";
@ -18,7 +23,10 @@ export const RealmContext = React.createContext<RealmContextType | undefined>(
);
export const RealmContextProvider: FunctionComponent = ({ children }) => {
const [realm, setRealm] = useState(environment.loginRealm);
const routeMatch = useRouteMatch<DashboardParams>(DashboardRoute.path);
const [realm, setRealm] = useState(
routeMatch?.params.realm ?? environment.loginRealm
);
const [realms, setRealms] = useState<RealmRepresentation[]>([]);
const adminClient = useAdminClient();
const recentUsed = new RecentUsed();
@ -34,6 +42,8 @@ export const RealmContextProvider: FunctionComponent = ({ children }) => {
[]
);
useEffect(() => adminClient.setConfig({ realmName: realm }), [realm]);
const set = (realm: string) => {
if (
realms.length === 0 ||
@ -41,9 +51,6 @@ export const RealmContextProvider: FunctionComponent = ({ children }) => {
) {
recentUsed.setRecentUsed(realm);
setRealm(realm);
adminClient.setConfig({
realmName: realm,
});
}
};
return (

View file

@ -1,17 +1,17 @@
import "./index.css";
import React, { StrictMode } from "react";
import ReactDOM from "react-dom";
import i18n from "./i18n";
import { App } from "./App";
import i18n from "./i18n";
import init from "./context/auth/keycloak";
import { KeycloakAdminConsole } from "./KeycloakAdminConsole";
console.info("supported languages", ...i18n.languages);
init().then((adminClient) => {
ReactDOM.render(
<StrictMode>
<KeycloakAdminConsole adminClient={adminClient} />
<App adminClient={adminClient} />
</StrictMode>,
document.getElementById("app")
);