Refactor user federation providers to React Router v6 (#4177)
This commit is contained in:
parent
343aabb904
commit
6f498a9af7
8 changed files with 97 additions and 74 deletions
|
@ -1,45 +1,40 @@
|
|||
import { ReactElement, useState } from "react";
|
||||
import {
|
||||
CardHeader,
|
||||
CardActions,
|
||||
CardTitle,
|
||||
CardBody,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
Dropdown,
|
||||
KebabToggle,
|
||||
Label,
|
||||
Flex,
|
||||
FlexItem,
|
||||
KebabToggle,
|
||||
Label,
|
||||
} from "@patternfly/react-core";
|
||||
import "./keycloak-card.css";
|
||||
import { useRouteMatch } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom-v5-compat";
|
||||
import { ReactElement, useState } from "react";
|
||||
import { To, useNavigate } from "react-router-dom-v5-compat";
|
||||
import { ClickableCard } from "./ClickableCard";
|
||||
|
||||
import "./keycloak-card.css";
|
||||
|
||||
export type KeycloakCardProps = {
|
||||
id: string;
|
||||
title: string;
|
||||
dropdownItems?: ReactElement[];
|
||||
labelText?: string;
|
||||
labelColor?: any;
|
||||
footerText?: string;
|
||||
configEnabled?: boolean;
|
||||
providerId?: string;
|
||||
to: To;
|
||||
};
|
||||
|
||||
export const KeycloakCard = ({
|
||||
id,
|
||||
title,
|
||||
dropdownItems,
|
||||
labelText,
|
||||
labelColor,
|
||||
footerText,
|
||||
providerId,
|
||||
to,
|
||||
}: KeycloakCardProps) => {
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { url } = useRouteMatch();
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
|
||||
const onDropdownToggle = () => {
|
||||
setIsDropdownOpen(!isDropdownOpen);
|
||||
|
@ -49,12 +44,8 @@ export const KeycloakCard = ({
|
|||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const openSettings = () => {
|
||||
navigate(`${url}/${providerId}/${id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickableCard isSelectable onClick={openSettings}>
|
||||
<ClickableCard isSelectable onClick={() => navigate(to)}>
|
||||
<CardHeader>
|
||||
<CardActions>
|
||||
{dropdownItems && (
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||
import {
|
||||
AlertVariant,
|
||||
ButtonVariant,
|
||||
|
@ -13,22 +14,25 @@ import {
|
|||
TextVariants,
|
||||
} from "@patternfly/react-core";
|
||||
import { DatabaseIcon } from "@patternfly/react-icons";
|
||||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom-v5-compat";
|
||||
|
||||
import { useAlerts } from "../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { ManagePriorityDialog } from "./ManagePriorityDialog";
|
||||
import { ClickableCard } from "../components/keycloak-card/ClickableCard";
|
||||
import { KeycloakCard } from "../components/keycloak-card/KeycloakCard";
|
||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||
import { toUpperCase } from "../util";
|
||||
import { toProvider } from "./routes/NewProvider";
|
||||
import { ClickableCard } from "../components/keycloak-card/ClickableCard";
|
||||
import helpUrls from "../help-urls";
|
||||
import { toUpperCase } from "../util";
|
||||
import { ManagePriorityDialog } from "./ManagePriorityDialog";
|
||||
import { toCustomUserFederation } from "./routes/CustomUserFederation";
|
||||
import { toNewCustomUserFederation } from "./routes/NewCustomUserFederation";
|
||||
import { toUserFederationKerberos } from "./routes/UserFederationKerberos";
|
||||
import { toUserFederationLdap } from "./routes/UserFederationLdap";
|
||||
|
||||
import "./user-federation.css";
|
||||
|
||||
|
@ -72,7 +76,7 @@ export default function UserFederationSection() {
|
|||
<DropdownItem
|
||||
key={p.id}
|
||||
onClick={() =>
|
||||
navigate(toProvider({ realm, providerId: p.id!, id: "new" }))
|
||||
navigate(toNewCustomUserFederation({ realm, providerId: p.id! }))
|
||||
}
|
||||
>
|
||||
{p.id.toUpperCase() == "LDAP"
|
||||
|
@ -119,6 +123,17 @@ export default function UserFederationSection() {
|
|||
return a < b ? -1 : 1;
|
||||
};
|
||||
|
||||
const toDetails = (providerId: string, id: string) => {
|
||||
switch (providerId) {
|
||||
case "ldap":
|
||||
return toUserFederationLdap({ realm, id });
|
||||
case "kerberos":
|
||||
return toUserFederationKerberos({ realm, id });
|
||||
default:
|
||||
return toCustomUserFederation({ realm, providerId, id });
|
||||
}
|
||||
};
|
||||
|
||||
if (userFederations) {
|
||||
cards = userFederations.sort(cardSorter).map((userFederation, index) => (
|
||||
<GalleryItem
|
||||
|
@ -126,7 +141,7 @@ export default function UserFederationSection() {
|
|||
className="keycloak-admin--user-federation__gallery-item"
|
||||
>
|
||||
<KeycloakCard
|
||||
id={userFederation.id!}
|
||||
to={toDetails(userFederation.providerId!, userFederation.id!)}
|
||||
dropdownItems={[
|
||||
<DropdownItem
|
||||
key={`${index}-cardDelete`}
|
||||
|
@ -138,7 +153,6 @@ export default function UserFederationSection() {
|
|||
{t("common:delete")}
|
||||
</DropdownItem>,
|
||||
]}
|
||||
providerId={userFederation.providerId!}
|
||||
title={userFederation.name!}
|
||||
footerText={toUpperCase(userFederation.providerId!)}
|
||||
labelText={
|
||||
|
@ -196,7 +210,9 @@ export default function UserFederationSection() {
|
|||
<ClickableCard
|
||||
key={p.id}
|
||||
onClick={() =>
|
||||
navigate(toProvider({ realm, providerId: p.id! }))
|
||||
navigate(
|
||||
toNewCustomUserFederation({ realm, providerId: p.id! })
|
||||
)
|
||||
}
|
||||
data-testid={`${p.id}-card`}
|
||||
>
|
||||
|
|
|
@ -21,7 +21,7 @@ import { useRealm } from "../../context/realm-context/RealmContext";
|
|||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
import { useParams } from "../../utils/useParams";
|
||||
import type { ProviderRouteParams } from "../routes/NewProvider";
|
||||
import type { CustomUserFederationRouteParams } from "../routes/CustomUserFederation";
|
||||
import { toUserFederation } from "../routes/UserFederation";
|
||||
import { ExtendedHeader } from "../shared/ExtendedHeader";
|
||||
import { SettingsCache } from "../shared/SettingsCache";
|
||||
|
@ -31,7 +31,7 @@ import "./custom-provider-settings.css";
|
|||
|
||||
export default function CustomProviderSettings() {
|
||||
const { t } = useTranslation("user-federation");
|
||||
const { id, providerId } = useParams<ProviderRouteParams>();
|
||||
const { id, providerId } = useParams<CustomUserFederationRouteParams>();
|
||||
const navigate = useNavigate();
|
||||
const form = useForm<ComponentRepresentation>({
|
||||
shouldUnregister: false,
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import type { RouteDef } from "../route-config";
|
||||
import { CustomUserFederationRoute } from "./routes/CustomUserFederation";
|
||||
import { NewCustomUserFederationRoute } from "./routes/NewCustomUserFederation";
|
||||
import { NewKerberosUserFederationRoute } from "./routes/NewKerberosUserFederation";
|
||||
import { NewLdapUserFederationRoute } from "./routes/NewLdapUserFederation";
|
||||
import {
|
||||
CustomEditProviderRoute,
|
||||
CustomProviderRoute,
|
||||
} from "./routes/NewProvider";
|
||||
import { UserFederationRoute } from "./routes/UserFederation";
|
||||
import { UserFederationKerberosRoute } from "./routes/UserFederationKerberos";
|
||||
import {
|
||||
|
@ -25,8 +23,8 @@ const routes: RouteDef[] = [
|
|||
UserFederationLdapRoute,
|
||||
UserFederationLdapWithTabRoute,
|
||||
UserFederationLdapMapperRoute,
|
||||
CustomProviderRoute,
|
||||
CustomEditProviderRoute,
|
||||
NewCustomUserFederationRoute,
|
||||
CustomUserFederationRoute,
|
||||
];
|
||||
|
||||
export default routes;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { lazy } from "react";
|
||||
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 CustomUserFederationRouteParams = {
|
||||
realm: string;
|
||||
providerId: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export const CustomUserFederationRoute: RouteDef = {
|
||||
path: "/:realm/user-federation/:providerId/:id",
|
||||
component: lazy(() => import("../custom/CustomProviderSettings")),
|
||||
breadcrumb: (t) => t("user-federation:providerDetails"),
|
||||
access: "view-realm",
|
||||
};
|
||||
|
||||
export const toCustomUserFederation = (
|
||||
params: CustomUserFederationRouteParams
|
||||
): Partial<Path> => ({
|
||||
pathname: generatePath(CustomUserFederationRoute.path, params),
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
import { lazy } from "react";
|
||||
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 NewCustomUserFederationRouteParams = {
|
||||
realm: string;
|
||||
providerId: string;
|
||||
};
|
||||
|
||||
export const NewCustomUserFederationRoute: RouteDef = {
|
||||
path: "/:realm/user-federation/:providerId/new",
|
||||
component: lazy(() => import("../custom/CustomProviderSettings")),
|
||||
breadcrumb: (t) => t("user-federation:addCustomProvider"),
|
||||
access: "view-realm",
|
||||
};
|
||||
|
||||
export const toNewCustomUserFederation = (
|
||||
params: NewCustomUserFederationRouteParams
|
||||
): Partial<Path> => ({
|
||||
pathname: generatePath(NewCustomUserFederationRoute.path, params),
|
||||
});
|
|
@ -1,29 +0,0 @@
|
|||
import { lazy } from "react";
|
||||
import { generatePath } from "react-router-dom-v5-compat";
|
||||
|
||||
import type { Path } from "react-router-dom-v5-compat";
|
||||
import type { RouteDef } from "../../route-config";
|
||||
|
||||
export type ProviderRouteParams = {
|
||||
realm: string;
|
||||
providerId: string;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export const CustomProviderRoute: RouteDef = {
|
||||
path: "/:realm/user-federation/:providerId/new",
|
||||
component: lazy(() => import("../custom/CustomProviderSettings")),
|
||||
breadcrumb: (t) => t("user-federation:addCustomProvider"),
|
||||
access: "view-realm",
|
||||
};
|
||||
|
||||
export const CustomEditProviderRoute: RouteDef = {
|
||||
path: "/:realm/user-federation/:providerId/:id",
|
||||
component: lazy(() => import("../custom/CustomProviderSettings")),
|
||||
breadcrumb: (t) => t("user-federation:providerDetails"),
|
||||
access: "view-realm",
|
||||
};
|
||||
|
||||
export const toProvider = (params: ProviderRouteParams): Partial<Path> => ({
|
||||
pathname: generatePath(CustomProviderRoute.path, params),
|
||||
});
|
|
@ -1,20 +1,20 @@
|
|||
import { ReactElement } from "react";
|
||||
import { useParams, useNavigate } from "react-router-dom-v5-compat";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
AlertVariant,
|
||||
ButtonVariant,
|
||||
DropdownItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { ReactElement } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom-v5-compat";
|
||||
|
||||
import type { ProviderRouteParams } from "../routes/NewProvider";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { CustomUserFederationRouteParams } from "../routes/CustomUserFederation";
|
||||
import { toUserFederation } from "../routes/UserFederation";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
|
||||
type HeaderProps = {
|
||||
provider: string;
|
||||
|
@ -30,7 +30,7 @@ export const Header = ({
|
|||
dropdownItems = [],
|
||||
}: HeaderProps) => {
|
||||
const { t } = useTranslation("user-federation");
|
||||
const { id } = useParams<ProviderRouteParams>();
|
||||
const { id } = useParams<Partial<CustomUserFederationRouteParams>>();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { adminClient } = useAdminClient();
|
||||
|
|
Loading…
Reference in a new issue