Use new routing conventions for client routes (#888)

This commit is contained in:
Jon Koops 2021-07-21 17:08:40 +02:00 committed by GitHub
parent 242e6f7b98
commit 1860ea5b58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 243 additions and 149 deletions

View file

@ -7,9 +7,9 @@ export default class ListingPage {
private searchBtn =
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-control:visible";
private createBtn =
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-primary:visible";
".pf-c-page__main .pf-c-toolbar__content-section .pf-m-primary:visible";
private importBtn =
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-link";
".pf-c-page__main .pf-c-toolbar__content-section .pf-m-link";
goToCreateItem() {
cy.get(this.createBtn).click();

View file

@ -1,8 +1,3 @@
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
import { Controller, useFormContext } from "react-hook-form";
import moment from "moment";
import {
ActionGroup,
AlertVariant,
@ -17,27 +12,32 @@ import {
TextInput,
ToolbarItem,
} from "@patternfly/react-core";
import type GlobalRequestResult from "keycloak-admin/lib/defs/globalRequestResult";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import { convertToFormValues, toUpperCase } from "../util";
import { FormAccess } from "../components/form-access/FormAccess";
import { ScrollForm } from "../components/scroll-form/ScrollForm";
import { HelpItem } from "../components/help-enabler/HelpItem";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
import { FineGrainOpenIdConnect } from "./advanced/FineGrainOpenIdConnect";
import { OpenIdConnectCompatibilityModes } from "./advanced/OpenIdConnectCompatibilityModes";
import { AdvancedSettings } from "./advanced/AdvancedSettings";
import { TimeSelector } from "../components/time-selector/TimeSelector";
import { useAdminClient } from "../context/auth/AdminClient";
import type GlobalRequestResult from "keycloak-admin/lib/defs/globalRequestResult";
import moment from "moment";
import React, { useEffect, useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { Trans, useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { AddHostDialog } from "./advanced/AddHostDialog";
import { FineGrainSamlEndpointConfig } from "./advanced/FineGrainSamlEndpointConfig";
import { AuthenticationOverrides } from "./advanced/AuthenticationOverrides";
import { useRealm } from "../context/realm-context/RealmContext";
import type { SaveOptions } from "./ClientDetails";
import { FormAccess } from "../components/form-access/FormAccess";
import { HelpItem } from "../components/help-enabler/HelpItem";
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
import { ScrollForm } from "../components/scroll-form/ScrollForm";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
import { TimeSelector } from "../components/time-selector/TimeSelector";
import { useAdminClient } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import { convertToFormValues, toUpperCase } from "../util";
import { AddHostDialog } from "./advanced/AddHostDialog";
import { AdvancedSettings } from "./advanced/AdvancedSettings";
import { AuthenticationOverrides } from "./advanced/AuthenticationOverrides";
import { FineGrainOpenIdConnect } from "./advanced/FineGrainOpenIdConnect";
import { FineGrainSamlEndpointConfig } from "./advanced/FineGrainSamlEndpointConfig";
import { OpenIdConnectCompatibilityModes } from "./advanced/OpenIdConnectCompatibilityModes";
import type { SaveOptions } from "./ClientDetails";
import { toClient } from "./routes/Client";
type AdvancedProps = {
save: (options?: SaveOptions) => void;
@ -184,7 +184,7 @@ export const AdvancedTab = ({
<Text className="pf-u-pb-lg">
<Trans i18nKey="clients-help:notBeforeIntro">
In order to successfully push setup url on
<Link to={`/${realm}/clients/${id}/settings`}>
<Link to={toClient({ realm, clientId: id!, tab: "settings" })}>
{t("settings")}
</Link>
tab

View file

@ -1,4 +1,3 @@
import React, { useState } from "react";
import {
Alert,
AlertVariant,
@ -11,40 +10,42 @@ import {
Tabs,
TabTitleText,
} from "@patternfly/react-core";
import { useHistory, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import _ from "lodash";
import { ClientSettings } from "./ClientSettings";
import React, { useState } from "react";
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useHistory, useParams } from "react-router-dom";
import { useAlerts } from "../components/alert/Alerts";
import {
ConfirmDialogModal,
useConfirmDialog,
} from "../components/confirm-dialog/ConfirmDialog";
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { Credentials } from "./credentials/Credentials";
import {
convertFormValuesToObject,
convertToFormValues,
exportClient,
} from "../util";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import {
convertToMultiline,
MultiLine,
toValue,
} from "../components/multi-line-input/MultiLineInput";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import { RolesList } from "../realm-roles/RolesList";
import {
convertFormValuesToObject,
convertToFormValues,
exportClient,
} from "../util";
import { AdvancedTab } from "./AdvancedTab";
import { ClientSettings } from "./ClientSettings";
import { Credentials } from "./credentials/Credentials";
import { Keys } from "./keys/Keys";
import type { ClientParams } from "./routes/Client";
import { toClients } from "./routes/Clients";
import { ClientScopes } from "./scopes/ClientScopes";
import { EvaluateScopes } from "./scopes/EvaluateScopes";
import { RolesList } from "../realm-roles/RolesList";
import { ServiceAccount } from "./service-account/ServiceAccount";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import { AdvancedTab } from "./AdvancedTab";
import { useRealm } from "../context/realm-context/RealmContext";
import { Keys } from "./keys/Keys";
type ClientDetailHeaderProps = {
onChange: (value: boolean) => void;
@ -137,7 +138,7 @@ export const ClientDetails = () => {
const [activeTab2, setActiveTab2] = useState(30);
const form = useForm<ClientForm>();
const { clientId } = useParams<{ clientId: string }>();
const { clientId } = useParams<ClientParams>();
const clientAuthenticatorType = useWatch({
control: form.control,
@ -161,7 +162,7 @@ export const ClientDetails = () => {
try {
await adminClient.clients.del({ id: clientId });
addAlert(t("clientDeletedSuccess"), AlertVariant.success);
history.push(`/${realm}/clients`);
history.push(toClients({ realm }));
} catch (error) {
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
}

View file

@ -1,34 +1,35 @@
import React, { useState } from "react";
import { Link, useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
AlertVariant,
Badge,
Button,
ButtonVariant,
PageSection,
ToolbarItem,
Tab,
TabTitleText,
ToolbarItem,
} from "@patternfly/react-core";
import { cellWidth, TableText } from "@patternfly/react-table";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import { emptyFormatter, exportClient, getBaseUrl } from "../util";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { formattedLinkTableCell } from "../components/external-link/FormattedLink";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAdminClient } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import { emptyFormatter, exportClient, getBaseUrl } from "../util";
import { InitialAccessTokenList } from "./initial-access/InitialAccessTokenList";
import { cellWidth, TableText } from "@patternfly/react-table";
import { toAddClient } from "./routes/AddClient";
import { toClient } from "./routes/Client";
import { toImportClient } from "./routes/ImportClient";
export const ClientsSection = () => {
const { t } = useTranslation("clients");
const { addAlert } = useAlerts();
const history = useHistory();
const adminClient = useAdminClient();
const { realm } = useRealm();
@ -70,7 +71,10 @@ export const ClientsSection = () => {
const ClientDetailLink = (client: ClientRepresentation) => (
<>
<Link key={client.id} to={`/${realm}/clients/${client.id}/settings`}>
<Link
key={client.id}
to={toClient({ realm, clientId: client.id!, tab: "settings" })}
>
{client.clientId}
{!client.enabled && (
<Badge key={`${client.id}-disabled`} isRead className="pf-u-ml-sm">
@ -114,19 +118,16 @@ export const ClientsSection = () => {
toolbarItem={
<>
<ToolbarItem>
<Button
onClick={() =>
history.push(`/${realm}/clients/add-client`)
}
>
{/* @ts-ignore */}
<Button component={Link} to={toAddClient({ realm })}>
{t("createClient")}
</Button>
</ToolbarItem>
<ToolbarItem>
<Button
onClick={() =>
history.push(`/${realm}/clients/import-client`)
}
component={Link}
// @ts-ignore
to={toImportClient({ realm })}
variant="link"
>
{t("importClient")}

View file

@ -1,23 +1,24 @@
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import {
AlertVariant,
Button,
PageSection,
Wizard,
AlertVariant,
WizardFooter,
WizardContextConsumer,
Button,
WizardFooter,
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import React, { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { GeneralSettings } from "./GeneralSettings";
import { CapabilityConfig } from "./CapabilityConfig";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { useAlerts } from "../../components/alert/Alerts";
import { ViewHeader } from "../../components/view-header/ViewHeader";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import { useAdminClient } from "../../context/auth/AdminClient";
import { useRealm } from "../../context/realm-context/RealmContext";
import { toClient } from "../routes/Client";
import { toClients } from "../routes/Clients";
import { CapabilityConfig } from "./CapabilityConfig";
import { GeneralSettings } from "./GeneralSettings";
export const NewClientForm = () => {
const { t } = useTranslation("clients");
@ -45,7 +46,9 @@ export const NewClientForm = () => {
try {
const newClient = await adminClient.clients.create({ ...client });
addAlert(t("createSuccess"), AlertVariant.success);
history.push(`/${realm}/clients/${newClient.id}/settings`);
history.push(
toClient({ realm, clientId: newClient.id, tab: "settings" })
);
} catch (error) {
addAlert(t("createError", { error }), AlertVariant.danger);
}
@ -119,7 +122,7 @@ export const NewClientForm = () => {
<PageSection variant="light">
<FormProvider {...methods}>
<Wizard
onClose={() => history.push(`/${realm}/clients`)}
onClose={() => history.push(toClients({ realm }))}
navAriaLabel={`${title} steps`}
mainAriaLabel={`${title} content`}
steps={[

View file

@ -1,26 +1,27 @@
import React from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
PageSection,
FormGroup,
TextInput,
ActionGroup,
Button,
AlertVariant,
Button,
FormGroup,
PageSection,
TextInput,
} from "@patternfly/react-core";
import { FormProvider, useForm } from "react-hook-form";
import { ClientDescription } from "../ClientDescription";
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
import { useAlerts } from "../../components/alert/Alerts";
import { ViewHeader } from "../../components/view-header/ViewHeader";
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
import { useAdminClient } from "../../context/auth/AdminClient";
import React from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useHistory } from "react-router-dom";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form-access/FormAccess";
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
import { ViewHeader } from "../../components/view-header/ViewHeader";
import { useAdminClient } from "../../context/auth/AdminClient";
import { useRealm } from "../../context/realm-context/RealmContext";
import { convertFormValuesToObject, convertToFormValues } from "../../util";
import { CapabilityConfig } from "../add/CapabilityConfig";
import { ClientDescription } from "../ClientDescription";
import { toClient } from "../routes/Client";
import { toClients } from "../routes/Clients";
export const ImportForm = () => {
const { t } = useTranslation("clients");
@ -56,7 +57,9 @@ export const ImportForm = () => {
attributes: convertFormValuesToObject(client.attributes || {}),
});
addAlert(t("clientImportSuccess"), AlertVariant.success);
history.push(`/${realm}/clients/${newClient.id}`);
history.push(
toClient({ realm, clientId: newClient.id, tab: "settings" })
);
} catch (error) {
addAlert(t("clientImportError", { error }), AlertVariant.danger);
}
@ -91,10 +94,8 @@ export const ImportForm = () => {
<Button variant="primary" type="submit">
{t("common:save")}
</Button>
<Button
variant="link"
onClick={() => history.push(`/${realm}/clients`)}
>
{/* @ts-ignore */}
<Button variant="link" component={Link} to={toClients({ realm })}>
{t("common:cancel")}
</Button>
</ActionGroup>

View file

@ -15,11 +15,12 @@ import { FormAccess } from "../../components/form-access/FormAccess";
import { ViewHeader } from "../../components/view-header/ViewHeader";
import { HelpItem } from "../../components/help-enabler/HelpItem";
import { TimeSelector } from "../../components/time-selector/TimeSelector";
import { useHistory } from "react-router-dom";
import { Link, useHistory } from "react-router-dom";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useAdminClient } from "../../context/auth/AdminClient";
import { useAlerts } from "../../components/alert/Alerts";
import { AccessTokenDialog } from "./AccessTokenDialog";
import { toClients } from "../routes/Clients";
export const CreateInitialAccessToken = () => {
const { t } = useTranslation("clients");
@ -52,7 +53,7 @@ export const CreateInitialAccessToken = () => {
toggleDialog={() => {
setToken("");
addAlert(t("tokenSaveSuccess"), AlertVariant.success);
history.push(`/${realm}/clients/initialAccessToken`);
history.push(toClients({ realm, tab: "initialAccessToken" }));
}}
/>
)}
@ -129,9 +130,9 @@ export const CreateInitialAccessToken = () => {
<Button
data-testid="cancel"
variant="link"
onClick={() =>
history.push(`/${realm}/clients/initialAccessToken`)
}
component={Link}
// @ts-ignore
to={toClients({ realm, tab: "initialAccessToken" })}
>
{t("common:cancel")}
</Button>

View file

@ -1,17 +1,17 @@
import React, { useState } from "react";
import { useHistory, useRouteMatch } from "react-router-dom";
import moment from "moment";
import { useTranslation } from "react-i18next";
import { AlertVariant, Button, ButtonVariant } from "@patternfly/react-core";
import { wrappable } from "@patternfly/react-table";
import type ClientInitialAccessPresentation from "keycloak-admin/lib/defs/clientInitialAccessPresentation";
import moment from "moment";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useHistory } from "react-router-dom";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
import { useAdminClient } from "../../context/auth/AdminClient";
import { useRealm } from "../../context/realm-context/RealmContext";
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { useAlerts } from "../../components/alert/Alerts";
import { toCreateInitialAccessToken } from "../routes/CreateInitialAccessToken";
export const InitialAccessTokenList = () => {
const { t } = useTranslation("clients");
@ -21,7 +21,6 @@ export const InitialAccessTokenList = () => {
const { realm } = useRealm();
const history = useHistory();
const { url } = useRouteMatch();
const [token, setToken] = useState<ClientInitialAccessPresentation>();
@ -57,7 +56,8 @@ export const InitialAccessTokenList = () => {
loader={loader}
toolbarItem={
<>
<Button onClick={() => history.push(`${url}/create`)}>
{/* @ts-ignore */}
<Button component={Link} to={toCreateInitialAccessToken({ realm })}>
{t("common:create")}
</Button>
</>
@ -104,7 +104,9 @@ export const InitialAccessTokenList = () => {
message={t("noTokens")}
instructions={t("noTokensInstructions")}
primaryActionText={t("common:create")}
onPrimaryAction={() => history.push(`${url}/create`)}
onPrimaryAction={() =>
history.push(toCreateInitialAccessToken({ realm }))
}
/>
}
/>

16
src/clients/routes.ts Normal file
View file

@ -0,0 +1,16 @@
import type { RouteDef } from "../route-config";
import { AddClientRoute } from "./routes/AddClient";
import { ClientRoute } from "./routes/Client";
import { ClientsRoute } from "./routes/Clients";
import { CreateInitialAccessTokenRoute } from "./routes/CreateInitialAccessToken";
import { ImportClientRoute } from "./routes/ImportClient";
const routes: RouteDef[] = [
AddClientRoute,
ImportClientRoute,
ClientsRoute,
CreateInitialAccessTokenRoute,
ClientRoute,
];
export default routes;

View file

@ -0,0 +1,19 @@
import type { LocationDescriptorObject } from "history";
import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config";
import { NewClientForm } from "../add/NewClientForm";
export type AddClientParams = { realm: string };
export const AddClientRoute: RouteDef = {
path: "/:realm/clients/add-client",
component: NewClientForm,
breadcrumb: (t) => t("clients:createClient"),
access: "manage-clients",
};
export const toAddClient = (
params: AddClientParams
): LocationDescriptorObject => ({
pathname: generatePath(AddClientRoute.path, params),
});

View file

@ -0,0 +1,23 @@
import type { LocationDescriptorObject } from "history";
import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config";
import { ClientDetails } from "../ClientDetails";
export type ClientTab = "settings" | "roles" | "clientScopes" | "advanced";
export type ClientParams = {
realm: string;
clientId: string;
tab: ClientTab;
};
export const ClientRoute: RouteDef = {
path: "/:realm/clients/:clientId/:tab",
component: ClientDetails,
breadcrumb: (t) => t("clients:clientSettings"),
access: "view-clients",
};
export const toClient = (params: ClientParams): LocationDescriptorObject => ({
pathname: generatePath(ClientRoute.path, params),
});

View file

@ -0,0 +1,22 @@
import type { LocationDescriptorObject } from "history";
import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config";
import { ClientsSection } from "../ClientsSection";
export type ClientsTab = "list" | "initialAccessToken";
export type ClientsParams = {
realm: string;
tab?: ClientsTab;
};
export const ClientsRoute: RouteDef = {
path: "/:realm/clients/:tab?",
component: ClientsSection,
breadcrumb: (t) => t("clients:clientList"),
access: "query-clients",
};
export const toClients = (params: ClientsParams): LocationDescriptorObject => ({
pathname: generatePath(ClientsRoute.path, params),
});

View file

@ -0,0 +1,19 @@
import type { LocationDescriptorObject } from "history";
import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config";
import { CreateInitialAccessToken } from "../initial-access/CreateInitialAccessToken";
export type CreateInitialAccessTokenParams = { realm: string };
export const CreateInitialAccessTokenRoute: RouteDef = {
path: "/:realm/clients/initialAccessToken/create",
component: CreateInitialAccessToken,
breadcrumb: (t) => t("clients:createToken"),
access: "manage-clients",
};
export const toCreateInitialAccessToken = (
params: CreateInitialAccessTokenParams
): LocationDescriptorObject => ({
pathname: generatePath(CreateInitialAccessTokenRoute.path, params),
});

View file

@ -0,0 +1,19 @@
import type { LocationDescriptorObject } from "history";
import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config";
import { ImportForm } from "../import/ImportForm";
export type ImportClientParams = { realm: string };
export const ImportClientRoute: RouteDef = {
path: "/:realm/clients/import-client",
component: ImportForm,
breadcrumb: (t) => t("clients:importClient"),
access: "manage-clients",
};
export const toImportClient = (
params: ImportClientParams
): LocationDescriptorObject => ({
pathname: generatePath(ImportClientRoute.path, params),
});

View file

@ -7,11 +7,7 @@ import { RoleMappingForm } from "./client-scopes/add/RoleMappingForm";
import { ClientScopesSection } from "./client-scopes/ClientScopesSection";
import { MappingDetails } from "./client-scopes/details/MappingDetails";
import { ClientScopeForm } from "./client-scopes/form/ClientScopeForm";
import { NewClientForm } from "./clients/add/NewClientForm";
import { ClientDetails } from "./clients/ClientDetails";
import { ClientsSection } from "./clients/ClientsSection";
import { ImportForm } from "./clients/import/ImportForm";
import { CreateInitialAccessToken } from "./clients/initial-access/CreateInitialAccessToken";
import clientRoutes from "./clients/routes";
import { DashboardSection } from "./dashboard/Dashboard";
import { EventsSection } from "./events/EventsSection";
import { GroupsSection } from "./groups/GroupsSection";
@ -55,36 +51,13 @@ export type RouteDef = {
};
export const routes: RouteDef[] = [
...clientRoutes,
{
path: "/:realm/add-realm",
component: NewRealmForm,
breadcrumb: (t) => t("realm:createRealm"),
access: "manage-realm",
},
{
path: "/:realm/clients/add-client",
component: NewClientForm,
breadcrumb: (t) => t("clients:createClient"),
access: "manage-clients",
},
{
path: "/:realm/clients/import-client",
component: ImportForm,
breadcrumb: (t) => t("clients:importClient"),
access: "manage-clients",
},
{
path: "/:realm/clients/:tab?",
component: ClientsSection,
breadcrumb: (t) => t("clients:clientList"),
access: "query-clients",
},
{
path: "/:realm/clients/initialAccessToken/create",
component: CreateInitialAccessToken,
breadcrumb: (t) => t("clients:createToken"),
access: "manage-clients",
},
{
path: "/:realm/clients/:clientId/roles/add-role",
component: RealmRoleTabs,
@ -97,12 +70,6 @@ export const routes: RouteDef[] = [
breadcrumb: (t) => t("roles:roleDetails"),
access: "view-realm",
},
{
path: "/:realm/clients/:clientId/:tab",
component: ClientDetails,
breadcrumb: (t) => t("clients:clientSettings"),
access: "view-clients",
},
{
path: "/:realm/client-scopes/new",
component: ClientScopeForm,