Use routable tabs for user details (#3976)

This commit is contained in:
Jon Koops 2022-12-08 16:22:30 +01:00 committed by GitHub
parent 633a123a65
commit 9ac61efab4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 13 deletions

View file

@ -11,19 +11,23 @@ import {
import { useState } from "react"; import { useState } from "react";
import { Controller, FormProvider, useForm } from "react-hook-form"; import { Controller, FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { useNavigate } from "react-router-dom-v5-compat"; import { useNavigate } from "react-router-dom-v5-compat";
import { useAlerts } from "../components/alert/Alerts"; import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner"; import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs"; import {
RoutableTabs,
routableTab,
} from "../components/routable-tabs/RoutableTabs";
import { ViewHeader } from "../components/view-header/ViewHeader"; import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAccess } from "../context/access/Access"; import { useAccess } from "../context/access/Access";
import { useAdminClient, useFetch } from "../context/auth/AdminClient"; import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext"; import { useRealm } from "../context/realm-context/RealmContext";
import { UserProfileProvider } from "../realm-settings/user-profile/UserProfileContext"; import { UserProfileProvider } from "../realm-settings/user-profile/UserProfileContext";
import { useParams } from "../utils/useParams"; import { useParams } from "../utils/useParams";
import { toUser, UserParams } from "./routes/User"; import { toUser, UserParams, UserTab } from "./routes/User";
import { toUsers } from "./routes/Users"; import { toUsers } from "./routes/Users";
import { UserAttributes } from "./UserAttributes"; import { UserAttributes } from "./UserAttributes";
import { UserConsents } from "./UserConsents"; import { UserConsents } from "./UserConsents";
@ -42,6 +46,7 @@ const UsersTabs = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { realm } = useRealm(); const { realm } = useRealm();
const { hasAccess } = useAccess(); const { hasAccess } = useAccess();
const history = useHistory();
const { adminClient } = useAdminClient(); const { adminClient } = useAdminClient();
const userForm = useForm<UserRepresentation>({ mode: "onChange" }); const userForm = useForm<UserRepresentation>({ mode: "onChange" });
@ -157,6 +162,16 @@ const UsersTabs = () => {
return <KeycloakSpinner />; return <KeycloakSpinner />;
} }
const toTab = (tab: UserTab) =>
toUser({
realm,
id,
tab,
});
const routableUserTab = (tab: UserTab) =>
routableTab({ history, to: toTab(tab) });
return ( return (
<> <>
<ImpersonateConfirm /> <ImpersonateConfirm />
@ -198,11 +213,15 @@ const UsersTabs = () => {
<UserProfileProvider> <UserProfileProvider>
<FormProvider {...userForm}> <FormProvider {...userForm}>
{id && user && ( {id && user && (
<KeycloakTabs isBox mountOnEnter> <RoutableTabs
isBox
mountOnEnter
defaultLocation={toTab("settings")}
>
<Tab <Tab
eventKey="settings"
data-testid="user-details-tab" data-testid="user-details-tab"
title={<TabTitleText>{t("common:details")}</TabTitleText>} title={<TabTitleText>{t("common:details")}</TabTitleText>}
{...routableUserTab("settings")}
> >
<PageSection variant="light"> <PageSection variant="light">
{bruteForced && ( {bruteForced && (
@ -216,61 +235,61 @@ const UsersTabs = () => {
</PageSection> </PageSection>
</Tab> </Tab>
<Tab <Tab
eventKey="attributes"
data-testid="attributes" data-testid="attributes"
title={<TabTitleText>{t("common:attributes")}</TabTitleText>} title={<TabTitleText>{t("common:attributes")}</TabTitleText>}
{...routableUserTab("attributes")}
> >
<UserAttributes user={user} /> <UserAttributes user={user} />
</Tab> </Tab>
<Tab <Tab
eventKey="credentials"
data-testid="credentials" data-testid="credentials"
isHidden={!user.access?.manage} isHidden={!user.access?.manage}
title={<TabTitleText>{t("common:credentials")}</TabTitleText>} title={<TabTitleText>{t("common:credentials")}</TabTitleText>}
{...routableUserTab("credentials")}
> >
<UserCredentials user={user} /> <UserCredentials user={user} />
</Tab> </Tab>
<Tab <Tab
eventKey="role-mapping"
data-testid="role-mapping-tab" data-testid="role-mapping-tab"
isHidden={!user.access?.mapRoles} isHidden={!user.access?.mapRoles}
title={<TabTitleText>{t("roleMapping")}</TabTitleText>} title={<TabTitleText>{t("roleMapping")}</TabTitleText>}
{...routableUserTab("role-mapping")}
> >
<UserRoleMapping id={id} name={user.username!} /> <UserRoleMapping id={id} name={user.username!} />
</Tab> </Tab>
<Tab <Tab
eventKey="groups"
data-testid="user-groups-tab" data-testid="user-groups-tab"
title={<TabTitleText>{t("common:groups")}</TabTitleText>} title={<TabTitleText>{t("common:groups")}</TabTitleText>}
{...routableUserTab("groups")}
> >
<UserGroups user={user} /> <UserGroups user={user} />
</Tab> </Tab>
<Tab <Tab
eventKey="consents"
data-testid="user-consents-tab" data-testid="user-consents-tab"
title={<TabTitleText>{t("consents")}</TabTitleText>} title={<TabTitleText>{t("consents")}</TabTitleText>}
{...routableUserTab("consents")}
> >
<UserConsents /> <UserConsents />
</Tab> </Tab>
{hasAccess("view-identity-providers") && ( {hasAccess("view-identity-providers") && (
<Tab <Tab
eventKey="identity-provider-links"
data-testid="identity-provider-links-tab" data-testid="identity-provider-links-tab"
title={ title={
<TabTitleText>{t("identityProviderLinks")}</TabTitleText> <TabTitleText>{t("identityProviderLinks")}</TabTitleText>
} }
{...routableUserTab("identity-provider-links")}
> >
<UserIdentityProviderLinks userId={id} /> <UserIdentityProviderLinks userId={id} />
</Tab> </Tab>
)} )}
<Tab <Tab
eventKey="sessions"
data-testid="user-sessions-tab" data-testid="user-sessions-tab"
title={<TabTitleText>{t("sessions")}</TabTitleText>} title={<TabTitleText>{t("sessions")}</TabTitleText>}
{...routableUserTab("sessions")}
> >
<UserSessions /> <UserSessions />
</Tab> </Tab>
</KeycloakTabs> </RoutableTabs>
)} )}
{!id && ( {!id && (
<PageSection variant="light"> <PageSection variant="light">

View file

@ -8,7 +8,10 @@ export type UserTab =
| "groups" | "groups"
| "consents" | "consents"
| "attributes" | "attributes"
| "sessions"; | "sessions"
| "credentials"
| "role-mapping"
| "identity-provider-links";
export type UserParams = { export type UserParams = {
realm: string; realm: string;