use context for adminClient (#28693)
* use context for adminClient Now we can reuse the components as we can use the adminClient from the context Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * split environment into base, admin and account Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * added type to useEnvironment Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
dde2746595
commit
e28aa90fcb
218 changed files with 1110 additions and 756 deletions
|
@ -12,11 +12,9 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { LinkIcon, UnlinkIcon } from "@patternfly/react-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IconMapper, useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { IconMapper, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { linkAccount, unLinkAccount } from "../api/methods";
|
||||
import { LinkedAccountRepresentation } from "../api/representations";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
|
||||
type AccountRowProps = {
|
||||
account: LinkedAccountRepresentation;
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
} from "@patternfly/react-icons";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { deleteSession, getDevices } from "../api/methods";
|
||||
import {
|
||||
ClientRepresentation,
|
||||
|
@ -32,7 +32,6 @@ import {
|
|||
} from "../api/representations";
|
||||
import { Page } from "../components/page/Page";
|
||||
import { TFuncKey } from "../i18n";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { formatDate } from "../utils/formatDate";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { EmptyRow } from "../components/datalist/EmptyRow";
|
|||
import { Page } from "../components/page/Page";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
import { AccountRow } from "./AccountRow";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
export const LinkedAccounts = () => {
|
||||
const { t } = useTranslation();
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { EllipsisVIcon } from "@patternfly/react-icons";
|
||||
import { CSSProperties, useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { getCredentials } from "../api/methods";
|
||||
import {
|
||||
CredentialContainer,
|
||||
|
@ -26,7 +27,6 @@ import {
|
|||
import { EmptyRow } from "../components/datalist/EmptyRow";
|
||||
import { Page } from "../components/page/Page";
|
||||
import { TFuncKey } from "../i18n";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { formatDate } from "../utils/formatDate";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
|
||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
||||
import { CallOptions } from "./api/methods";
|
||||
import { Links, parseLinks } from "./api/parse-links";
|
||||
import { parseResponse } from "./api/parse-response";
|
||||
import { Permission, Resource, Scope } from "./api/representations";
|
||||
import { request } from "./api/request";
|
||||
import { KeycloakContext } from "./root/KeycloakContext";
|
||||
|
||||
export const fetchResources = async (
|
||||
{ signal, context }: CallOptions,
|
||||
|
@ -43,7 +44,7 @@ export const fetchPermission = async (
|
|||
};
|
||||
|
||||
export const updateRequest = (
|
||||
context: KeycloakContext,
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
resourceId: string,
|
||||
username: string,
|
||||
scopes: Scope[] | string[],
|
||||
|
@ -54,7 +55,7 @@ export const updateRequest = (
|
|||
});
|
||||
|
||||
export const updatePermissions = (
|
||||
context: KeycloakContext,
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
resourceId: string,
|
||||
permissions: Permission[],
|
||||
) =>
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { KeycloakContext } from "../root/KeycloakContext";
|
||||
import {
|
||||
AccountEnvironment,
|
||||
KeycloakContext,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
||||
import { joinPath } from "../utils/joinPath";
|
||||
import { parseResponse } from "./parse-response";
|
||||
import {
|
||||
|
@ -13,7 +17,7 @@ import {
|
|||
import { request } from "./request";
|
||||
|
||||
export type CallOptions = {
|
||||
context: KeycloakContext;
|
||||
context: KeycloakContext<BaseEnvironment>;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
|
@ -41,7 +45,7 @@ export async function getSupportedLocales({
|
|||
}
|
||||
|
||||
export async function savePersonalInfo(
|
||||
context: KeycloakContext,
|
||||
context: KeycloakContext<AccountEnvironment>,
|
||||
info: UserRepresentation,
|
||||
): Promise<void> {
|
||||
const response = await request("/", context, { body: info, method: "POST" });
|
||||
|
@ -81,11 +85,17 @@ export async function getApplications({
|
|||
return parseResponse<ClientRepresentation[]>(response);
|
||||
}
|
||||
|
||||
export async function deleteConsent(context: KeycloakContext, id: string) {
|
||||
export async function deleteConsent(
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
id: string,
|
||||
) {
|
||||
return request(`/applications/${id}/consent`, context, { method: "DELETE" });
|
||||
}
|
||||
|
||||
export async function deleteSession(context: KeycloakContext, id?: string) {
|
||||
export async function deleteSession(
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
id?: string,
|
||||
) {
|
||||
return request(`/sessions${id ? `/${id}` : ""}`, context, {
|
||||
method: "DELETE",
|
||||
});
|
||||
|
@ -104,7 +114,7 @@ export async function getLinkedAccounts({ signal, context }: CallOptions) {
|
|||
}
|
||||
|
||||
export async function unLinkAccount(
|
||||
context: KeycloakContext,
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
account: LinkedAccountRepresentation,
|
||||
) {
|
||||
const response = await request(
|
||||
|
@ -119,7 +129,7 @@ export async function unLinkAccount(
|
|||
}
|
||||
|
||||
export async function linkAccount(
|
||||
context: KeycloakContext,
|
||||
context: KeycloakContext<BaseEnvironment>,
|
||||
account: LinkedAccountRepresentation,
|
||||
) {
|
||||
const redirectUri = encodeURIComponent(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Environment } from "../environment";
|
||||
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
|
||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
||||
import Keycloak from "keycloak-js";
|
||||
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
|
||||
import { joinPath } from "../utils/joinPath";
|
||||
import { KeycloakContext } from "../root/KeycloakContext";
|
||||
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
|
||||
|
||||
export type RequestOptions = {
|
||||
signal?: AbortSignal;
|
||||
|
@ -35,7 +35,7 @@ async function _request(
|
|||
|
||||
export async function request(
|
||||
path: string,
|
||||
{ environment, keycloak }: KeycloakContext,
|
||||
{ environment, keycloak }: KeycloakContext<BaseEnvironment>,
|
||||
opts: RequestOptions = {},
|
||||
) {
|
||||
return _request(url(environment, path), {
|
||||
|
@ -44,7 +44,7 @@ export async function request(
|
|||
});
|
||||
}
|
||||
|
||||
export const url = (environment: Environment, path: string) =>
|
||||
export const url = (environment: BaseEnvironment, path: string) =>
|
||||
new URL(
|
||||
joinPath(environment.authUrl, "realms", environment.realm, "account", path),
|
||||
);
|
||||
|
|
|
@ -22,12 +22,11 @@ import {
|
|||
} from "@patternfly/react-icons";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { deleteConsent, getApplications } from "../api/methods";
|
||||
import { ClientRepresentation } from "../api/representations";
|
||||
import { Page } from "../components/page/Page";
|
||||
import { TFuncKey } from "../i18n";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { formatDate } from "../utils/formatDate";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Spinner } from "@patternfly/react-core";
|
||||
import { Suspense, lazy, useMemo, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { MenuItem } from "../root/PageNav";
|
||||
import { ContentComponentParams } from "../routes";
|
||||
import { joinPath } from "../utils/joinPath";
|
||||
|
|
|
@ -8,10 +8,10 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { getGroups } from "../api/methods";
|
||||
import { Group } from "../api/representations";
|
||||
import { Page } from "../components/page/Page";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
|
||||
export const Groups = () => {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { LanguageDetectorModule, createInstance } from "i18next";
|
||||
import HttpBackend from "i18next-http-backend";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
import { environment } from "./environment";
|
||||
import { environment } from "@keycloak/keycloak-ui-shared";
|
||||
import { joinPath } from "./utils/joinPath";
|
||||
|
||||
const DEFAULT_LOCALE = "en";
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
export { PersonalInfo } from "./personal-info/PersonalInfo";
|
||||
export { ErrorPage } from "./root/ErrorPage";
|
||||
export { Header } from "./root/Header";
|
||||
export { KeycloakProvider, useEnvironment } from "./root/KeycloakContext";
|
||||
export { PageNav } from "./root/PageNav";
|
||||
export { DeviceActivity } from "./account-security/DeviceActivity";
|
||||
export { LinkedAccounts } from "./account-security/LinkedAccounts";
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import {
|
||||
AccountEnvironment,
|
||||
UserProfileFields,
|
||||
beerify,
|
||||
debeerify,
|
||||
setUserProfileServerError,
|
||||
useAlerts,
|
||||
useEnvironment,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
ActionGroup,
|
||||
|
@ -18,7 +20,6 @@ import { TFunction } from "i18next";
|
|||
import { useState } from "react";
|
||||
import { ErrorOption, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
getPersonalInfo,
|
||||
getSupportedLocales,
|
||||
|
@ -29,14 +30,12 @@ import {
|
|||
UserRepresentation,
|
||||
} from "../api/representations";
|
||||
import { Page } from "../components/page/Page";
|
||||
import { environment } from "../environment";
|
||||
import { TFuncKey, i18n } from "../i18n";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
|
||||
export const PersonalInfo = () => {
|
||||
const { t } = useTranslation();
|
||||
const context = useEnvironment();
|
||||
const context = useEnvironment<AccountEnvironment>();
|
||||
const [userProfileMetadata, setUserProfileMetadata] =
|
||||
useState<UserProfileMetadata>();
|
||||
const [supportedLocales, setSupportedLocales] = useState<string[]>([]);
|
||||
|
@ -106,7 +105,7 @@ export const PersonalInfo = () => {
|
|||
form={form}
|
||||
userProfileMetadata={userProfileMetadata}
|
||||
supportedLocales={supportedLocales}
|
||||
currentLocale={environment.locale}
|
||||
currentLocale={context.environment.locale}
|
||||
t={
|
||||
((key: unknown, params) =>
|
||||
t(key as TFuncKey, params as any)) as TFunction
|
||||
|
|
|
@ -2,15 +2,14 @@ import { Button, Form, Modal } from "@patternfly/react-core";
|
|||
import { Fragment, useEffect } from "react";
|
||||
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
SelectControl,
|
||||
TextControl,
|
||||
useAlerts,
|
||||
useEnvironment,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { updatePermissions } from "../api";
|
||||
import type { Permission, Resource } from "../api/representations";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
|
||||
type EditTheResourceProps = {
|
||||
resource: Resource;
|
||||
|
|
|
@ -11,11 +11,9 @@ import { UserCheckIcon } from "@patternfly/react-icons";
|
|||
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { fetchPermission, updateRequest } from "../api";
|
||||
import { Permission, Resource } from "../api/representations";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
|
||||
type PermissionRequestProps = {
|
||||
resource: Resource;
|
||||
|
|
|
@ -32,13 +32,11 @@ import {
|
|||
} from "@patternfly/react-table";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||
import { fetchPermission, fetchResources, updatePermissions } from "../api";
|
||||
import { getPermissionRequests } from "../api/methods";
|
||||
import { Links } from "../api/parse-links";
|
||||
import { Permission, Resource } from "../api/representations";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
import { EditTheResource } from "./EditTheResource";
|
||||
import { PermissionRequest } from "./PermissionRequest";
|
||||
|
|
|
@ -22,10 +22,10 @@ import {
|
|||
FormErrorText,
|
||||
SelectControl,
|
||||
useAlerts,
|
||||
useEnvironment,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { updateRequest } from "../api";
|
||||
import { Permission, Resource } from "../api/representations";
|
||||
import { useEnvironment } from "../root/KeycloakContext";
|
||||
import { SharedWith } from "./SharedWith";
|
||||
|
||||
type ShareTheResourceProps = {
|
||||
|
|
|
@ -2,11 +2,13 @@ import { Button } from "@patternfly/react-core";
|
|||
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useHref } from "react-router-dom";
|
||||
import { KeycloakMasthead, label } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { environment } from "../environment";
|
||||
import {
|
||||
KeycloakMasthead,
|
||||
environment,
|
||||
label,
|
||||
useEnvironment,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { joinPath } from "../utils/joinPath";
|
||||
import { useEnvironment } from "./KeycloakContext";
|
||||
|
||||
import style from "./header.module.css";
|
||||
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
import { Spinner } from "@patternfly/react-core";
|
||||
import Keycloak from "keycloak-js";
|
||||
import {
|
||||
PropsWithChildren,
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { AlertProvider, Help } from "@keycloak/keycloak-ui-shared";
|
||||
import { Environment } from "../environment";
|
||||
import { ErrorPage } from "./ErrorPage";
|
||||
|
||||
export type KeycloakContext = KeycloakContextProps & {
|
||||
keycloak: Keycloak;
|
||||
};
|
||||
|
||||
const KeycloakEnvContext = createContext<KeycloakContext | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
export const useEnvironment = () => {
|
||||
const context = useContext(KeycloakEnvContext);
|
||||
if (!context)
|
||||
throw Error(
|
||||
"no environment provider in the hierarchy make sure to add the provider",
|
||||
);
|
||||
return context;
|
||||
};
|
||||
|
||||
type KeycloakContextProps = {
|
||||
environment: Environment;
|
||||
};
|
||||
|
||||
export const KeycloakProvider = ({
|
||||
environment,
|
||||
children,
|
||||
}: PropsWithChildren<KeycloakContextProps>) => {
|
||||
const calledOnce = useRef(false);
|
||||
const [init, setInit] = useState(false);
|
||||
const [error, setError] = useState<unknown>();
|
||||
const keycloak = useMemo(
|
||||
() => {
|
||||
const keycloak = new Keycloak({
|
||||
url: environment.authUrl,
|
||||
realm: environment.realm,
|
||||
clientId: environment.clientId,
|
||||
});
|
||||
|
||||
keycloak.onAuthLogout = () => keycloak.login();
|
||||
|
||||
return keycloak;
|
||||
},
|
||||
[environment],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// only needed in dev mode
|
||||
if (calledOnce.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const init = () => keycloak.init({
|
||||
onLoad: "check-sso",
|
||||
pkceMethod: "S256",
|
||||
responseMode: "query",
|
||||
});
|
||||
|
||||
init()
|
||||
.then(() => setInit(true))
|
||||
.catch((error) => setError(error));
|
||||
|
||||
calledOnce.current = true;
|
||||
}, [keycloak]);
|
||||
|
||||
if (error) {
|
||||
return <ErrorPage error={error} />;
|
||||
}
|
||||
|
||||
if (!init) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
return (
|
||||
<KeycloakEnvContext.Provider value={{ environment, keycloak }}>
|
||||
<AlertProvider>
|
||||
<Help>{children}</Help>
|
||||
</AlertProvider>
|
||||
</KeycloakEnvContext.Provider>
|
||||
);
|
||||
};
|
|
@ -4,8 +4,8 @@ import {
|
|||
NavItem,
|
||||
NavList,
|
||||
PageSidebar,
|
||||
Spinner,
|
||||
PageSidebarBody,
|
||||
Spinner,
|
||||
} from "@patternfly/react-core";
|
||||
import {
|
||||
PropsWithChildren,
|
||||
|
@ -22,11 +22,15 @@ import {
|
|||
useLinkClickHandler,
|
||||
useLocation,
|
||||
} from "react-router-dom";
|
||||
import {
|
||||
AccountEnvironment,
|
||||
environment,
|
||||
useEnvironment,
|
||||
type Feature,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import fetchContentJson from "../content/fetchContent";
|
||||
import { environment, type Feature } from "../environment";
|
||||
import { TFuncKey } from "../i18n";
|
||||
import { usePromise } from "../utils/usePromise";
|
||||
import { useEnvironment } from "./KeycloakContext";
|
||||
|
||||
type RootMenuItem = {
|
||||
label: TFuncKey;
|
||||
|
@ -45,7 +49,7 @@ export type MenuItem = RootMenuItem | MenuItemWithChildren;
|
|||
|
||||
export const PageNav = () => {
|
||||
const [menuItems, setMenuItems] = useState<MenuItem[]>();
|
||||
const context = useEnvironment();
|
||||
const context = useEnvironment<AccountEnvironment>();
|
||||
|
||||
usePromise((signal) => fetchContentJson({ signal, context }), setMenuItems);
|
||||
return (
|
||||
|
@ -82,7 +86,7 @@ function NavMenuItem({ menuItem }: NavMenuItemProps) {
|
|||
const { t } = useTranslation();
|
||||
const {
|
||||
environment: { features },
|
||||
} = useEnvironment();
|
||||
} = useEnvironment<AccountEnvironment>();
|
||||
const { pathname } = useLocation();
|
||||
const isActive = useMemo(
|
||||
() => matchMenuItem(pathname, menuItem),
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
|
||||
import { Page, Spinner } from "@patternfly/react-core";
|
||||
import { Suspense } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { environment } from "../environment";
|
||||
import { Header } from "./Header";
|
||||
import { KeycloakProvider } from "./KeycloakContext";
|
||||
import { PageNav } from "./PageNav";
|
||||
|
||||
export const Root = () => {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { lazy } from "react";
|
||||
import type { IndexRouteObject, RouteObject } from "react-router-dom";
|
||||
|
||||
import { environment } from "@keycloak/keycloak-ui-shared";
|
||||
import { ErrorPage } from "./root/ErrorPage";
|
||||
import { Root } from "./root/Root";
|
||||
import { environment } from "./environment";
|
||||
|
||||
const DeviceActivity = lazy(() => import("./account-security/DeviceActivity"));
|
||||
const LinkedAccounts = lazy(() => import("./account-security/LinkedAccounts"));
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
<![CDATA[
|
||||
<script id="environment" type="application/json">
|
||||
{
|
||||
"loginRealm": "${loginRealm!"master"}",
|
||||
"realm": "${loginRealm!"master"}",
|
||||
"clientId": "${clientId}",
|
||||
"authServerUrl": "${authServerUrl}",
|
||||
"authUrl": "${authUrl}",
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import { Page } from "@patternfly/react-core";
|
||||
import { PropsWithChildren, Suspense } from "react";
|
||||
import { PropsWithChildren, Suspense, useEffect, useState } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Help, mainPageContentId } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import {
|
||||
mainPageContentId,
|
||||
useEnvironment,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { Header } from "./PageHeader";
|
||||
import { PageNav } from "./PageNav";
|
||||
import { AdminClientContext, initAdminClient } from "./admin-client";
|
||||
import { AlertProvider } from "./components/alert/Alerts";
|
||||
import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs";
|
||||
import { ErrorRenderer } from "./components/error/ErrorRenderer";
|
||||
|
@ -30,11 +34,9 @@ const AppContexts = ({ children }: PropsWithChildren) => (
|
|||
<RealmsProvider>
|
||||
<RecentRealmsProvider>
|
||||
<AccessContextProvider>
|
||||
<Help>
|
||||
<AlertProvider>
|
||||
<SubGroups>{children}</SubGroups>
|
||||
</AlertProvider>
|
||||
</Help>
|
||||
<AlertProvider>
|
||||
<SubGroups>{children}</SubGroups>
|
||||
</AlertProvider>
|
||||
</AccessContextProvider>
|
||||
</RecentRealmsProvider>
|
||||
</RealmsProvider>
|
||||
|
@ -45,23 +47,37 @@ const AppContexts = ({ children }: PropsWithChildren) => (
|
|||
);
|
||||
|
||||
export const App = () => {
|
||||
const { keycloak, environment } = useEnvironment();
|
||||
const [adminClient, setAdminClient] = useState<KeycloakAdminClient>();
|
||||
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
const client = await initAdminClient(keycloak, environment);
|
||||
setAdminClient(client);
|
||||
};
|
||||
init().catch(console.error);
|
||||
}, []);
|
||||
|
||||
if (!adminClient) return <KeycloakSpinner />;
|
||||
return (
|
||||
<AppContexts>
|
||||
<Page
|
||||
header={<Header />}
|
||||
isManagedSidebar
|
||||
sidebar={<PageNav />}
|
||||
breadcrumb={<PageBreadCrumbs />}
|
||||
mainContainerId={mainPageContentId}
|
||||
>
|
||||
<ErrorBoundaryFallback fallback={ErrorRenderer}>
|
||||
<Suspense fallback={<KeycloakSpinner />}>
|
||||
<AuthWall>
|
||||
<Outlet />
|
||||
</AuthWall>
|
||||
</Suspense>
|
||||
</ErrorBoundaryFallback>
|
||||
</Page>
|
||||
</AppContexts>
|
||||
<AdminClientContext.Provider value={{ keycloak, adminClient }}>
|
||||
<AppContexts>
|
||||
<Page
|
||||
header={<Header />}
|
||||
isManagedSidebar
|
||||
sidebar={<PageNav />}
|
||||
breadcrumb={<PageBreadCrumbs />}
|
||||
mainContainerId={mainPageContentId}
|
||||
>
|
||||
<ErrorBoundaryFallback fallback={ErrorRenderer}>
|
||||
<Suspense fallback={<KeycloakSpinner />}>
|
||||
<AuthWall>
|
||||
<Outlet />
|
||||
</AuthWall>
|
||||
</Suspense>
|
||||
</ErrorBoundaryFallback>
|
||||
</Page>
|
||||
</AppContexts>
|
||||
</AdminClientContext.Provider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -18,16 +18,15 @@ import { BarsIcon, EllipsisVIcon, HelpIcon } from "@patternfly/react-icons";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useHref } from "react-router-dom";
|
||||
import { useHelp } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { useEnvironment, useHelp } from "@keycloak/keycloak-ui-shared";
|
||||
import { HelpHeader } from "./components/help-enabler/HelpHeader";
|
||||
import { useRealm } from "./context/realm-context/RealmContext";
|
||||
import { useWhoAmI } from "./context/whoami/WhoAmI";
|
||||
import { toDashboard } from "./dashboard/routes/Dashboard";
|
||||
import environment from "./environment";
|
||||
import { keycloak } from "./keycloak";
|
||||
|
||||
const ManageAccountDropdownItem = () => {
|
||||
const { keycloak } = useEnvironment();
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<DropdownItem
|
||||
|
@ -41,6 +40,7 @@ const ManageAccountDropdownItem = () => {
|
|||
};
|
||||
|
||||
const SignOutDropdownItem = () => {
|
||||
const { keycloak } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<DropdownItem
|
||||
|
@ -146,6 +146,7 @@ const UserDropdown = () => {
|
|||
};
|
||||
|
||||
export const Header = () => {
|
||||
const { environment, keycloak } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
const { realm } = useRealm();
|
||||
|
||||
|
|
8
js/apps/admin-ui/src/Root.tsx
Normal file
8
js/apps/admin-ui/src/Root.tsx
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
|
||||
import { App } from "./App";
|
||||
|
||||
export const Root = () => (
|
||||
<KeycloakProvider environment={environment}>
|
||||
<App />
|
||||
</KeycloakProvider>
|
||||
);
|
|
@ -1,20 +1,41 @@
|
|||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import {
|
||||
createNamedContext,
|
||||
useRequiredContext,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
||||
import type Keycloak from "keycloak-js";
|
||||
|
||||
import environment from "./environment";
|
||||
import { keycloak } from "./keycloak";
|
||||
export type AdminClientProps = {
|
||||
keycloak: Keycloak;
|
||||
adminClient: KeycloakAdminClient;
|
||||
};
|
||||
|
||||
export const adminClient = new KeycloakAdminClient();
|
||||
export const AdminClientContext = createNamedContext<
|
||||
AdminClientProps | undefined
|
||||
>("AdminClientContext", undefined);
|
||||
|
||||
adminClient.setConfig({ realmName: environment.loginRealm });
|
||||
adminClient.baseUrl = environment.authUrl;
|
||||
adminClient.registerTokenProvider({
|
||||
async getAccessToken() {
|
||||
try {
|
||||
await keycloak.updateToken(5);
|
||||
} catch (error) {
|
||||
keycloak.login();
|
||||
}
|
||||
export const useAdminClient = () => useRequiredContext(AdminClientContext);
|
||||
|
||||
return keycloak.token;
|
||||
},
|
||||
});
|
||||
export async function initAdminClient(
|
||||
keycloak: Keycloak,
|
||||
environment: BaseEnvironment,
|
||||
) {
|
||||
const adminClient = new KeycloakAdminClient();
|
||||
|
||||
adminClient.setConfig({ realmName: environment.realm });
|
||||
adminClient.baseUrl = environment.authUrl;
|
||||
adminClient.registerTokenProvider({
|
||||
async getAccessToken() {
|
||||
try {
|
||||
await keycloak.updateToken(5);
|
||||
} catch (error) {
|
||||
keycloak.login();
|
||||
}
|
||||
|
||||
return keycloak.token;
|
||||
},
|
||||
});
|
||||
|
||||
return adminClient;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@ import { sortBy } from "lodash-es";
|
|||
import { useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
@ -42,6 +40,7 @@ import { Policies } from "./policies/Policies";
|
|||
import { AuthenticationTab, toAuthentication } from "./routes/Authentication";
|
||||
import { toCreateFlow } from "./routes/CreateFlow";
|
||||
import { toFlow } from "./routes/Flow";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
|
||||
type UsedBy = "SPECIFIC_CLIENTS" | "SPECIFIC_PROVIDERS" | "DEFAULT";
|
||||
|
||||
|
@ -83,6 +82,7 @@ const AliasRenderer = ({ id, alias, usedBy, builtIn }: AuthenticationType) => {
|
|||
};
|
||||
|
||||
export default function AuthenticationSection() {
|
||||
const { adminClient } = useAdminClient();
|
||||
const { t } = useTranslation();
|
||||
const { realm: realmName } = useRealm();
|
||||
const [key, setKey] = useState(0);
|
||||
|
|
|
@ -10,11 +10,10 @@ import { SelectVariant } from "@patternfly/react-core/deprecated";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
import { REALM_FLOWS } from "./AuthenticationSection";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
|
||||
type BindingForm = {
|
||||
bindingType: keyof RealmRepresentation;
|
||||
|
@ -26,6 +25,8 @@ type BindFlowDialogProps = {
|
|||
};
|
||||
|
||||
export const BindFlowDialog = ({ flowAlias, onClose }: BindFlowDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<BindingForm>();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -11,8 +11,7 @@ import { useEffect } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
import { NameDescription } from "./form/NameDescription";
|
||||
|
@ -31,6 +30,8 @@ export const DuplicateFlowModal = ({
|
|||
toggleDialog,
|
||||
onComplete,
|
||||
}: DuplicateFlowModalProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<AuthenticationFlowRepresentation>({ mode: "onChange" });
|
||||
const { setValue, getValues, handleSubmit } = form;
|
||||
|
|
|
@ -9,9 +9,8 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { useEffect } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { NameDescription } from "./form/NameDescription";
|
||||
|
||||
|
@ -21,6 +20,8 @@ type EditFlowModalProps = {
|
|||
};
|
||||
|
||||
export const EditFlowModal = ({ flow, toggleDialog }: EditFlowModalProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const form = useForm<AuthenticationFlowRepresentation>({ mode: "onChange" });
|
||||
|
|
|
@ -21,7 +21,7 @@ import { DomainIcon, TableIcon } from "@patternfly/react-icons";
|
|||
import { useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||
|
@ -52,6 +52,8 @@ export const providerConditionFilter = (
|
|||
) => value.displayName?.startsWith("Condition ");
|
||||
|
||||
export default function FlowDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { realm } = useRealm();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -3,8 +3,7 @@ import type RequiredActionProviderSimpleRepresentation from "@keycloak/keycloak-
|
|||
import { AlertVariant, Switch } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { toKey } from "../util";
|
||||
|
@ -22,6 +21,8 @@ type Row = {
|
|||
};
|
||||
|
||||
export const RequiredActions = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ import {
|
|||
import { PlusIcon } from "@patternfly/react-icons";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import type { ExpandableExecution } from "../execution-model";
|
||||
import { AddStepModal, FlowType } from "./modals/AddStepModal";
|
||||
|
@ -29,6 +28,8 @@ export const AddFlowDropdown = ({
|
|||
onAddExecution,
|
||||
onAddFlow,
|
||||
}: AddFlowDropdownProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
|
|
@ -15,7 +15,7 @@ import { useEffect, useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
|
@ -34,6 +34,8 @@ type ExecutionConfigModalProps = {
|
|||
export const ExecutionConfigModal = ({
|
||||
execution,
|
||||
}: ExecutionConfigModalProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { CheckCircleIcon } from "@patternfly/react-icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { fetchUsedBy } from "../../components/role-mapping/resource";
|
||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||
import useToggle from "../../utils/useToggle";
|
||||
|
@ -36,6 +36,8 @@ type UsedByModalProps = {
|
|||
};
|
||||
|
||||
const UsedByModal = ({ id, isSpecificClient, onClose }: UsedByModalProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const loader = async (
|
||||
|
@ -43,7 +45,7 @@ const UsedByModal = ({ id, isSpecificClient, onClose }: UsedByModalProps) => {
|
|||
max?: number,
|
||||
search?: string,
|
||||
): Promise<{ name: string }[]> => {
|
||||
const result = await fetchUsedBy({
|
||||
const result = await fetchUsedBy(adminClient, {
|
||||
id,
|
||||
type: isSpecificClient ? "clients" : "idp",
|
||||
first: first || 0,
|
||||
|
|
|
@ -10,12 +10,11 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { PaginatingTableToolbar } from "../../../components/table-toolbar/PaginatingTableToolbar";
|
||||
import { useFetch } from "../../../utils/useFetch";
|
||||
import useLocaleSort, { mapByKey } from "../../../utils/useLocaleSort";
|
||||
import { providerConditionFilter } from "../../FlowDetails";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
|
||||
type AuthenticationProviderListProps = {
|
||||
list?: AuthenticationProviderRepresentation[];
|
||||
|
@ -56,6 +55,8 @@ type AddStepModalProps = {
|
|||
};
|
||||
|
||||
export const AddStepModal = ({ name, type, onSelect }: AddStepModalProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [value, setValue] = useState<AuthenticationProviderRepresentation>();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { useEffect, useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl, TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
import { useFetch } from "../../../utils/useFetch";
|
||||
|
||||
type AddSubFlowProps = {
|
||||
|
@ -33,6 +33,8 @@ export const AddSubFlowModal = ({
|
|||
onConfirm,
|
||||
onCancel,
|
||||
}: AddSubFlowProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<Flow>();
|
||||
const [formProviders, setFormProviders] =
|
||||
|
|
|
@ -8,9 +8,8 @@ import {
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
@ -22,6 +21,8 @@ import { NameDescription } from "./NameDescription";
|
|||
const TYPES = ["basic-flow", "client-flow"] as const;
|
||||
|
||||
export default function CreateFlow() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { useEffect } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl, TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
|
@ -33,6 +33,8 @@ type FormFields = Omit<
|
|||
>;
|
||||
|
||||
export const CibaPolicy = ({ realm, realmUpdated }: CibaPolicyProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<FormFields>({ mode: "onChange" });
|
||||
const { realm: realmName } = useRealm();
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
SelectControl,
|
||||
SwitchControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";
|
||||
|
@ -43,6 +43,8 @@ type FormFields = Omit<
|
|||
>;
|
||||
|
||||
export const OtpPolicy = ({ realm, realmUpdated }: OtpPolicyProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<FormFields>({ mode: "onChange", defaultValues: realm });
|
||||
const {
|
||||
|
|
|
@ -7,15 +7,15 @@ import {
|
|||
ButtonVariant,
|
||||
Divider,
|
||||
EmptyState,
|
||||
EmptyStateActions,
|
||||
EmptyStateBody,
|
||||
EmptyStateFooter,
|
||||
EmptyStateHeader,
|
||||
EmptyStateIcon,
|
||||
PageSection,
|
||||
Toolbar,
|
||||
ToolbarContent,
|
||||
ToolbarItem,
|
||||
EmptyStateActions,
|
||||
EmptyStateHeader,
|
||||
EmptyStateFooter,
|
||||
Select,
|
||||
SelectOption,
|
||||
MenuToggle,
|
||||
|
@ -25,8 +25,7 @@ import { PlusCircleIcon } from "@patternfly/react-icons";
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
|
@ -94,6 +93,8 @@ export const PasswordPolicy = ({
|
|||
realm,
|
||||
realmUpdated,
|
||||
}: PasswordPolicyProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { passwordPolicies } = useServerInfo();
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@ import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/r
|
|||
import { Tab, Tabs, TabTitleText } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
|
@ -13,6 +12,8 @@ import { PasswordPolicy } from "./PasswordPolicy";
|
|||
import { WebauthnPolicy } from "./WebauthnPolicy";
|
||||
|
||||
export const Policies = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [subTab, setSubTab] = useState(1);
|
||||
const { realm: realmName } = useRealm();
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
TextControl,
|
||||
useHelp,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
|
@ -30,6 +29,7 @@ import { TimeSelectorControl } from "../../components/time-selector/TimeSelector
|
|||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import "./webauthn-policy.css";
|
||||
|
||||
const SIGNATURE_ALGORITHMS = [
|
||||
|
@ -108,6 +108,8 @@ export const WebauthnPolicy = ({
|
|||
realmUpdated,
|
||||
isPasswordLess = false,
|
||||
}: WebauthnPolicyProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm: realmName } = useRealm();
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AlertVariant } from "@patternfly/react-core";
|
|||
import { Select } from "@patternfly/react-core/deprecated";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import type { Row } from "../clients/scopes/ClientScopes";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import {
|
||||
|
@ -24,6 +24,8 @@ export const ChangeTypeDropdown = ({
|
|||
selectedRows,
|
||||
refresh,
|
||||
}: ChangeTypeDropdownProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
|
@ -44,12 +46,13 @@ export const ChangeTypeDropdown = ({
|
|||
selectedRows.map((row) => {
|
||||
return clientId
|
||||
? changeClientScope(
|
||||
adminClient,
|
||||
clientId,
|
||||
row,
|
||||
row.type,
|
||||
value as ClientScope,
|
||||
)
|
||||
: changeScope(row, value as ClientScope);
|
||||
: changeScope(adminClient, row, value as ClientScope);
|
||||
}),
|
||||
);
|
||||
setOpen(false);
|
||||
|
|
|
@ -14,8 +14,7 @@ import { cellWidth } from "@patternfly/react-table";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import type { Row } from "../clients/scopes/ClientScopes";
|
||||
import { getProtocolName } from "../clients/utils";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
|
@ -56,6 +55,8 @@ type TypeSelectorProps = ClientScopeDefaultOptionalType & {
|
|||
};
|
||||
|
||||
const TypeSelector = (scope: TypeSelectorProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
@ -66,7 +67,7 @@ const TypeSelector = (scope: TypeSelectorProps) => {
|
|||
all
|
||||
onSelect={async (value) => {
|
||||
try {
|
||||
await changeScope(scope, value as AllClientScopeType);
|
||||
await changeScope(adminClient, scope, value as AllClientScopeType);
|
||||
addAlert(t("clientScopeSuccess"), AlertVariant.success);
|
||||
scope.refresh();
|
||||
} catch (error) {
|
||||
|
@ -90,6 +91,8 @@ const ClientScopeDetailLink = ({
|
|||
};
|
||||
|
||||
export default function ClientScopesSection() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { realm } = useRealm();
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
@ -165,7 +168,7 @@ export default function ClientScopesSection() {
|
|||
try {
|
||||
for (const scope of selectedScopes) {
|
||||
try {
|
||||
await removeScope(scope);
|
||||
await removeScope(adminClient, scope);
|
||||
} catch (error: any) {
|
||||
console.warn(
|
||||
"could not remove scope",
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { AlertVariant, PageSection } from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import {
|
||||
ClientScopeDefaultOptionalType,
|
||||
|
@ -15,6 +14,8 @@ import { ScopeForm } from "./details/ScopeForm";
|
|||
import { toClientScope } from "./routes/ClientScope";
|
||||
|
||||
export default function CreateClientScope() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
@ -37,7 +38,11 @@ export default function CreateClientScope() {
|
|||
throw new Error(t("notFound"));
|
||||
}
|
||||
|
||||
await changeScope({ ...clientScope, id: scope.id }, clientScope.type);
|
||||
await changeScope(
|
||||
adminClient,
|
||||
{ ...clientScope, id: scope.id },
|
||||
clientScope.type,
|
||||
);
|
||||
|
||||
addAlert(t("createClientScopeSuccess", AlertVariant.success));
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ import { useState } from "react";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useHelp } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import {
|
||||
AllClientScopes,
|
||||
|
@ -43,10 +42,12 @@ import {
|
|||
ClientScopeTab,
|
||||
toClientScope,
|
||||
} from "./routes/ClientScope";
|
||||
import { toMapper } from "./routes/Mapper";
|
||||
import { toClientScopes } from "./routes/ClientScopes";
|
||||
import { toMapper } from "./routes/Mapper";
|
||||
|
||||
export default function EditClientScope() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
@ -118,7 +119,7 @@ export default function EditClientScope() {
|
|||
|
||||
try {
|
||||
await adminClient.clientScopes.update({ id }, clientScope);
|
||||
await changeScope({ ...clientScope, id }, clientScope.type);
|
||||
await changeScope(adminClient, { ...clientScope, id }, clientScope.type);
|
||||
|
||||
addAlert(t("updateSuccessClientScope"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
|
|
|
@ -15,7 +15,8 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useMatch, useNavigate } from "react-router-dom";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { toDedicatedScope } from "../../clients/routes/DedicatedScopeDetails";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
|
||||
|
@ -28,9 +29,10 @@ import { useFetch } from "../../utils/useFetch";
|
|||
import { useParams } from "../../utils/useParams";
|
||||
import { toClientScope } from "../routes/ClientScope";
|
||||
import { MapperParams, MapperRoute } from "../routes/Mapper";
|
||||
import { toDedicatedScope } from "../../clients/routes/DedicatedScopeDetails";
|
||||
|
||||
export default function MappingDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ import { useMemo, useState } from "react";
|
|||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import {
|
||||
ConfirmDialogModal,
|
||||
|
@ -188,6 +187,8 @@ export type FormFields = Omit<
|
|||
>;
|
||||
|
||||
export default function ClientDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -2,7 +2,7 @@ import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/
|
|||
import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
|
||||
import { PageSection } from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import type { LoaderFunction } from "../components/table-toolbar/KeycloakDataTable";
|
||||
import SessionsTable from "../sessions/SessionsTable";
|
||||
|
||||
|
@ -11,6 +11,8 @@ type ClientSessionsProps = {
|
|||
};
|
||||
|
||||
export const ClientSessions = ({ client }: ClientSessionsProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const loader: LoaderFunction<UserSessionRepresentation> = async (
|
||||
|
|
|
@ -14,8 +14,7 @@ import { IRowData, TableText, cellWidth } from "@patternfly/react-table";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../admin-client";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormattedLink } from "../components/external-link/FormattedLink";
|
||||
|
@ -74,6 +73,7 @@ const ClientDescription = (client: ClientRepresentation) => (
|
|||
);
|
||||
|
||||
const ClientHomeLink = (client: ClientRepresentation) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
const href = convertClientToUrl(client, adminClient.baseUrl);
|
||||
|
||||
if (!href) {
|
||||
|
@ -117,6 +117,8 @@ const ToolbarItems = () => {
|
|||
};
|
||||
|
||||
export default function ClientsSection() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -8,8 +8,7 @@ import { useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
@ -23,6 +22,8 @@ import { GeneralSettings } from "./GeneralSettings";
|
|||
import { LoginSettings } from "./LoginSettings";
|
||||
|
||||
export default function NewClientForm() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { realm } = useRealm();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
||||
type FormFields = {
|
||||
|
@ -28,6 +28,8 @@ export const AddHostDialog = ({
|
|||
onAdded,
|
||||
onClose,
|
||||
}: AddHostDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<FormFields>();
|
||||
const {
|
||||
|
|
|
@ -8,21 +8,20 @@ import {
|
|||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { convertAttributeNameToForm } from "../../util";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
|
||||
import { FormFields } from "../ClientDetails";
|
||||
import { TokenLifespan } from "./TokenLifespan";
|
||||
|
||||
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
|
||||
|
||||
type AdvancedSettingsProps = {
|
||||
save: () => void;
|
||||
reset: () => void;
|
||||
|
@ -36,6 +35,8 @@ export const AdvancedSettings = ({
|
|||
protocol,
|
||||
hasConfigureAccess,
|
||||
}: AdvancedSettingsProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { sortBy } from "lodash-es";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
|
||||
|
@ -21,6 +21,8 @@ export const AuthenticationOverrides = ({
|
|||
reset,
|
||||
hasConfigureAccess,
|
||||
}: AuthenticationOverridesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [flows, setFlows] = useState<AuthenticationFlowRepresentation[]>([]);
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -35,6 +34,8 @@ export const ClusteringPanel = ({
|
|||
save,
|
||||
client: { id, registeredNodes, access },
|
||||
}: AdvancedProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const formatDate = useFormatDate();
|
||||
|
|
|
@ -30,9 +30,8 @@ import {
|
|||
HelpItem,
|
||||
TextControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { ForbiddenSection } from "../../ForbiddenSection";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { ClientSelect } from "../../components/client/ClientSelect";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -98,6 +97,8 @@ export const AuthorizationEvaluate = (props: Props) => {
|
|||
};
|
||||
|
||||
const AuthorizationEvaluateContent = ({ client }: Props) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const form = useForm<EvaluateFormInputs>({ mode: "onChange" });
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -9,16 +9,18 @@ import { saveAs } from "file-saver";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TextAreaControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { prettyPrintJSON } from "../../util";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { useParams } from "../../utils/useParams";
|
||||
import type { ClientParams } from "../routes/Client";
|
||||
|
||||
export const AuthorizationExport = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { clientId } = useParams<ClientParams>();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||
import { Alert, AlertVariant } from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { ConfirmDialogModal } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import type { PermissionScopeRepresentation } from "./Scopes";
|
||||
|
@ -25,6 +24,8 @@ export const DeleteScopeDialog = ({
|
|||
open,
|
||||
toggleDialog,
|
||||
}: DeleteScopeDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import type ResourceServerRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceServerRepresentation";
|
||||
import { DescriptionList } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { adminClient } from "../../admin-client";
|
||||
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { toPermissionDetails } from "../routes/PermissionDetails";
|
||||
import { toScopeDetails } from "../routes/Scope";
|
||||
import { DetailDescription, DetailDescriptionLink } from "./DetailDescription";
|
||||
|
@ -21,6 +20,8 @@ type DetailCellProps = {
|
|||
};
|
||||
|
||||
export const DetailCell = ({ id, clientId, uris }: DetailCellProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { realm } = useRealm();
|
||||
const [scope, setScope] = useState<Scope>();
|
||||
const [permissions, setPermissions] =
|
||||
|
|
|
@ -21,8 +21,7 @@ import {
|
|||
TextAreaControl,
|
||||
TextControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -46,6 +45,8 @@ type FormFields = PolicyRepresentation & {
|
|||
};
|
||||
|
||||
export default function PermissionDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const form = useForm<FormFields>({
|
||||
|
|
|
@ -26,8 +26,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
@ -73,6 +72,8 @@ export const AuthorizationPermissions = ({
|
|||
clientId,
|
||||
isDisabled = false,
|
||||
}: PermissionsProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -20,8 +20,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
@ -66,6 +65,8 @@ export const AuthorizationPolicies = ({
|
|||
clientId,
|
||||
isDisabled = false,
|
||||
}: PoliciesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -16,23 +16,23 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
|
||||
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
|
||||
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { useParams } from "../../utils/useParams";
|
||||
import { toAuthorizationTab } from "../routes/AuthenticationTab";
|
||||
import { ResourceDetailsParams, toResourceDetails } from "../routes/Resource";
|
||||
import { ScopePicker } from "./ScopePicker";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
import "./resource-details.css";
|
||||
|
||||
type SubmittedResource = Omit<
|
||||
|
@ -43,6 +43,8 @@ type SubmittedResource = Omit<
|
|||
};
|
||||
|
||||
export default function ResourceDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [client, setClient] = useState<ClientRepresentation>();
|
||||
const [resource, setResource] = useState<ResourceRepresentation>();
|
||||
|
|
|
@ -19,8 +19,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
@ -54,6 +53,8 @@ export const AuthorizationResources = ({
|
|||
clientId,
|
||||
isDisabled = false,
|
||||
}: ResourcesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import PolicyProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyProviderRepresentation";
|
||||
import type PolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation";
|
||||
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
||||
import type {
|
||||
|
@ -17,18 +18,16 @@ import {
|
|||
useFormContext,
|
||||
} from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { toPolicyDetails } from "../routes/PolicyDetails";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { toCreatePolicy } from "../routes/NewPolicy";
|
||||
import { NewPolicyDialog } from "./NewPolicyDialog";
|
||||
import useToggle from "../../utils/useToggle";
|
||||
import PolicyProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyProviderRepresentation";
|
||||
import { toCreatePolicy } from "../routes/NewPolicy";
|
||||
import { toPolicyDetails } from "../routes/PolicyDetails";
|
||||
import { toResourceDetails } from "../routes/Resource";
|
||||
import { NewPolicyDialog } from "./NewPolicyDialog";
|
||||
|
||||
type Type = "resources" | "policies";
|
||||
|
||||
|
@ -76,6 +75,8 @@ export const ResourcesPolicySelect = ({
|
|||
preSelected,
|
||||
isRequired = false,
|
||||
}: ResourcesPolicySelectProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { realm } = useRealm();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -12,7 +12,7 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
|
@ -26,6 +26,8 @@ import { DeleteScopeDialog } from "./DeleteScopeDialog";
|
|||
type FormFields = Omit<ScopeRepresentation, "resources">;
|
||||
|
||||
export default function ScopeDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { id, scopeId, realm } = useParams<ScopeDetailsParams>();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -9,8 +9,7 @@ import { useState } from "react";
|
|||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
|
||||
type Scope = {
|
||||
|
@ -19,6 +18,8 @@ type Scope = {
|
|||
};
|
||||
|
||||
export const ScopePicker = ({ clientId }: { clientId: string }) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { control } = useFormContext();
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@ import {
|
|||
import { useRef, useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
|
||||
type ScopeSelectProps = {
|
||||
|
@ -22,6 +21,8 @@ export const ScopeSelect = ({
|
|||
resourceId,
|
||||
preSelected,
|
||||
}: ScopeSelectProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
|
|
|
@ -18,8 +18,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
||||
import { PaginatingTableToolbar } from "../../components/table-toolbar/PaginatingTableToolbar";
|
||||
|
@ -53,6 +52,8 @@ export const AuthorizationScopes = ({
|
|||
clientId,
|
||||
isDisabled = false,
|
||||
}: ScopesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -11,7 +11,7 @@ import { useState } from "react";
|
|||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FixedButtonsGroup } from "../../components/form/FixedButtonGroup";
|
||||
|
@ -35,6 +35,8 @@ export type FormFields = Omit<
|
|||
>;
|
||||
|
||||
export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [resource, setResource] = useState<ResourceServerRepresentation>();
|
||||
const [importDialog, toggleImportDialog] = useToggle();
|
||||
|
|
|
@ -6,8 +6,7 @@ import { useState } from "react";
|
|||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
import { useFetch } from "../../../utils/useFetch";
|
||||
import useLocaleSort, { mapByKey } from "../../../utils/useLocaleSort";
|
||||
import { AddScopeDialog } from "../../scopes/AddScopeDialog";
|
||||
|
@ -18,6 +17,8 @@ export type RequiredIdValue = {
|
|||
};
|
||||
|
||||
export const ClientScope = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
|
||||
import {
|
||||
FormErrorText,
|
||||
HelpItem,
|
||||
TextControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
import { Button, Checkbox, FormGroup } from "@patternfly/react-core";
|
||||
import { MinusCircleIcon } from "@patternfly/react-icons";
|
||||
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
FormErrorText,
|
||||
HelpItem,
|
||||
TextControl,
|
||||
} from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
import { GroupPickerDialog } from "../../../components/group/GroupPickerDialog";
|
||||
import { useFetch } from "../../../utils/useFetch";
|
||||
|
||||
|
@ -26,6 +25,8 @@ export type GroupValue = {
|
|||
};
|
||||
|
||||
export const Group = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -11,8 +11,7 @@ import { useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
import { useAlerts } from "../../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../../components/form/FormAccess";
|
||||
|
@ -62,6 +61,8 @@ const COMPONENTS: {
|
|||
export const isValidComponentType = (value: string) => value in COMPONENTS;
|
||||
|
||||
export default function PolicyDetails() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { id, realm, policyId, policyType } = useParams<PolicyDetailsParams>();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -5,8 +5,7 @@ import { useState } from "react";
|
|||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../../admin-client";
|
||||
import { useAdminClient } from "../../../admin-client";
|
||||
import { DefaultSwitchControl } from "../../../components/SwitchControl";
|
||||
import { AddRoleMappingModal } from "../../../components/role-mapping/AddRoleMappingModal";
|
||||
import { Row, ServiceRole } from "../../../components/role-mapping/RoleMapping";
|
||||
|
@ -14,6 +13,8 @@ import { useFetch } from "../../../utils/useFetch";
|
|||
import type { RequiredIdValue } from "./ClientScope";
|
||||
|
||||
export const Role = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -4,15 +4,15 @@ import {
|
|||
Button,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
InputGroupItem,
|
||||
Split,
|
||||
SplitItem,
|
||||
InputGroupItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { PasswordInput } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
|
@ -89,6 +89,8 @@ const ExpireDateFormatter = ({ time }: { time: number }) => {
|
|||
};
|
||||
|
||||
export const ClientSecret = ({ client, secret, toggle }: ClientSecretProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import { useState } from "react";
|
|||
import { useFormContext, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -40,6 +40,8 @@ export type CredentialsProps = {
|
|||
};
|
||||
|
||||
export const Credentials = ({ client, save, refresh }: CredentialsProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const clientId = client.id!;
|
||||
|
|
|
@ -12,8 +12,7 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { FileUploadForm } from "../../components/json-file-upload/FileUploadForm";
|
||||
|
@ -34,6 +33,8 @@ import { toClients } from "../routes/Clients";
|
|||
const isXml = (text: string) => text.match(/(<.[^(><.)]+>)/g);
|
||||
|
||||
export default function ImportForm() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { FormProvider, useForm } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { NumberControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";
|
||||
|
@ -20,6 +20,8 @@ import { toClients } from "../routes/Clients";
|
|||
import { AccessTokenDialog } from "./AccessTokenDialog";
|
||||
|
||||
export default function CreateInitialAccessToken() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm({ mode: "onChange" });
|
||||
const {
|
||||
|
|
|
@ -4,8 +4,7 @@ import { wrappable } from "@patternfly/react-table";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
||||
|
@ -18,6 +17,8 @@ import useFormatDate, { FORMAT_DATE_AND_TIME } from "../../utils/useFormatDate";
|
|||
import { toCreateInitialAccessToken } from "../routes/CreateInitialAccessToken";
|
||||
|
||||
export const InitialAccessTokenList = () => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
|
|
@ -3,8 +3,7 @@ import { Button, Form, Modal } from "@patternfly/react-core";
|
|||
import { saveAs } from "file-saver";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { KeyForm, getFileExtension } from "./GenerateKeyDialog";
|
||||
|
@ -21,6 +20,8 @@ export const ExportSamlKeyDialog = ({
|
|||
close,
|
||||
keyType,
|
||||
}: ExportSamlKeyDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { realm } = useRealm();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import { useState } from "react";
|
|||
import { useFormContext, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -38,6 +38,8 @@ type KeysProps = {
|
|||
const attr = "jwt.credential";
|
||||
|
||||
export const Keys = ({ clientId, save, hasConfigureAccess }: KeysProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
control,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AlertVariant } from "@patternfly/react-core";
|
||||
import { FormProvider, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { ConfirmDialogModal } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { KeyForm } from "./GenerateKeyDialog";
|
||||
|
@ -19,6 +19,8 @@ export const SamlImportKeyDialog = ({
|
|||
attr,
|
||||
onClose,
|
||||
}: SamlImportKeyDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext<SamlKeysDialogForm>();
|
||||
const { handleSubmit } = form;
|
||||
|
@ -26,7 +28,7 @@ export const SamlImportKeyDialog = ({
|
|||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
const submit = (form: SamlKeysDialogForm) => {
|
||||
submitForm(form, id, attr, (error) => {
|
||||
submitForm(adminClient, form, id, attr, (error) => {
|
||||
if (error) {
|
||||
addError("importError", error);
|
||||
} else {
|
||||
|
|
|
@ -17,7 +17,7 @@ import { Fragment, useState } from "react";
|
|||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormPanel, HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
|
@ -154,6 +154,8 @@ const KeySection = ({
|
|||
};
|
||||
|
||||
export const SamlKeys = ({ clientId, save }: SamlKeysProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [isChanged, setIsChanged] = useState<KeyTypes>();
|
||||
const [keyInfo, setKeyInfo] = useState<CertificateRepresentation[]>();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import type CertificateRepresentation from "@keycloak/keycloak-admin-client/lib/defs/certificateRepresentation";
|
||||
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
|
||||
import {
|
||||
|
@ -22,8 +23,7 @@ import { useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { Certificate } from "./Certificate";
|
||||
import { KeyForm } from "./GenerateKeyDialog";
|
||||
|
@ -41,6 +41,7 @@ export type SamlKeysDialogForm = KeyStoreConfig & {
|
|||
};
|
||||
|
||||
export const submitForm = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
form: SamlKeysDialogForm,
|
||||
id: string,
|
||||
attr: KeyTypes,
|
||||
|
@ -70,6 +71,8 @@ export const SamlKeysDialog = ({
|
|||
onClose,
|
||||
onCancel,
|
||||
}: SamlKeysDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [type, setType] = useState(false);
|
||||
const [keys, setKeys] = useState<CertificateRepresentation>();
|
||||
|
@ -82,7 +85,7 @@ export const SamlKeysDialog = ({
|
|||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
const submit = (form: SamlKeysDialogForm) => {
|
||||
submitForm(form, id, attr, (error) => {
|
||||
submitForm(adminClient, form, id, attr, (error) => {
|
||||
if (error) {
|
||||
addError("importError", error);
|
||||
} else {
|
||||
|
|
|
@ -3,8 +3,7 @@ import { Button, ButtonVariant, ToolbarItem } from "@patternfly/react-core";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import {
|
||||
|
@ -44,6 +43,8 @@ const DetailLink = (comp: ComponentRepresentation) => {
|
|||
export const ClientRegistrationList = ({
|
||||
subType,
|
||||
}: ClientRegistrationListProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { subTab } = useParams<ClientRegistrationParams>();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -12,7 +12,7 @@ import { FormProvider, useForm, useWatch } from "react-hook-form";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
|
||||
|
@ -29,6 +29,8 @@ import {
|
|||
import { toClientRegistration } from "../routes/ClientRegistration";
|
||||
|
||||
export default function DetailProvider() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { id, providerId, subTab } = useParams<RegistrationProviderParams>();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -3,8 +3,7 @@ import { AlertVariant } from "@patternfly/react-core";
|
|||
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { AttributeForm } from "../../components/key-value-form/AttributeForm";
|
||||
import { RoleForm } from "../../components/role-form/RoleForm";
|
||||
|
@ -14,6 +13,8 @@ import { toClientRole } from "../routes/ClientRole";
|
|||
import { NewRoleParams } from "../routes/NewRole";
|
||||
|
||||
export default function CreateClientRole() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const form = useForm<AttributeForm>({ mode: "onChange" });
|
||||
const navigate = useNavigate();
|
||||
|
|
|
@ -13,8 +13,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { ChangeTypeDropdown } from "../../client-scopes/ChangeTypeDropdown";
|
||||
import {
|
||||
SearchDropdown,
|
||||
|
@ -73,6 +72,8 @@ const TypeSelector = ({
|
|||
fineGrainedAccess,
|
||||
...scope
|
||||
}: TypeSelectorProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
@ -89,6 +90,7 @@ const TypeSelector = ({
|
|||
onSelect={async (value) => {
|
||||
try {
|
||||
await changeClientScope(
|
||||
adminClient,
|
||||
clientId,
|
||||
scope,
|
||||
scope.type,
|
||||
|
@ -110,6 +112,8 @@ export const ClientScopes = ({
|
|||
clientName,
|
||||
fineGrainedAccess,
|
||||
}: ClientScopesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
@ -205,6 +209,7 @@ export const ClientScopes = ({
|
|||
onConfirm: async () => {
|
||||
try {
|
||||
await removeClientScope(
|
||||
adminClient,
|
||||
clientId,
|
||||
selectedRows[0],
|
||||
selectedRows[0].type as ClientScope,
|
||||
|
@ -230,7 +235,12 @@ export const ClientScopes = ({
|
|||
await Promise.all(
|
||||
scopes.map(
|
||||
async (scope) =>
|
||||
await addClientScope(clientId, scope.scope, scope.type!),
|
||||
await addClientScope(
|
||||
adminClient,
|
||||
clientId,
|
||||
scope.scope,
|
||||
scope.type!,
|
||||
),
|
||||
),
|
||||
);
|
||||
addAlert(t("clientScopeSuccess"), AlertVariant.success);
|
||||
|
@ -301,6 +311,7 @@ export const ClientScopes = ({
|
|||
await Promise.all(
|
||||
selectedRows.map((row) =>
|
||||
removeClientScope(
|
||||
adminClient,
|
||||
clientId,
|
||||
{ ...row },
|
||||
row.type as ClientScope,
|
||||
|
|
|
@ -9,12 +9,10 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { RoleMapping, Row } from "../../components/role-mapping/RoleMapping";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
|
||||
|
@ -25,6 +23,8 @@ type DedicatedScopeProps = {
|
|||
export const DedicatedScope = ({
|
||||
client: initialClient,
|
||||
}: DedicatedScopeProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
|
||||
|
|
|
@ -10,8 +10,7 @@ import {
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { MapperList } from "../../client-scopes/details/MapperList";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
@ -31,6 +30,8 @@ import { toMapper } from "../routes/Mapper";
|
|||
import { DedicatedScope } from "./DedicatedScope";
|
||||
|
||||
export default function DedicatedScopes() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm, clientId } = useParams<DedicatedScopeDetailsParams>();
|
||||
|
|
|
@ -28,16 +28,15 @@ import { useEffect, useRef, useState } from "react";
|
|||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem, useHelp } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||
import { UserSelect } from "../../components/users/UserSelect";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { prettyPrintJSON } from "../../util";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { GeneratedCodeTab } from "./GeneratedCodeTab";
|
||||
import { useAccess } from "../../context/access/Access";
|
||||
|
||||
import "./evaluate.css";
|
||||
|
||||
|
@ -116,6 +115,8 @@ const EffectiveRoles = ({
|
|||
};
|
||||
|
||||
export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const prefix = "openid";
|
||||
const { t } = useTranslation();
|
||||
const { enabled } = useHelp();
|
||||
|
|
|
@ -6,8 +6,7 @@ import { InfoCircleIcon } from "@patternfly/react-icons";
|
|||
import { useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { RoleMapping, Row } from "../../components/role-mapping/RoleMapping";
|
||||
|
@ -23,6 +22,8 @@ type ServiceAccountProps = {
|
|||
};
|
||||
|
||||
export const ServiceAccount = ({ client }: ServiceAccountProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation";
|
||||
|
||||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import {
|
||||
DropdownItem,
|
||||
Select,
|
||||
|
@ -9,8 +10,6 @@ import {
|
|||
import type { TFunction } from "i18next";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { toUpperCase } from "../../util";
|
||||
|
||||
export enum ClientScope {
|
||||
|
@ -96,23 +95,25 @@ export type ClientScopeDefaultOptionalType = ClientScopeRepresentation & {
|
|||
};
|
||||
|
||||
export const changeScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientScope: ClientScopeDefaultOptionalType,
|
||||
changeTo: AllClientScopeType,
|
||||
) => {
|
||||
await removeScope(clientScope);
|
||||
await addScope(clientScope, changeTo);
|
||||
await removeScope(adminClient, clientScope);
|
||||
await addScope(adminClient, clientScope, changeTo);
|
||||
};
|
||||
|
||||
const castAdminClient = () =>
|
||||
const castAdminClient = (adminClient: KeycloakAdminClient) =>
|
||||
adminClient.clientScopes as unknown as {
|
||||
[index: string]: Function;
|
||||
};
|
||||
|
||||
export const removeScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientScope: ClientScopeDefaultOptionalType,
|
||||
) => {
|
||||
if (clientScope.type !== AllClientScopes.none)
|
||||
await castAdminClient()[
|
||||
await castAdminClient(adminClient)[
|
||||
`delDefault${
|
||||
clientScope.type === ClientScope.optional ? "Optional" : ""
|
||||
}ClientScope`
|
||||
|
@ -122,11 +123,12 @@ export const removeScope = async (
|
|||
};
|
||||
|
||||
const addScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientScope: ClientScopeDefaultOptionalType,
|
||||
type: AllClientScopeType,
|
||||
) => {
|
||||
if (type !== AllClientScopes.none)
|
||||
await castAdminClient()[
|
||||
await castAdminClient(adminClient)[
|
||||
`addDefault${type === ClientScope.optional ? "Optional" : ""}ClientScope`
|
||||
]({
|
||||
id: clientScope.id!,
|
||||
|
@ -134,18 +136,20 @@ const addScope = async (
|
|||
};
|
||||
|
||||
export const changeClientScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientId: string,
|
||||
clientScope: ClientScopeRepresentation,
|
||||
type: AllClientScopeType,
|
||||
changeTo: ClientScopeType,
|
||||
) => {
|
||||
if (type !== "none") {
|
||||
await removeClientScope(clientId, clientScope, type);
|
||||
await removeClientScope(adminClient, clientId, clientScope, type);
|
||||
}
|
||||
await addClientScope(clientId, clientScope, changeTo);
|
||||
await addClientScope(adminClient, clientId, clientScope, changeTo);
|
||||
};
|
||||
|
||||
export const removeClientScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientId: string,
|
||||
clientScope: ClientScopeRepresentation,
|
||||
type: ClientScope,
|
||||
|
@ -159,6 +163,7 @@ export const removeClientScope = async (
|
|||
};
|
||||
|
||||
export const addClientScope = async (
|
||||
adminClient: KeycloakAdminClient,
|
||||
clientId: string,
|
||||
clientScope: ClientScopeRepresentation,
|
||||
type: ClientScopeType,
|
||||
|
|
|
@ -4,8 +4,7 @@ import { SelectProps, SelectVariant } from "@patternfly/react-core/deprecated";
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import type { ComponentProps } from "../dynamic/components";
|
||||
|
||||
|
@ -20,6 +19,8 @@ export const ClientSelect = ({
|
|||
required = false,
|
||||
variant = SelectVariant.typeahead,
|
||||
}: ClientSelectProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [clients, setClients] = useState<ClientRepresentation[]>([]);
|
||||
|
|
|
@ -16,8 +16,7 @@ import { saveAs } from "file-saver";
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem, useHelp } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { addTrailingSlash, prettyPrintJSON } from "../../util";
|
||||
|
@ -38,6 +37,8 @@ export const DownloadDialog = ({
|
|||
toggleDialog,
|
||||
protocol = "openid-connect",
|
||||
}: DownloadDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { realm } = useRealm();
|
||||
const { t } = useTranslation();
|
||||
const { enabled } = useHelp();
|
||||
|
|
|
@ -4,8 +4,7 @@ import { useState } from "react";
|
|||
import { useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { KeySelect } from "../key-value-form/KeySelect";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
@ -17,6 +16,8 @@ export const UserProfileAttributeListComponent = ({
|
|||
helpText,
|
||||
required = false,
|
||||
}: ComponentProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
formState: { errors },
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
import { AngleRightIcon } from "@patternfly/react-icons";
|
||||
import { Fragment, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { useFetch } from "../../utils/useFetch";
|
||||
import { ListEmptyState } from "../list-empty-state/ListEmptyState";
|
||||
import { PaginatingTableToolbar } from "../table-toolbar/PaginatingTableToolbar";
|
||||
|
@ -53,6 +53,8 @@ export const GroupPickerDialog = ({
|
|||
onClose,
|
||||
onConfirm,
|
||||
}: GroupPickerDialogProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const [selectedRows, setSelectedRows] = useState<SelectableGroup[]>([]);
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@ import { useState } from "react";
|
|||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAdminClient } from "../../admin-client";
|
||||
import { toPermissionDetails } from "../../clients/routes/PermissionDetails";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
|
@ -45,6 +44,8 @@ type PermissionsTabProps = {
|
|||
};
|
||||
|
||||
export const PermissionsTab = ({ id, type }: PermissionsTabProps) => {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const { realm } = useRealm();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue