feat(web): table ui upgrade
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-02 15:29:46
|
* @Date: 2026-02-02 15:29:46
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-25 15:06:40
|
* @Last Modified time: 2026-03-23 12:11:18
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* RbTable Component
|
* RbTable Component
|
||||||
@@ -199,7 +199,7 @@ const RbTable = forwardRef<TableRef, TableComponentProps>(({
|
|||||||
if (scrollY !== undefined) {
|
if (scrollY !== undefined) {
|
||||||
config.y = scrollY;
|
config.y = scrollY;
|
||||||
} else if (isScroll) {
|
} else if (isScroll) {
|
||||||
config.y = 'calc(100vh - 240px)';
|
config.y = 'calc(100vh - 256px)';
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.keys(config).length > 0 ? config : undefined;
|
return Object.keys(config).length > 0 ? config : undefined;
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ export const en = {
|
|||||||
zh: 'Chinese'
|
zh: 'Chinese'
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
|
userList: 'User List',
|
||||||
searchPlaceholder: 'search user…',
|
searchPlaceholder: 'search user…',
|
||||||
userId: 'User ID',
|
userId: 'User ID',
|
||||||
username: 'Username',
|
username: 'Username',
|
||||||
|
|||||||
@@ -943,6 +943,7 @@ export const zh = {
|
|||||||
zh: '中'
|
zh: '中'
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
|
userList: '用户列表',
|
||||||
searchPlaceholder: '搜索用户…',
|
searchPlaceholder: '搜索用户…',
|
||||||
userId: '用户ID',
|
userId: '用户ID',
|
||||||
username: '用户名',
|
username: '用户名',
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ export const lightTheme: ThemeConfig = {
|
|||||||
rowSelectedHoverBg: '#F0F3F8',
|
rowSelectedHoverBg: '#F0F3F8',
|
||||||
cellPaddingBlock: 8,
|
cellPaddingBlock: 8,
|
||||||
cellFontSizeSM: 12,
|
cellFontSizeSM: 12,
|
||||||
|
footerBg: '#FFFFFF',
|
||||||
|
colorText: '#5B6167',
|
||||||
|
|
||||||
// cellPaddingInline: 24,
|
// cellPaddingInline: 24,
|
||||||
selectionColumnWidth: 48,
|
selectionColumnWidth: 48,
|
||||||
|
|||||||
@@ -153,18 +153,17 @@ body {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
.ant-table-container {
|
.ant-table-container {
|
||||||
border: 1px solid #DFE4ED;
|
border-radius: 12px;
|
||||||
border-radius: 8px;
|
border: none;
|
||||||
border-bottom: 0;
|
|
||||||
}
|
}
|
||||||
.ant-table-wrapper table {
|
.ant-table-wrapper table {
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
}
|
}
|
||||||
.ant-table-row:last-child .ant-table-cell:first-child {
|
.ant-table-row:last-child .ant-table-cell:first-child {
|
||||||
border-bottom-left-radius: 8px;
|
border-bottom-left-radius: none;
|
||||||
}
|
}
|
||||||
.ant-table-row:last-child .ant-table-cell:last-child {
|
.ant-table-row:last-child .ant-table-cell:last-child {
|
||||||
border-bottom-right-radius: 8px;
|
border-bottom-right-radius: none;
|
||||||
}
|
}
|
||||||
.ant-table-cell::before {
|
.ant-table-cell::before {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -177,7 +176,8 @@ body {
|
|||||||
}
|
}
|
||||||
.ant-table-wrapper .ant-table-thead>tr>th,
|
.ant-table-wrapper .ant-table-thead>tr>th,
|
||||||
.ant-table-wrapper .ant-table-thead>tr>td {
|
.ant-table-wrapper .ant-table-thead>tr>td {
|
||||||
font-weight: 500;
|
font-weight: normal;
|
||||||
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.ant-table-wrapper .ant-table.ant-table-small .ant-table-title,
|
.ant-table-wrapper .ant-table.ant-table-small .ant-table-title,
|
||||||
.ant-table-wrapper .ant-table.ant-table-small .ant-table-footer,
|
.ant-table-wrapper .ant-table.ant-table-small .ant-table-footer,
|
||||||
@@ -190,12 +190,20 @@ body {
|
|||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
}
|
}
|
||||||
.ant-table-wrapper .ant-table-pagination.ant-pagination {
|
.ant-table-wrapper .ant-table-pagination.ant-pagination {
|
||||||
margin: 24px 0 32px 0;
|
padding: 13px 24px;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-radius: 0px 0px 12px 12px;
|
||||||
}
|
}
|
||||||
.table-header-has-bg.ant-table-wrapper .ant-table-thead>tr>th,
|
.ant-table-wrapper .ant-table-thead>tr>th,
|
||||||
.table-header-has-bg.ant-table-wrapper .ant-table-thead>tr>td {
|
.ant-table-wrapper .ant-table-thead>tr>td,
|
||||||
|
.table-header.ant-table-wrapper .ant-table-thead>tr>th,
|
||||||
|
.table-header.ant-table-wrapper .ant-table-thead>tr>td {
|
||||||
background-color: #F6F6F6;
|
background-color: #F6F6F6;
|
||||||
}
|
}
|
||||||
|
.ant-table-wrapper .ant-btn {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.table-header-has-bg.ant-table-wrapper .ant-table,
|
.table-header-has-bg.ant-table-wrapper .ant-table,
|
||||||
.table-header-has-bg.ant-table-wrapper table {
|
.table-header-has-bg.ant-table-wrapper table {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ const Index = () => {
|
|||||||
title: t('space.spaceName'),
|
title: t('space.spaceName'),
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
|
className: 'rb:text-[#212332]'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('space.spaceIcon'),
|
title: t('space.spaceIcon'),
|
||||||
@@ -119,8 +120,6 @@ const Index = () => {
|
|||||||
rowKey="id"
|
rowKey="id"
|
||||||
bordered={false}
|
bordered={false}
|
||||||
scrollY="100%"
|
scrollY="100%"
|
||||||
className="rb:-mb-3!"
|
|
||||||
// scroll={{ y: 'calc(100vh - 340px)' }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 17:51:08
|
* @Date: 2026-02-03 17:51:08
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-25 15:44:54
|
* @Last Modified time: 2026-03-23 12:14:51
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* User Management Page
|
* User Management Page
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { Button, Space, App } from 'antd';
|
import { Button, App, Flex } from 'antd';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { ColumnsType } from 'antd/es/table';
|
import type { ColumnsType } from 'antd/es/table';
|
||||||
|
|
||||||
@@ -68,28 +68,33 @@ const UserManagement: React.FC = () => {
|
|||||||
title: t('user.userId'),
|
title: t('user.userId'),
|
||||||
dataIndex: 'id',
|
dataIndex: 'id',
|
||||||
key: 'id',
|
key: 'id',
|
||||||
fixed: 'left',
|
width: 190,
|
||||||
|
className: 'rb:text-[#212332]'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <>{t('user.username')}<div className="rb:text-[#5B6167] rb:text-[12px] rb:font-medium">({t(`user.subUsername`)})</div></>,
|
title: <>{t('user.username')}<div className="rb:text-[#5B6167] rb:text-[12px] rb:font-medium">({t(`user.subUsername`)})</div></>,
|
||||||
dataIndex: 'email',
|
dataIndex: 'email',
|
||||||
key: 'email',
|
key: 'email',
|
||||||
|
width: 210,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('user.displayName'),
|
title: t('user.displayName'),
|
||||||
dataIndex: 'username',
|
dataIndex: 'username',
|
||||||
key: 'username',
|
key: 'username',
|
||||||
|
width: 130,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('user.role'),
|
title: t('user.role'),
|
||||||
dataIndex: 'is_superuser',
|
dataIndex: 'is_superuser',
|
||||||
key: 'is_superuser',
|
key: 'is_superuser',
|
||||||
|
width: 70,
|
||||||
render: (isSuperuser: boolean) => isSuperuser ? t('user.superuser') : t('user.normalUser'),
|
render: (isSuperuser: boolean) => isSuperuser ? t('user.superuser') : t('user.normalUser'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('user.status'),
|
title: t('user.status'),
|
||||||
dataIndex: 'is_active',
|
dataIndex: 'is_active',
|
||||||
key: 'is_active',
|
key: 'is_active',
|
||||||
|
width: 80,
|
||||||
render: (isActive: boolean) => (
|
render: (isActive: boolean) => (
|
||||||
<StatusTag
|
<StatusTag
|
||||||
text={isActive ? t('user.enabled') : t('user.disabled')}
|
text={isActive ? t('user.enabled') : t('user.disabled')}
|
||||||
@@ -101,20 +106,22 @@ const UserManagement: React.FC = () => {
|
|||||||
title: t('user.createTime'),
|
title: t('user.createTime'),
|
||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
|
width: 110,
|
||||||
render: (createdAt: string) => formatDateTime(createdAt, 'YYYY-MM-DD HH:mm:ss'),
|
render: (createdAt: string) => formatDateTime(createdAt, 'YYYY-MM-DD HH:mm:ss'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('user.lastLoginTime'),
|
title: t('user.lastLoginTime'),
|
||||||
dataIndex: 'last_login_at',
|
dataIndex: 'last_login_at',
|
||||||
key: 'last_login_at',
|
key: 'last_login_at',
|
||||||
|
width: 110,
|
||||||
render: (lastLoginAt: string) => lastLoginAt ? formatDateTime(lastLoginAt, 'YYYY-MM-DD HH:mm:ss') : '-',
|
render: (lastLoginAt: string) => lastLoginAt ? formatDateTime(lastLoginAt, 'YYYY-MM-DD HH:mm:ss') : '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('common.operation'),
|
title: t('common.operation'),
|
||||||
key: 'action',
|
key: 'action',
|
||||||
fixed: 'right',
|
width: 137,
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size="large">
|
<Flex wrap>
|
||||||
{record.is_active &&
|
{record.is_active &&
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
@@ -129,18 +136,19 @@ const UserManagement: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{t(`user.${record.is_active ? 'disabledOpera' : 'enabledOpera'}`)}
|
{t(`user.${record.is_active ? 'disabledOpera' : 'enabledOpera'}`)}
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Flex>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rb:h-[calc(100vh-80px)] rb:overflow-hidden">
|
<div className="rb:h-[calc(100vh-80px)] rb:overflow-hidden rb:bg-white rb:rounded-lg rb:pt-3 rb:px-3">
|
||||||
<div className="rb:flex rb:justify-end rb:mb-3">
|
<Flex justify="space-between" align="center" className="rb:px-1! rb:mb-3!">
|
||||||
|
<div className="rb:gont-[MiSans-Bold] rb:font-bold rb:text-[#212332] rb:leading-5">{t('user.userList')}</div>
|
||||||
<Button type="primary" onClick={handleCreate}>
|
<Button type="primary" onClick={handleCreate}>
|
||||||
{t('user.createUser')}
|
+ {t('user.createUser')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</Flex>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
|
|||||||
Reference in New Issue
Block a user