diff --git a/HANDOFF.md b/HANDOFF.md index 443b697..38d1799 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -99,7 +99,7 @@ README.md 运行、路由、库结构、登录说明 | --- | --- | | 分组管理 | 树形表格:新建根分组(左侧)、加子分组、编辑(名称/上级/格式/图标/排序/状态)、删除;行内状态开关即时生效;图标可留空 | | 内容 | 选分组以列表展示条目(选主分组时包含所有子分组);列:标题 / 跳转链接 / 所属分组 / 操作;弹窗新增/编辑,编辑时显示不可改的「标识」 | -| 侧边栏 | 分组树逐项勾选(`settings.sidebar.tree_hidden`),子分组可单独勾选 | +| 侧边栏 | 分组树逐项勾选,开关在右侧、**拨动即保存**(无单独保存/撤销按钮);子分组可单独勾选 | | 首页卡片 | 新建/改名/删除卡片;勾选若干分组(可混合格式),每组单独设条数 | | 页头 | 启用开关、速度、条目、标签与色调 | | 资料 | 头像 URL、名称、角色、简介、位置 | diff --git a/docs/ADMIN-PLAN.md b/docs/ADMIN-PLAN.md index 40564dd..7da2074 100644 --- a/docs/ADMIN-PLAN.md +++ b/docs/ADMIN-PLAN.md @@ -147,6 +147,12 @@ DELETE /api/items/:id ## 11. 实施记录 +### P12(2026-10-31,内容/侧边栏交互微调) + +- 内容页与条目弹窗的分组下拉只显示分组名,去掉格式后缀与缩进空格,选项统一左对齐; +- 侧边栏页:开关移到右侧,拨动即写入 `settings.sidebar.tree_hidden`;移除「保存侧边栏 / 撤销改动 / 保存」按钮,保存成功用 Toast 提示; +- 验证:下拉选项无括号、x 对齐;侧边栏无保存按钮、开关在右、切换后设置即时落库。 + ### P11(2026-10-31,内容页列表化) - 内容页改为与分组管理一致的列表:标题 / 跳转链接 / 所属分组 / 操作; diff --git a/stash-web/src/App.css b/stash-web/src/App.css index 9dffb90..9b6a1fb 100644 --- a/stash-web/src/App.css +++ b/stash-web/src/App.css @@ -1267,6 +1267,20 @@ a.entry-href:hover { font-size: var(--su-font-size-sm); } +/* 侧边栏勾选:标题在左,开关在右 */ +.sidebar-toggle-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--su-space-3); + padding: var(--su-space-1) 0; +} + +.sidebar-toggle-row .admin-item-title { + flex: 1; + min-width: 0; +} + .admin-category-row > * { min-width: 0; } diff --git a/stash-web/src/components/admin/AdminNext.tsx b/stash-web/src/components/admin/AdminNext.tsx index cc7c484..66db7e0 100644 --- a/stash-web/src/components/admin/AdminNext.tsx +++ b/stash-web/src/components/admin/AdminNext.tsx @@ -136,6 +136,22 @@ export function AdminNext() { toast.success('已保存') } + /** 侧边栏开关即时保存(不再单独点保存按钮) */ + const saveSidebar = async (sidebar: SiteSettings['sidebar']) => { + if (document === null || draft === null) return + setSaving(true) + const result = await saveSettings(document.version, { ...draft, sidebar }) + setSaving(false) + if (!result.ok) { + toast.error(result.error) + void load() + return + } + setDocument(result.document) + setDraft(clone(result.document.settings)) + toast.success('侧边栏已保存') + } + const confirmDelete = async () => { if (pending === null) return setDeleting(true) @@ -234,9 +250,13 @@ export function AdminNext() { setDraft({ ...draft, sidebar })} - onSave={save} saving={saving} + onToggle={(key, visible) => { + const hidden = new Set(draft.sidebar.tree_hidden) + if (visible) hidden.delete(key) + else hidden.add(key) + void saveSidebar({ ...draft.sidebar, tree_hidden: [...hidden] }) + }} /> )} @@ -265,7 +285,7 @@ export function AdminNext() { {tab === 'system' && } - {(tab === 'header' || tab === 'profile' || tab === 'sidebar') && ( + {(tab === 'header' || tab === 'profile') && (