✨ feat(ui): Implement unified compact/adaptive table mode + icon refinement
Summary
• Added per-table “Compact / Adaptive” view toggle to all major table components (Tokens, Channels, Logs, MjLogs, TaskLogs, Redemptions, Users).
• Persist user preference in a single localStorage entry (`table_compact_modes`) instead of scattered keys.
Details
1. utils.js
• Re-implemented `getTableCompactMode` / `setTableCompactMode` to read & write a shared JSON object.
• Imported storage-key constant from `constants`.
2. hooks/useTableCompactMode.js
• Hook now consumes the unified helpers and listens to `storage` events via the shared key constant.
3. constants
• Added `TABLE_COMPACT_MODES_KEY` to `common.constant.js` and re-exported via `constants/index.js`.
4. Table components
• Integrated `useTableCompactMode('<tableName>')`.
• Dynamically remove `fixed: 'right'` column and horizontal `scroll` when in compact mode.
• UI: toggle button placed at card title’s right; responsive layout on small screens.
5. UI polish
• Replaced all lucide-react `List`/`ListIcon` usages with Semi UI `IconDescend` for consistency.
• Restored correct icons where `Hash` was intended (TaskLogsTable).
Benefits
• Consistent UX for switching list density across the app.
• Cleaner localStorage footprint with easier future maintenance.
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
AlertCircle,
|
||||
HelpCircle,
|
||||
Coins,
|
||||
Tags
|
||||
Tags,
|
||||
} from 'lucide-react';
|
||||
|
||||
import { CHANNEL_OPTIONS, ITEMS_PER_PAGE } from '../../constants/index.js';
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconSetting,
|
||||
IconDescend,
|
||||
IconSearch,
|
||||
IconEdit,
|
||||
IconDelete,
|
||||
@@ -64,6 +65,7 @@ import {
|
||||
import { loadChannelModels } from '../../helpers/index.js';
|
||||
import EditTagModal from '../../pages/Channel/EditTagModal.js';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTableCompactMode } from '../../hooks/useTableCompactMode';
|
||||
|
||||
const ChannelsTable = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -683,6 +685,7 @@ const ChannelsTable = () => {
|
||||
const [typeCounts, setTypeCounts] = useState({});
|
||||
const requestCounter = useRef(0);
|
||||
const [formApi, setFormApi] = useState(null);
|
||||
const [compactMode, setCompactMode] = useTableCompactMode('channels');
|
||||
const formInitValues = {
|
||||
searchKeyword: '',
|
||||
searchGroup: '',
|
||||
@@ -1576,6 +1579,16 @@ const ChannelsTable = () => {
|
||||
{t('批量操作')}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
||||
<Button
|
||||
theme='light'
|
||||
type='secondary'
|
||||
icon={<IconDescend />}
|
||||
className="!rounded-full w-full md:w-auto"
|
||||
onClick={() => setCompactMode(!compactMode)}
|
||||
>
|
||||
{compactMode ? t('自适应列表') : t('紧凑列表')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center gap-4 w-full md:w-auto order-1 md:order-2">
|
||||
@@ -1766,9 +1779,9 @@ const ChannelsTable = () => {
|
||||
bordered={false}
|
||||
>
|
||||
<Table
|
||||
columns={getVisibleColumns()}
|
||||
columns={compactMode ? getVisibleColumns().map(({ fixed, ...rest }) => rest) : getVisibleColumns()}
|
||||
dataSource={pageData}
|
||||
scroll={{ x: 'max-content' }}
|
||||
scroll={compactMode ? undefined : { x: 'max-content' }}
|
||||
pagination={{
|
||||
currentPage: activePage,
|
||||
pageSize: pageSize,
|
||||
|
||||
Reference in New Issue
Block a user