fix(admin): 子分组开关即时保存并立即显示分组管理
- 拨动开关即调用 PATCH allowGroups,成功后本地更新分类,无需再点保存 - 侧栏导航的分组列表同样跟随开关显示 - 失败时回滚开关状态
This commit is contained in:
@@ -130,6 +130,14 @@ export function AdminPage() {
|
||||
|
||||
const requestDelete = (card: CategorySummary) => setPendingDelete(card)
|
||||
|
||||
/** 只更新本地分类缓存(不改 draft),用于「子分组」开关即时生效 */
|
||||
const patchCategory = (id: string, patch: Partial<CategorySummary>) =>
|
||||
setCategories((current) =>
|
||||
current.map((category) =>
|
||||
category.id === id ? { ...category, ...patch } : category,
|
||||
),
|
||||
)
|
||||
|
||||
const confirmDelete = async () => {
|
||||
if (pendingDelete === null) return
|
||||
setDeleting(true)
|
||||
@@ -232,6 +240,7 @@ export function AdminPage() {
|
||||
categories={categories}
|
||||
onReload={load}
|
||||
onDelete={requestDelete}
|
||||
onToggleGroups={(id, allow) => patchCategory(id, { allowGroups: allow })}
|
||||
/>
|
||||
) : tab === 'sidebar' ? (
|
||||
<SidebarForm
|
||||
@@ -505,7 +514,7 @@ function SidebarForm({
|
||||
|
||||
{ordered.map((category, index) => {
|
||||
const visible = !value.hidden.includes(category.id)
|
||||
const groups = orderedGroups(category)
|
||||
const groups = category.allowGroups === true ? orderedGroups(category) : []
|
||||
|
||||
return (
|
||||
<div className="admin-nav-block" key={category.id}>
|
||||
@@ -745,10 +754,12 @@ function CategoryManager({
|
||||
categories,
|
||||
onReload,
|
||||
onDelete,
|
||||
onToggleGroups,
|
||||
}: {
|
||||
categories: CategorySummary[]
|
||||
onReload: () => void
|
||||
onDelete: (card: CategorySummary) => void
|
||||
onToggleGroups: (id: string, allow: boolean) => void
|
||||
}) {
|
||||
return (
|
||||
<Space direction="column" gap="lg" align="stretch" className="admin-form">
|
||||
@@ -764,6 +775,7 @@ function CategoryManager({
|
||||
category={category}
|
||||
onReload={onReload}
|
||||
onDelete={onDelete}
|
||||
onToggleGroups={onToggleGroups}
|
||||
/>
|
||||
{category.allowGroups === true && (
|
||||
<>
|
||||
@@ -785,10 +797,12 @@ function CategoryRow({
|
||||
category,
|
||||
onReload,
|
||||
onDelete,
|
||||
onToggleGroups,
|
||||
}: {
|
||||
category: CategorySummary
|
||||
onReload: () => void
|
||||
onDelete: (card: CategorySummary) => void
|
||||
onToggleGroups: (id: string, allow: boolean) => void
|
||||
}) {
|
||||
const [title, setTitle] = useState(category.title)
|
||||
const [kind, setKind] = useState(category.kind ?? 'apps')
|
||||
@@ -800,6 +814,23 @@ function CategoryRow({
|
||||
const [allowGroups, setAllowGroups] = useState(category.allowGroups === true)
|
||||
const [busy, setBusy] = useState(false)
|
||||
|
||||
/** 子分组开关即时保存:切完立刻出现 / 收起分组管理 */
|
||||
const toggleGroups = async (next: boolean) => {
|
||||
setAllowGroups(next)
|
||||
setBusy(true)
|
||||
const result = await updateCategory(category.id, { allowGroups: next })
|
||||
setBusy(false)
|
||||
|
||||
if (!result.ok) {
|
||||
setAllowGroups(!next)
|
||||
toast.error(result.error)
|
||||
return
|
||||
}
|
||||
|
||||
onToggleGroups(category.id, next)
|
||||
toast.success(next ? '已开启子分组' : '已关闭子分组')
|
||||
}
|
||||
|
||||
const save = async () => {
|
||||
setBusy(true)
|
||||
const result = await updateCategory(category.id, {
|
||||
@@ -856,7 +887,7 @@ function CategoryRow({
|
||||
<div className="admin-toggle">
|
||||
<Switch
|
||||
checked={allowGroups}
|
||||
onChange={setAllowGroups}
|
||||
onChange={(next) => void toggleGroups(next)}
|
||||
label={`${category.title} 允许子分组`}
|
||||
/>
|
||||
<Text size="sm" tone="muted">
|
||||
|
||||
Reference in New Issue
Block a user