diff --git a/src/App.tsx b/src/App.tsx
index 86c6fb1d9b..e2b7ed473e 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,10 +1,6 @@
import { FunctionComponent, Suspense } from "react";
import { Page } from "@patternfly/react-core";
-import {
- HashRouter as Router,
- Route as LegacyRoute,
- Switch,
-} from "react-router-dom";
+import { HashRouter as Router, Switch } from "react-router-dom";
import { CompatRouter, CompatRoute } from "react-router-dom-v5-compat";
import { ErrorBoundary } from "react-error-boundary";
import type Keycloak from "keycloak-js";
@@ -101,19 +97,15 @@ export const App = ({ keycloak, adminClient }: AdminClientProps) => {
>
- {routes.map((route, i) => {
- const Route = route.legacy ? LegacyRoute : CompatRoute;
-
- return (
-
-
-
- );
- })}
+ {routes.map((route, i) => (
+
+
+
+ ))}
diff --git a/src/authentication/routes.ts b/src/authentication/routes.ts
index b27870c5bd..9d2fb87541 100644
--- a/src/authentication/routes.ts
+++ b/src/authentication/routes.ts
@@ -1,8 +1,17 @@
import type { RouteDef } from "../route-config";
-import { AuthenticationRoute } from "./routes/Authentication";
+import {
+ AuthenticationRoute,
+ AuthenticationRouteWithTab,
+} from "./routes/Authentication";
import { CreateFlowRoute } from "./routes/CreateFlow";
-import { FlowRoute } from "./routes/Flow";
+import { FlowRoute, FlowWithBuiltInRoute } from "./routes/Flow";
-const routes: RouteDef[] = [AuthenticationRoute, CreateFlowRoute, FlowRoute];
+const routes: RouteDef[] = [
+ AuthenticationRoute,
+ AuthenticationRouteWithTab,
+ CreateFlowRoute,
+ FlowRoute,
+ FlowWithBuiltInRoute,
+];
export default routes;
diff --git a/src/authentication/routes/Authentication.ts b/src/authentication/routes/Authentication.ts
index ea8410e390..e870f8b988 100644
--- a/src/authentication/routes/Authentication.ts
+++ b/src/authentication/routes/Authentication.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type AuthenticationTab = "flows" | "required-actions" | "policies";
@@ -8,15 +8,25 @@ export type AuthenticationTab = "flows" | "required-actions" | "policies";
export type AuthenticationParams = { realm: string; tab?: AuthenticationTab };
export const AuthenticationRoute: RouteDef = {
- path: "/:realm/authentication/:tab?",
+ path: "/:realm/authentication",
component: lazy(() => import("../AuthenticationSection")),
breadcrumb: (t) => t("authentication"),
access: ["view-realm", "view-identity-providers", "view-clients"],
- legacy: true,
+};
+
+export const AuthenticationRouteWithTab: RouteDef = {
+ ...AuthenticationRoute,
+ path: "/:realm/authentication/:tab",
};
export const toAuthentication = (
params: AuthenticationParams
-): Partial => ({
- pathname: generatePath(AuthenticationRoute.path, params),
-});
+): Partial => {
+ const path = params.tab
+ ? AuthenticationRouteWithTab.path
+ : AuthenticationRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/authentication/routes/Flow.ts b/src/authentication/routes/Flow.ts
index 8d0f9c676e..8084498d0c 100644
--- a/src/authentication/routes/Flow.ts
+++ b/src/authentication/routes/Flow.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type FlowParams = {
@@ -11,13 +11,21 @@ export type FlowParams = {
};
export const FlowRoute: RouteDef = {
- path: "/:realm/authentication/:id/:usedBy/:builtIn?",
+ path: "/:realm/authentication/:id/:usedBy",
component: lazy(() => import("../FlowDetails")),
breadcrumb: (t) => t("authentication:flowDetails"),
access: "view-authorization",
- legacy: true,
};
-export const toFlow = (params: FlowParams): Partial => ({
- pathname: generatePath(FlowRoute.path, params),
-});
+export const FlowWithBuiltInRoute: RouteDef = {
+ ...FlowRoute,
+ path: "/:realm/authentication/:id/:usedBy/:builtIn",
+};
+
+export const toFlow = (params: FlowParams): Partial => {
+ const path = params.builtIn ? FlowWithBuiltInRoute.path : FlowRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/client-scopes/routes.ts b/src/client-scopes/routes.ts
index 45fb2bb46d..a3c0f54a78 100644
--- a/src/client-scopes/routes.ts
+++ b/src/client-scopes/routes.ts
@@ -1,5 +1,8 @@
import type { RouteDef } from "../route-config";
-import { ClientScopeRoute } from "./routes/ClientScope";
+import {
+ ClientScopeRoute,
+ ClientScopeWithTypeRoute,
+} from "./routes/ClientScope";
import { ClientScopesRoute } from "./routes/ClientScopes";
import { MapperRoute } from "./routes/Mapper";
import { NewClientScopeRoute } from "./routes/NewClientScope";
@@ -8,6 +11,7 @@ const routes: RouteDef[] = [
NewClientScopeRoute,
MapperRoute,
ClientScopeRoute,
+ ClientScopeWithTypeRoute,
ClientScopesRoute,
];
diff --git a/src/client-scopes/routes/ClientScope.ts b/src/client-scopes/routes/ClientScope.ts
index d4cba46c7a..3d8d5e1542 100644
--- a/src/client-scopes/routes/ClientScope.ts
+++ b/src/client-scopes/routes/ClientScope.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type ClientScopeTab = "settings" | "mappers" | "scope";
@@ -13,13 +13,23 @@ export type ClientScopeParams = {
};
export const ClientScopeRoute: RouteDef = {
- path: "/:realm/client-scopes/:id/:tab/:type?",
+ path: "/:realm/client-scopes/:id/:tab",
component: lazy(() => import("../form/ClientScopeForm")),
breadcrumb: (t) => t("client-scopes:clientScopeDetails"),
access: "view-clients",
- legacy: true,
};
-export const toClientScope = (params: ClientScopeParams): Partial => ({
- pathname: generatePath(ClientScopeRoute.path, params),
-});
+export const ClientScopeWithTypeRoute: RouteDef = {
+ ...ClientScopeRoute,
+ path: "/:realm/client-scopes/:id/:tab/:type",
+};
+
+export const toClientScope = (params: ClientScopeParams): Partial => {
+ const path = params.type
+ ? ClientScopeWithTypeRoute.path
+ : ClientScopeRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/clients/routes.ts b/src/clients/routes.ts
index 4bbda52dde..2995237398 100644
--- a/src/clients/routes.ts
+++ b/src/clients/routes.ts
@@ -1,39 +1,56 @@
import type { RouteDef } from "../route-config";
import { AddClientRoute } from "./routes/AddClient";
import { ClientRoute } from "./routes/Client";
-import { ClientsRoute } from "./routes/Clients";
+import { ClientsRoute, ClientsRouteWithTab } from "./routes/Clients";
import { CreateInitialAccessTokenRoute } from "./routes/CreateInitialAccessToken";
import { ImportClientRoute } from "./routes/ImportClient";
import { MapperRoute } from "./routes/Mapper";
import { ClientScopesRoute } from "./routes/ClientScopeTab";
import { AuthorizationRoute } from "./routes/AuthenticationTab";
import { NewResourceRoute } from "./routes/NewResource";
-import { ResourceDetailsRoute } from "./routes/Resource";
+import {
+ ResourceDetailsRoute,
+ ResourceDetailsWithResourceIdRoute,
+} from "./routes/Resource";
import { NewScopeRoute } from "./routes/NewScope";
-import { ScopeDetailsRoute } from "./routes/Scope";
+import {
+ ScopeDetailsRoute,
+ ScopeDetailsWithScopeIdRoute,
+} from "./routes/Scope";
import { NewPolicyRoute } from "./routes/NewPolicy";
import { PolicyDetailsRoute } from "./routes/PolicyDetails";
-import { NewPermissionRoute } from "./routes/NewPermission";
+import {
+ NewPermissionRoute,
+ NewPermissionWithSelectedIdRoute,
+} from "./routes/NewPermission";
import { PermissionDetailsRoute } from "./routes/PermissionDetails";
-import { DedicatedScopeDetailsRoute } from "./routes/DedicatedScopeDetails";
+import {
+ DedicatedScopeDetailsRoute,
+ DedicatedScopeDetailsWithTabRoute,
+} from "./routes/DedicatedScopeDetails";
const routes: RouteDef[] = [
AddClientRoute,
ImportClientRoute,
ClientsRoute,
+ ClientsRouteWithTab,
CreateInitialAccessTokenRoute,
ClientRoute,
MapperRoute,
DedicatedScopeDetailsRoute,
+ DedicatedScopeDetailsWithTabRoute,
ClientScopesRoute,
AuthorizationRoute,
NewResourceRoute,
ResourceDetailsRoute,
+ ResourceDetailsWithResourceIdRoute,
NewScopeRoute,
ScopeDetailsRoute,
+ ScopeDetailsWithScopeIdRoute,
NewPolicyRoute,
PolicyDetailsRoute,
NewPermissionRoute,
+ NewPermissionWithSelectedIdRoute,
PermissionDetailsRoute,
];
diff --git a/src/clients/routes/Clients.ts b/src/clients/routes/Clients.ts
index 8624f827de..3b3066ca25 100644
--- a/src/clients/routes/Clients.ts
+++ b/src/clients/routes/Clients.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type ClientsTab = "list" | "initial-access-token";
@@ -11,13 +11,21 @@ export type ClientsParams = {
};
export const ClientsRoute: RouteDef = {
- path: "/:realm/clients/:tab?",
+ path: "/:realm/clients",
component: lazy(() => import("../ClientsSection")),
breadcrumb: (t) => t("clients:clientList"),
access: "query-clients",
- legacy: true,
};
-export const toClients = (params: ClientsParams): Partial => ({
- pathname: generatePath(ClientsRoute.path, params),
-});
+export const ClientsRouteWithTab: RouteDef = {
+ ...ClientsRoute,
+ path: "/:realm/clients/:tab",
+};
+
+export const toClients = (params: ClientsParams): Partial => {
+ const path = params.tab ? ClientsRouteWithTab.path : ClientsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/clients/routes/DedicatedScopeDetails.ts b/src/clients/routes/DedicatedScopeDetails.ts
index 667d0b390b..39a455affe 100644
--- a/src/clients/routes/DedicatedScopeDetails.ts
+++ b/src/clients/routes/DedicatedScopeDetails.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type DedicatedScopeTab = "mappers" | "scope";
@@ -12,15 +12,25 @@ export type DedicatedScopeDetailsParams = {
};
export const DedicatedScopeDetailsRoute: RouteDef = {
- path: "/:realm/clients/:clientId/clientScopes/dedicated/:tab?",
+ path: "/:realm/clients/:clientId/clientScopes/dedicated",
component: lazy(() => import("../scopes/DedicatedScopes")),
breadcrumb: (t) => t("clients:dedicatedScopes"),
access: "view-clients",
- legacy: true,
+};
+
+export const DedicatedScopeDetailsWithTabRoute: RouteDef = {
+ ...DedicatedScopeDetailsRoute,
+ path: "/:realm/clients/:clientId/clientScopes/dedicated/:tab",
};
export const toDedicatedScope = (
params: DedicatedScopeDetailsParams
-): Partial => ({
- pathname: generatePath(DedicatedScopeDetailsRoute.path, params),
-});
+): Partial => {
+ const path = params.tab
+ ? DedicatedScopeDetailsWithTabRoute.path
+ : DedicatedScopeDetailsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/clients/routes/NewPermission.ts b/src/clients/routes/NewPermission.ts
index 4387d1ad42..34d6e74204 100644
--- a/src/clients/routes/NewPermission.ts
+++ b/src/clients/routes/NewPermission.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type PermissionType = "resource" | "scope";
@@ -13,15 +13,23 @@ export type NewPermissionParams = {
};
export const NewPermissionRoute: RouteDef = {
- path: "/:realm/clients/:id/authorization/permission/new/:permissionType/:selectedId?",
+ path: "/:realm/clients/:id/authorization/permission/new/:permissionType",
component: lazy(() => import("../authorization/PermissionDetails")),
breadcrumb: (t) => t("clients:createPermission"),
access: "view-clients",
- legacy: true,
};
-export const toNewPermission = (
- params: NewPermissionParams
-): Partial => ({
- pathname: generatePath(NewPermissionRoute.path, params),
-});
+export const NewPermissionWithSelectedIdRoute: RouteDef = {
+ ...NewPermissionRoute,
+ path: "/:realm/clients/:id/authorization/permission/new/:permissionType/:selectedId?",
+};
+
+export const toNewPermission = (params: NewPermissionParams): Partial => {
+ const path = params.selectedId
+ ? NewPermissionWithSelectedIdRoute.path
+ : NewPermissionRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/clients/routes/Resource.ts b/src/clients/routes/Resource.ts
index cb770c2e49..ea3c2601e5 100644
--- a/src/clients/routes/Resource.ts
+++ b/src/clients/routes/Resource.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type ResourceDetailsParams = {
@@ -10,15 +10,25 @@ export type ResourceDetailsParams = {
};
export const ResourceDetailsRoute: RouteDef = {
- path: "/:realm/clients/:id/authorization/resource/:resourceId?",
+ path: "/:realm/clients/:id/authorization/resource",
component: lazy(() => import("../authorization/ResourceDetails")),
breadcrumb: (t) => t("clients:createResource"),
access: "view-clients",
- legacy: true,
+};
+
+export const ResourceDetailsWithResourceIdRoute: RouteDef = {
+ ...ResourceDetailsRoute,
+ path: "/:realm/clients/:id/authorization/resource/:resourceId",
};
export const toResourceDetails = (
params: ResourceDetailsParams
-): Partial => ({
- pathname: generatePath(ResourceDetailsRoute.path, params),
-});
+): Partial => {
+ const path = params.resourceId
+ ? ResourceDetailsWithResourceIdRoute.path
+ : ResourceDetailsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/clients/routes/Scope.ts b/src/clients/routes/Scope.ts
index 7549f76204..78c3a974e6 100644
--- a/src/clients/routes/Scope.ts
+++ b/src/clients/routes/Scope.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type ScopeDetailsParams = {
@@ -10,13 +10,23 @@ export type ScopeDetailsParams = {
};
export const ScopeDetailsRoute: RouteDef = {
- path: "/:realm/clients/:id/authorization/scope/:scopeId?",
+ path: "/:realm/clients/:id/authorization/scope",
component: lazy(() => import("../authorization/ScopeDetails")),
breadcrumb: (t) => t("clients:createAuthorizationScope"),
access: "manage-clients",
- legacy: true,
};
-export const toScopeDetails = (params: ScopeDetailsParams): Partial => ({
- pathname: generatePath(ScopeDetailsRoute.path, params),
-});
+export const ScopeDetailsWithScopeIdRoute: RouteDef = {
+ ...ScopeDetailsRoute,
+ path: "/:realm/clients/:id/authorization/scope/:scopeId",
+};
+
+export const toScopeDetails = (params: ScopeDetailsParams): Partial => {
+ const path = params.scopeId
+ ? ScopeDetailsWithScopeIdRoute.path
+ : ScopeDetailsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/context/realm-context/RealmContext.tsx b/src/context/realm-context/RealmContext.tsx
index 90d91f6e2a..e85db5ec97 100644
--- a/src/context/realm-context/RealmContext.tsx
+++ b/src/context/realm-context/RealmContext.tsx
@@ -3,7 +3,7 @@ import { useRouteMatch } from "react-router-dom";
import { RecentUsed } from "../../components/realm-selector/recent-used";
import {
DashboardParams,
- DashboardRoute,
+ DashboardRouteWithRealm,
} from "../../dashboard/routes/Dashboard";
import environment from "../../environment";
import { createNamedContext } from "../../utils/createNamedContext";
@@ -22,7 +22,9 @@ export const RealmContext = createNamedContext(
export const RealmContextProvider: FunctionComponent = ({ children }) => {
const { adminClient } = useAdminClient();
const recentUsed = useMemo(() => new RecentUsed(), []);
- const routeMatch = useRouteMatch(DashboardRoute.path);
+ const routeMatch = useRouteMatch(
+ DashboardRouteWithRealm.path
+ );
const realmParam = routeMatch?.params.realm;
const realm = useMemo(
() => realmParam ?? environment.loginRealm,
diff --git a/src/dashboard/routes.ts b/src/dashboard/routes.ts
index e3df4a471b..1520e1d4c0 100644
--- a/src/dashboard/routes.ts
+++ b/src/dashboard/routes.ts
@@ -1,6 +1,14 @@
import type { RouteDef } from "../route-config";
-import { DashboardRoute } from "./routes/Dashboard";
+import {
+ DashboardRoute,
+ DashboardRouteWithRealm,
+ DashboardRouteWithTab,
+} from "./routes/Dashboard";
-const routes: RouteDef[] = [DashboardRoute];
+const routes: RouteDef[] = [
+ DashboardRoute,
+ DashboardRouteWithRealm,
+ DashboardRouteWithTab,
+];
export default routes;
diff --git a/src/dashboard/routes/Dashboard.ts b/src/dashboard/routes/Dashboard.ts
index f2a3cb7e46..6b144e9739 100644
--- a/src/dashboard/routes/Dashboard.ts
+++ b/src/dashboard/routes/Dashboard.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type DashboardTab = "info" | "providers";
@@ -8,13 +8,30 @@ export type DashboardTab = "info" | "providers";
export type DashboardParams = { realm?: string; tab?: DashboardTab };
export const DashboardRoute: RouteDef = {
- path: "/:realm?/:tab?",
+ path: "/",
component: lazy(() => import("../Dashboard")),
breadcrumb: (t) => t("common:home"),
access: "anyone",
- legacy: true,
};
-export const toDashboard = (params: DashboardParams): Partial => ({
- pathname: generatePath(DashboardRoute.path, params),
-});
+export const DashboardRouteWithRealm: RouteDef = {
+ ...DashboardRoute,
+ path: "/:realm",
+};
+
+export const DashboardRouteWithTab: RouteDef = {
+ ...DashboardRoute,
+ path: "/:realm/:tab",
+};
+
+export const toDashboard = (params: DashboardParams): Partial => {
+ const pathname = params.realm
+ ? params.tab
+ ? DashboardRouteWithTab.path
+ : DashboardRouteWithRealm.path
+ : DashboardRoute.path;
+
+ return {
+ pathname: generatePath(pathname, params),
+ };
+};
diff --git a/src/events/routes.ts b/src/events/routes.ts
index 3d5f54a971..9640c8d020 100644
--- a/src/events/routes.ts
+++ b/src/events/routes.ts
@@ -1,6 +1,6 @@
import type { RouteDef } from "../route-config";
-import { EventsRoute } from "./routes/Events";
+import { EventsRoute, EventsRouteWithTab } from "./routes/Events";
-const routes: RouteDef[] = [EventsRoute];
+const routes: RouteDef[] = [EventsRoute, EventsRouteWithTab];
export default routes;
diff --git a/src/events/routes/Events.ts b/src/events/routes/Events.ts
index 7942107ed1..b7dce87296 100644
--- a/src/events/routes/Events.ts
+++ b/src/events/routes/Events.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type EventsTab = "user-events" | "admin-events";
@@ -11,13 +11,21 @@ export type EventsParams = {
};
export const EventsRoute: RouteDef = {
- path: "/:realm/events/:tab?",
+ path: "/:realm/events",
component: lazy(() => import("../EventsSection")),
breadcrumb: (t) => t("events:title"),
access: "view-events",
- legacy: true,
};
-export const toEvents = (params: EventsParams): Partial => ({
- pathname: generatePath(EventsRoute.path, params),
-});
+export const EventsRouteWithTab: RouteDef = {
+ ...EventsRoute,
+ path: "/:realm/events/:tab",
+};
+
+export const toEvents = (params: EventsParams): Partial => {
+ const path = params.tab ? EventsRouteWithTab.path : EventsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/groups/routes.ts b/src/groups/routes.ts
index 233b592f91..9355d645bf 100644
--- a/src/groups/routes.ts
+++ b/src/groups/routes.ts
@@ -1,7 +1,7 @@
import type { RouteDef } from "../route-config";
-import { GroupsRoute } from "./routes/Groups";
+import { GroupsRoute, GroupsWithIdRoute } from "./routes/Groups";
import { GroupsSearchRoute } from "./routes/GroupsSearch";
-const routes: RouteDef[] = [GroupsSearchRoute, GroupsRoute];
+const routes: RouteDef[] = [GroupsSearchRoute, GroupsRoute, GroupsWithIdRoute];
export default routes;
diff --git a/src/groups/routes/Groups.tsx b/src/groups/routes/Groups.tsx
index 9ab464b672..37a73f71d3 100644
--- a/src/groups/routes/Groups.tsx
+++ b/src/groups/routes/Groups.tsx
@@ -1,20 +1,28 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type GroupsParams = { realm: string; id?: string };
export const GroupsRoute: RouteDef = {
- path: "/:realm/groups/:id?",
+ path: "/:realm/groups",
component: lazy(() => import("../GroupsSection")),
access: "query-groups",
matchOptions: {
exact: false,
},
- legacy: true,
};
-export const toGroups = (params: GroupsParams): Partial => ({
- pathname: generatePath(GroupsRoute.path, params),
-});
+export const GroupsWithIdRoute: RouteDef = {
+ ...GroupsRoute,
+ path: "/:realm/groups/:id",
+};
+
+export const toGroups = (params: GroupsParams): Partial => {
+ const path = params.id ? GroupsWithIdRoute.path : GroupsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/realm-roles/routes.ts b/src/realm-roles/routes.ts
index 89ff196c1a..3970fa0910 100644
--- a/src/realm-roles/routes.ts
+++ b/src/realm-roles/routes.ts
@@ -1,16 +1,18 @@
import type { RouteDef } from "../route-config";
import { AddRoleRoute } from "./routes/AddRole";
import { AddRoleToClientRoute } from "./routes/AddRoleToClient";
-import { ClientRoleRoute } from "./routes/ClientRole";
-import { RealmRoleRoute } from "./routes/RealmRole";
+import { ClientRoleRoute, ClientRoleRouteWithTab } from "./routes/ClientRole";
+import { RealmRoleRoute, RealmRoleRouteWithTab } from "./routes/RealmRole";
import { RealmRolesRoute } from "./routes/RealmRoles";
const routes: RouteDef[] = [
AddRoleToClientRoute,
ClientRoleRoute,
+ ClientRoleRouteWithTab,
RealmRolesRoute,
AddRoleRoute,
RealmRoleRoute,
+ RealmRoleRouteWithTab,
];
export default routes;
diff --git a/src/realm-roles/routes/ClientRole.ts b/src/realm-roles/routes/ClientRole.ts
index f8c211ffa6..b2861d94a4 100644
--- a/src/realm-roles/routes/ClientRole.ts
+++ b/src/realm-roles/routes/ClientRole.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type ClientRoleTab =
@@ -17,13 +17,21 @@ export type ClientRoleParams = {
};
export const ClientRoleRoute: RouteDef = {
- path: "/:realm/clients/:clientId/roles/:id/:tab?",
+ path: "/:realm/clients/:clientId/roles/:id",
component: lazy(() => import("../RealmRoleTabs")),
breadcrumb: (t) => t("roles:roleDetails"),
access: "view-realm",
- legacy: true,
};
-export const toClientRole = (params: ClientRoleParams): Partial => ({
- pathname: generatePath(ClientRoleRoute.path, params),
-});
+export const ClientRoleRouteWithTab: RouteDef = {
+ ...ClientRoleRoute,
+ path: "/:realm/clients/:clientId/roles/:id/:tab",
+};
+
+export const toClientRole = (params: ClientRoleParams): Partial => {
+ const path = params.tab ? ClientRoleRouteWithTab.path : ClientRoleRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/realm-roles/routes/RealmRole.ts b/src/realm-roles/routes/RealmRole.ts
index f986fb5174..c81dc3b363 100644
--- a/src/realm-roles/routes/RealmRole.ts
+++ b/src/realm-roles/routes/RealmRole.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type RealmRoleTab =
@@ -16,13 +16,21 @@ export type RealmRoleParams = {
};
export const RealmRoleRoute: RouteDef = {
- path: "/:realm/roles/:id/:tab?",
+ path: "/:realm/roles/:id",
component: lazy(() => import("../RealmRoleTabs")),
breadcrumb: (t) => t("roles:roleDetails"),
access: ["view-realm", "view-users"],
- legacy: true,
};
-export const toRealmRole = (params: RealmRoleParams): Partial => ({
- pathname: generatePath(RealmRoleRoute.path, params),
-});
+export const RealmRoleRouteWithTab: RouteDef = {
+ ...RealmRoleRoute,
+ path: "/:realm/roles/:id/:tab",
+};
+
+export const toRealmRole = (params: RealmRoleParams): Partial => {
+ const path = params.tab ? RealmRoleRouteWithTab.path : RealmRoleRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/realm-settings/routes.ts b/src/realm-settings/routes.ts
index 6343049300..e3e3cf2323 100644
--- a/src/realm-settings/routes.ts
+++ b/src/realm-settings/routes.ts
@@ -1,6 +1,9 @@
import type { RouteDef } from "../route-config";
import { KeyProviderFormRoute } from "./routes/KeyProvider";
-import { RealmSettingsRoute } from "./routes/RealmSettings";
+import {
+ RealmSettingsRoute,
+ RealmSettingsRouteWithTab,
+} from "./routes/RealmSettings";
import { ClientPoliciesRoute } from "./routes/ClientPolicies";
import { AddClientProfileRoute } from "./routes/AddClientProfile";
import { ClientProfileRoute } from "./routes/ClientProfile";
@@ -8,8 +11,14 @@ import { AddExecutorRoute } from "./routes/AddExecutor";
import { ExecutorRoute } from "./routes/Executor";
import { AddClientPolicyRoute } from "./routes/AddClientPolicy";
import { EditClientPolicyRoute } from "./routes/EditClientPolicy";
-import { NewClientPolicyConditionRoute } from "./routes/AddCondition";
-import { EditClientPolicyConditionRoute } from "./routes/EditCondition";
+import {
+ NewClientPolicyConditionRoute,
+ NewClientPolicyConditionWithPolicyNameRoute,
+} from "./routes/AddCondition";
+import {
+ EditClientPolicyConditionRoute,
+ EditClientPolicyConditionWithPolicyNameRoute,
+} from "./routes/EditCondition";
import { UserProfileRoute } from "./routes/UserProfile";
import { AddAttributeRoute } from "./routes/AddAttribute";
import { KeysRoute } from "./routes/KeysTab";
@@ -19,6 +28,7 @@ import { EditAttributesGroupRoute } from "./routes/EditAttributesGroup";
const routes: RouteDef[] = [
RealmSettingsRoute,
+ RealmSettingsRouteWithTab,
KeysRoute,
KeyProviderFormRoute,
ClientPoliciesRoute,
@@ -29,7 +39,9 @@ const routes: RouteDef[] = [
AddClientPolicyRoute,
EditClientPolicyRoute,
NewClientPolicyConditionRoute,
+ NewClientPolicyConditionWithPolicyNameRoute,
EditClientPolicyConditionRoute,
+ EditClientPolicyConditionWithPolicyNameRoute,
UserProfileRoute,
AddAttributeRoute,
AttributeRoute,
diff --git a/src/realm-settings/routes/AddCondition.ts b/src/realm-settings/routes/AddCondition.ts
index 36b918d618..083e30dc06 100644
--- a/src/realm-settings/routes/AddCondition.ts
+++ b/src/realm-settings/routes/AddCondition.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type NewClientPolicyConditionParams = {
@@ -9,15 +9,25 @@ export type NewClientPolicyConditionParams = {
};
export const NewClientPolicyConditionRoute: RouteDef = {
- path: "/:realm/realm-settings/client-policies/:policyName?/edit-policy/create-condition",
+ path: "/:realm/realm-settings/client-policies",
component: lazy(() => import("../NewClientPolicyCondition")),
breadcrumb: (t) => t("realm-settings:addCondition"),
access: "manage-clients",
- legacy: true,
+};
+
+export const NewClientPolicyConditionWithPolicyNameRoute: RouteDef = {
+ ...NewClientPolicyConditionRoute,
+ path: "/:realm/realm-settings/client-policies/:policyName/edit-policy/create-condition",
};
export const toNewClientPolicyCondition = (
params: NewClientPolicyConditionParams
-): Partial => ({
- pathname: generatePath(NewClientPolicyConditionRoute.path, params),
-});
+): Partial => {
+ const path = params.policyName
+ ? NewClientPolicyConditionWithPolicyNameRoute.path
+ : NewClientPolicyConditionRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/realm-settings/routes/EditCondition.ts b/src/realm-settings/routes/EditCondition.ts
index a1ca4c967f..5731203a69 100644
--- a/src/realm-settings/routes/EditCondition.ts
+++ b/src/realm-settings/routes/EditCondition.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type EditClientPolicyConditionParams = {
@@ -10,15 +10,25 @@ export type EditClientPolicyConditionParams = {
};
export const EditClientPolicyConditionRoute: RouteDef = {
- path: "/:realm/realm-settings/client-policies/:policyName?/edit-policy/:conditionName/edit-condition",
+ path: "/:realm/realm-settings/client-policies",
component: lazy(() => import("../NewClientPolicyCondition")),
breadcrumb: (t) => t("realm-settings:editCondition"),
access: "manage-clients",
- legacy: true,
+};
+
+export const EditClientPolicyConditionWithPolicyNameRoute: RouteDef = {
+ ...EditClientPolicyConditionRoute,
+ path: "/:realm/realm-settings/client-policies/:policyName/edit-policy/:conditionName/edit-condition",
};
export const toEditClientPolicyCondition = (
params: EditClientPolicyConditionParams
-): Partial => ({
- pathname: generatePath(EditClientPolicyConditionRoute.path, params),
-});
+): Partial => {
+ const path = params.policyName
+ ? EditClientPolicyConditionWithPolicyNameRoute.path
+ : EditClientPolicyConditionRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/realm-settings/routes/RealmSettings.ts b/src/realm-settings/routes/RealmSettings.ts
index 807eed1423..8b19495d40 100644
--- a/src/realm-settings/routes/RealmSettings.ts
+++ b/src/realm-settings/routes/RealmSettings.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
export type RealmSettingsTab =
@@ -24,15 +24,23 @@ export type RealmSettingsParams = {
};
export const RealmSettingsRoute: RouteDef = {
- path: "/:realm/realm-settings/:tab?",
+ path: "/:realm/realm-settings",
component: lazy(() => import("../RealmSettingsSection")),
breadcrumb: (t) => t("realmSettings"),
access: "view-realm",
- legacy: true,
};
-export const toRealmSettings = (
- params: RealmSettingsParams
-): Partial => ({
- pathname: generatePath(RealmSettingsRoute.path, params),
-});
+export const RealmSettingsRouteWithTab: RouteDef = {
+ ...RealmSettingsRoute,
+ path: "/:realm/realm-settings/:tab",
+};
+
+export const toRealmSettings = (params: RealmSettingsParams): Partial => {
+ const path = params.tab
+ ? RealmSettingsRouteWithTab.path
+ : RealmSettingsRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/route-config.ts b/src/route-config.ts
index c99b33b018..82b31075e6 100644
--- a/src/route-config.ts
+++ b/src/route-config.ts
@@ -23,7 +23,6 @@ export type RouteDef = {
breadcrumb?: (t: TFunction) => string | ComponentType;
access: AccessType | AccessType[];
matchOptions?: MatchOptions;
- legacy?: boolean;
};
const NotFoundRoute: RouteDef = {
diff --git a/src/user-federation/UserFederationLdapSettings.tsx b/src/user-federation/UserFederationLdapSettings.tsx
index 1c6f775548..ad48670d48 100644
--- a/src/user-federation/UserFederationLdapSettings.tsx
+++ b/src/user-federation/UserFederationLdapSettings.tsx
@@ -24,14 +24,18 @@ import { FormProvider, useForm, useFormContext } from "react-hook-form";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { useAlerts } from "../components/alert/Alerts";
import { useTranslation } from "react-i18next";
-import { useParams } from "react-router-dom";
+import { useHistory, useParams } from "react-router-dom";
import { useNavigate } from "react-router-dom-v5-compat";
import { ScrollForm } from "../components/scroll-form/ScrollForm";
-import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
import { LdapMapperList } from "./ldap/mappers/LdapMapperList";
import { toUserFederation } from "./routes/UserFederation";
import { ExtendedHeader } from "./shared/ExtendedHeader";
+import {
+ routableTab,
+ RoutableTabs,
+} from "../components/routable-tabs/RoutableTabs";
+import { toUserFederationLdap } from "./routes/UserFederationLdap";
type ldapComponentRepresentation = ComponentRepresentation & {
config?: {
@@ -110,6 +114,7 @@ export default function UserFederationLdapSettings() {
const { t } = useTranslation("user-federation");
const form = useForm({ mode: "onChange" });
const navigate = useNavigate();
+ const history = useHistory();
const { adminClient } = useAdminClient();
const { realm } = useRealm();
@@ -189,11 +194,21 @@ export default function UserFederationLdapSettings() {
/>
{id ? (
-
+
{t("common:settings")}}
+ {...routableTab({
+ to: toUserFederationLdap({ realm, id, tab: "settings" }),
+ history,
+ })}
>
@@ -201,13 +216,16 @@ export default function UserFederationLdapSettings() {
{t("common:mappers")}}
data-testid="ldap-mappers-tab"
+ {...routableTab({
+ to: toUserFederationLdap({ realm, id, tab: "mappers" }),
+ history,
+ })}
>
-
+
) : (
diff --git a/src/user-federation/routes.ts b/src/user-federation/routes.ts
index df180b7bf6..ea8ab2a36e 100644
--- a/src/user-federation/routes.ts
+++ b/src/user-federation/routes.ts
@@ -7,7 +7,10 @@ import {
} from "./routes/NewProvider";
import { UserFederationRoute } from "./routes/UserFederation";
import { UserFederationKerberosRoute } from "./routes/UserFederationKerberos";
-import { UserFederationLdapRoute } from "./routes/UserFederationLdap";
+import {
+ UserFederationLdapRoute,
+ UserFederationLdapWithTabRoute,
+} from "./routes/UserFederationLdap";
import { UserFederationLdapMapperRoute } from "./routes/UserFederationLdapMapper";
import { UserFederationsKerberosRoute } from "./routes/UserFederationsKerberos";
import { UserFederationsLdapRoute } from "./routes/UserFederationsLdap";
@@ -20,6 +23,7 @@ const routes: RouteDef[] = [
UserFederationsLdapRoute,
NewLdapUserFederationRoute,
UserFederationLdapRoute,
+ UserFederationLdapWithTabRoute,
UserFederationLdapMapperRoute,
CustomProviderRoute,
CustomEditProviderRoute,
diff --git a/src/user-federation/routes/UserFederationLdap.ts b/src/user-federation/routes/UserFederationLdap.ts
index 111f18b478..c57b69fe03 100644
--- a/src/user-federation/routes/UserFederationLdap.ts
+++ b/src/user-federation/routes/UserFederationLdap.ts
@@ -1,6 +1,6 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
import type { Path } from "react-router-dom-v5-compat";
+import { generatePath } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
type UserFederationLdapTab = "settings" | "mappers";
@@ -12,15 +12,25 @@ export type UserFederationLdapParams = {
};
export const UserFederationLdapRoute: RouteDef = {
- path: "/:realm/user-federation/ldap/:id/:tab?",
+ path: "/:realm/user-federation/ldap/:id",
component: lazy(() => import("../UserFederationLdapSettings")),
breadcrumb: (t) => t("common:settings"),
access: "view-realm",
- legacy: true,
+};
+
+export const UserFederationLdapWithTabRoute: RouteDef = {
+ ...UserFederationLdapRoute,
+ path: "/:realm/user-federation/ldap/:id/:tab",
};
export const toUserFederationLdap = (
params: UserFederationLdapParams
-): Partial => ({
- pathname: generatePath(UserFederationLdapRoute.path, params),
-});
+): Partial => {
+ const path = params.tab
+ ? UserFederationLdapWithTabRoute.path
+ : UserFederationLdapRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};
diff --git a/src/user/routes.ts b/src/user/routes.ts
index 452e4a13f7..6caf21adbd 100644
--- a/src/user/routes.ts
+++ b/src/user/routes.ts
@@ -1,8 +1,13 @@
import type { RouteDef } from "../route-config";
import { AddUserRoute } from "./routes/AddUser";
import { UserRoute } from "./routes/User";
-import { UsersRoute } from "./routes/Users";
+import { UsersRoute, UsersRouteWithTab } from "./routes/Users";
-const routes: RouteDef[] = [AddUserRoute, UsersRoute, UserRoute];
+const routes: RouteDef[] = [
+ AddUserRoute,
+ UsersRoute,
+ UsersRouteWithTab,
+ UserRoute,
+];
export default routes;
diff --git a/src/user/routes/Users.ts b/src/user/routes/Users.ts
index 6241af1ccb..22e3721194 100644
--- a/src/user/routes/Users.ts
+++ b/src/user/routes/Users.ts
@@ -1,5 +1,5 @@
import { lazy } from "react";
-import { generatePath } from "react-router-dom";
+import { generatePath } from "react-router-dom-v5-compat";
import type { Path } from "react-router-dom-v5-compat";
import type { RouteDef } from "../../route-config";
@@ -8,13 +8,21 @@ export type UserTab = "list" | "permissions";
export type UsersParams = { realm: string; tab?: UserTab };
export const UsersRoute: RouteDef = {
- path: "/:realm/users/:tab?",
+ path: "/:realm/users",
component: lazy(() => import("../UsersSection")),
breadcrumb: (t) => t("users:title"),
access: "query-users",
- legacy: true,
};
-export const toUsers = (params: UsersParams): Partial => ({
- pathname: generatePath(UsersRoute.path, params),
-});
+export const UsersRouteWithTab: RouteDef = {
+ ...UsersRoute,
+ path: "/:realm/users/:tab",
+};
+
+export const toUsers = (params: UsersParams): Partial => {
+ const path = params.tab ? UsersRouteWithTab.path : UsersRoute.path;
+
+ return {
+ pathname: generatePath(path, params),
+ };
+};