0
Fork 0
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:
Xiao Yijun 2022-06-17 11:59:22 +08:00 committed by GitHub
parent 41e37a7995
commit 294c60062e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 19 deletions

View file

@ -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" />} />

View file

@ -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>

View file

@ -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 && (

View file

@ -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}>

View file

@ -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',

View file

@ -535,6 +535,7 @@ const translation = {
},
log_details: {
back_to_logs: '返回审计日志',
back_to_user: '返回 {{name}}',
success: '成功',
failed: '失败',
event_type: '事件类型',