mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
fix(console): return to user-details page from user-log-details page (#1135)
This commit is contained in:
parent
41e37a7995
commit
294c60062e
6 changed files with 34 additions and 19 deletions
|
@ -68,8 +68,9 @@ const Main = () => {
|
|||
</Route>
|
||||
<Route path="users">
|
||||
<Route index element={<Users />} />
|
||||
<Route path=":id" element={<UserDetails />} />
|
||||
<Route path=":id/logs" element={<UserDetails />} />
|
||||
<Route path=":userId" element={<UserDetails />} />
|
||||
<Route path=":userId/logs" element={<UserDetails />} />
|
||||
<Route path=":userId/logs/:logId" element={<AuditLogDetails />} />
|
||||
</Route>
|
||||
<Route path="sign-in-experience">
|
||||
<Route index element={<Navigate to="experience" />} />
|
||||
|
|
|
@ -3,7 +3,7 @@ import { conditionalString } from '@silverhand/essentials';
|
|||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import ApplicationName from '@/components/ApplicationName';
|
||||
|
@ -28,6 +28,7 @@ type Props = {
|
|||
|
||||
const AuditLogTable = ({ userId }: Props) => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { pathname } = useLocation();
|
||||
const [query, setQuery] = useSearchParams();
|
||||
const pageIndex = Number(query.get('page') ?? '1');
|
||||
const event = query.get('event');
|
||||
|
@ -114,7 +115,7 @@ const AuditLogTable = ({ userId }: Props) => {
|
|||
key={id}
|
||||
className={tableStyles.clickable}
|
||||
onClick={() => {
|
||||
navigate(`/audit-logs/${id}`);
|
||||
navigate(`${pathname}/${id}`);
|
||||
}}
|
||||
>
|
||||
<td>
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { LogDTO } from '@logto/schemas';
|
||||
import { LogDTO, User } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import ApplicationName from '@/components/ApplicationName';
|
||||
import Card from '@/components/Card';
|
||||
import CodeEditor from '@/components/CodeEditor';
|
||||
import DangerousRaw from '@/components/DangerousRaw';
|
||||
import DetailsSkeleton from '@/components/DetailsSkeleton';
|
||||
import LinkButton from '@/components/LinkButton';
|
||||
import TabNav, { TabNavItem } from '@/components/TabNav';
|
||||
|
@ -21,20 +22,30 @@ import * as detailsStyles from '@/scss/details.module.scss';
|
|||
import EventIcon from './components/EventIcon';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
const getAuditLogDetailsRelatedResourceLink = (pathname: string) =>
|
||||
`/${pathname.slice(0, pathname.lastIndexOf('/'))}`;
|
||||
|
||||
const AuditLogDetails = () => {
|
||||
const { logId } = useParams();
|
||||
const { userId, logId } = useParams();
|
||||
const { pathname } = useLocation();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { data, error } = useSWR<LogDTO, RequestError>(logId && `/api/logs/${logId}`);
|
||||
const { data: userData } = useSWR<User, RequestError>(userId && `/api/users/${userId}`);
|
||||
|
||||
const isLoading = !data && !error;
|
||||
|
||||
const backLink = getAuditLogDetailsRelatedResourceLink(pathname);
|
||||
const backLinkTitle = userId ? (
|
||||
<DangerousRaw>
|
||||
{t('log_details.back_to_user', { name: userData?.name ?? t('users.unnamed') })}
|
||||
</DangerousRaw>
|
||||
) : (
|
||||
'admin_console.log_details.back_to_logs'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={detailsStyles.container}>
|
||||
<LinkButton
|
||||
to="/audit-logs"
|
||||
icon={<Back />}
|
||||
title="admin_console.log_details.back_to_logs"
|
||||
className={styles.backLink}
|
||||
/>
|
||||
<LinkButton to={backLink} icon={<Back />} title={backLinkTitle} className={styles.backLink} />
|
||||
{isLoading && <DetailsSkeleton />}
|
||||
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||
{data && (
|
||||
|
|
|
@ -51,12 +51,12 @@ type FormData = {
|
|||
const UserDetails = () => {
|
||||
const location = useLocation();
|
||||
const isLogs = location.pathname.endsWith('/logs');
|
||||
const { id } = useParams();
|
||||
const { userId } = useParams();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const [isDeleteFormOpen, setIsDeleteFormOpen] = useState(false);
|
||||
const [isResetPasswordFormOpen, setIsResetPasswordFormOpen] = useState(false);
|
||||
|
||||
const { data, error, mutate } = useSWR<User, RequestError>(id && `/api/users/${id}`);
|
||||
const { data, error, mutate } = useSWR<User, RequestError>(userId && `/api/users/${userId}`);
|
||||
const isLoading = !data && !error;
|
||||
|
||||
const {
|
||||
|
@ -118,10 +118,10 @@ const UserDetails = () => {
|
|||
/>
|
||||
{isLoading && <DetailsSkeleton />}
|
||||
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||
{id && data && (
|
||||
{userId && data && (
|
||||
<>
|
||||
<Card className={styles.header}>
|
||||
<img className={styles.avatar} src={data.avatar ?? getAvatarById(id)} />
|
||||
<img className={styles.avatar} src={data.avatar ?? getAvatarById(userId)} />
|
||||
<div className={styles.metadata}>
|
||||
<div className={styles.name}>{data.name ?? '-'}</div>
|
||||
<div>
|
||||
|
@ -186,8 +186,8 @@ const UserDetails = () => {
|
|||
</Card>
|
||||
<Card className={classNames(styles.body, detailsStyles.body)}>
|
||||
<TabNav>
|
||||
<TabNavItem href={`/users/${id}`}>{t('user_details.tab_settings')}</TabNavItem>
|
||||
<TabNavItem href={`/users/${id}/logs`}>{t('user_details.tab_logs')}</TabNavItem>
|
||||
<TabNavItem href={`/users/${userId}`}>{t('user_details.tab_settings')}</TabNavItem>
|
||||
<TabNavItem href={`/users/${userId}/logs`}>{t('user_details.tab_logs')}</TabNavItem>
|
||||
</TabNav>
|
||||
{isLogs ? (
|
||||
<div className={styles.logs}>
|
||||
|
|
|
@ -551,6 +551,7 @@ const translation = {
|
|||
},
|
||||
log_details: {
|
||||
back_to_logs: 'Back to Audit Logs',
|
||||
back_to_user: 'Back to {{name}}',
|
||||
success: 'Success',
|
||||
failed: 'Failed',
|
||||
event_type: 'Event Type',
|
||||
|
|
|
@ -535,6 +535,7 @@ const translation = {
|
|||
},
|
||||
log_details: {
|
||||
back_to_logs: '返回审计日志',
|
||||
back_to_user: '返回 {{name}}',
|
||||
success: '成功',
|
||||
failed: '失败',
|
||||
event_type: '事件类型',
|
||||
|
|
Loading…
Add table
Reference in a new issue