style(admin): 分组管理表格整理
- 折叠箭头改成和前台侧栏 Menu 一样的 CSS 角标(6px 折角,展开/收起旋转) - 分组默认全部收起,首次拿到数据时统一折叠 - 操作列:加子分组 -> 新建子分组,并与编辑、删除一起配上图标 - 表格上方说明前加「说明:」
This commit is contained in:
+36
-3
@@ -975,22 +975,51 @@
|
||||
gap: var(--su-space-2);
|
||||
}
|
||||
|
||||
/* 折叠箭头:与前台侧栏 Menu 的 caret 同一套画法(CSS 画的 6px 角标) */
|
||||
.group-caret {
|
||||
width: 20px;
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--su-text-muted);
|
||||
font-size: var(--su-font-size-sm);
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.group-caret::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-left: 1px solid currentColor;
|
||||
border-bottom: 1px solid currentColor;
|
||||
opacity: 0.4;
|
||||
transform: rotate(315deg);
|
||||
transition:
|
||||
transform var(--su-duration-base) var(--su-ease-in-out),
|
||||
opacity var(--su-duration-base) var(--su-ease-in-out);
|
||||
}
|
||||
|
||||
.group-caret:hover::before {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.group-caret-open::before {
|
||||
opacity: 0.7;
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.group-caret-empty {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.group-caret-empty::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 分组图标选择:搜索 + 图标网格 */
|
||||
.icon-picker {
|
||||
display: flex;
|
||||
@@ -1080,12 +1109,16 @@
|
||||
}
|
||||
|
||||
.group-action {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--su-space-1);
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--su-color-primary);
|
||||
font-size: var(--su-font-size-sm);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.group-action:hover {
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
toast,
|
||||
type IconName,
|
||||
} from '@stash/ui'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { changePassword, fetchSession, logout, type SessionState } from '../../auth'
|
||||
import { LoginDialog } from '../auth/LoginDialog'
|
||||
import { GroupMark as GroupGlyph } from '../common/GroupMark'
|
||||
@@ -495,6 +495,24 @@ function GroupsPanel({
|
||||
const [collapsed, setCollapsed] = useState<Set<string>>(new Set())
|
||||
const [dialog, setDialog] = useState<GroupDialogState>(null)
|
||||
|
||||
// 默认全部收起:数据第一次到位时,把所有有子节点的分组塞进 collapsed
|
||||
const seeded = useRef(false)
|
||||
useEffect(() => {
|
||||
if (seeded.current || groups.length === 0) return
|
||||
seeded.current = true
|
||||
const keys = new Set<string>()
|
||||
const walk = (nodes: GroupNode[]) => {
|
||||
for (const node of nodes) {
|
||||
if (node.children.length > 0) {
|
||||
keys.add(node.key)
|
||||
walk(node.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(groups)
|
||||
setCollapsed(keys)
|
||||
}, [groups])
|
||||
|
||||
const rows = useMemo(() => {
|
||||
const result: { node: GroupNode; level: number }[] = []
|
||||
const walk = (nodes: GroupNode[], level: number) => {
|
||||
@@ -529,7 +547,7 @@ function GroupsPanel({
|
||||
return (
|
||||
<Space direction="column" gap="md" align="stretch" className="admin-form">
|
||||
<Text size="sm" tone="muted">
|
||||
分组用于控制前台侧边栏与卡片;可多层嵌套,根分组决定格式。内容(条目)只挂在分组上。
|
||||
说明:分组用于控制前台侧边栏与卡片;可多层嵌套,根分组决定格式。内容(条目)只挂在分组上。
|
||||
</Text>
|
||||
|
||||
<div className="group-toolbar">
|
||||
@@ -563,12 +581,11 @@ function GroupsPanel({
|
||||
{hasChildren ? (
|
||||
<button
|
||||
type="button"
|
||||
className="group-caret"
|
||||
className={`group-caret${open ? ' group-caret-open' : ''}`}
|
||||
aria-label={open ? `折叠 ${node.title}` : `展开 ${node.title}`}
|
||||
aria-expanded={open}
|
||||
onClick={() => toggle(node.key)}
|
||||
>
|
||||
{open ? '▾' : '▸'}
|
||||
</button>
|
||||
/>
|
||||
) : (
|
||||
<span className="group-caret group-caret-empty" aria-hidden="true" />
|
||||
)}
|
||||
@@ -593,13 +610,15 @@ function GroupsPanel({
|
||||
className="group-action"
|
||||
onClick={() => setDialog({ mode: 'child', parent: node })}
|
||||
>
|
||||
加子分组
|
||||
<Icon name="add_line" />
|
||||
新建子分组
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="group-action"
|
||||
onClick={() => setDialog({ mode: 'edit', group: node })}
|
||||
>
|
||||
<Icon name="edit_4_line" />
|
||||
编辑
|
||||
</button>
|
||||
<button
|
||||
@@ -607,6 +626,7 @@ function GroupsPanel({
|
||||
className="group-action group-action-danger"
|
||||
onClick={() => onDelete(node.key, node.title)}
|
||||
>
|
||||
<Icon name="delete_2_line" />
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user