diff --git a/memory/2026-06-20.md b/memory/2026-06-20.md index c586bfe..c6342fa 100644 --- a/memory/2026-06-20.md +++ b/memory/2026-06-20.md @@ -409,3 +409,23 @@ - 风险与关注点: - 改动仅影响 `/admin/elevation-records` 前端请求与类型适配,不改变后端接口字段、权限码或数据模型。 + +## Follow-up - 角色管理页分页交互与 effect 顺序对齐(FL-152) + +- 背景: + - 评审继续指出角色管理页表格分页 `onChange` 混入卡片视图状态更新,且清理 effect 顺序与用户管理页不同。 + +- 本次处理: + - 表格分页 `onChange` 仅保留 `setPagination({ current: page, pageSize })`,移除 `setCardViewPage(page)` 与 `setAllLoadedRoles([])`,避免表格分页触发卡片视图状态更新。 + - 将角色页 timeout cleanup effect 移到 resize/ResizeObserver effect 之前,对齐用户管理页 hook 排列。 + - 复核角色卡片更多菜单,当前仍为“查看菜单 → 删除”,删除已位于最后,无需改动。 + +- 验证: + - 基线:`npm --workspace web exec eslint src/app/admin/users/page.tsx src/app/admin/roles/page.tsx` 通过,仅用户页 1 条既有 unused eslint-disable warning。 + - 基线:`npm --workspace web exec tsc --noEmit` 通过。 + - 修改后:`npm --workspace web exec eslint src/app/admin/roles/page.tsx --max-warnings=0` 通过。 + - 修改后:`npm --workspace web exec tsc --noEmit` 通过。 + - 修改后:`npm --workspace web exec eslint src/app/admin/users/page.tsx src/app/admin/roles/page.tsx` 通过,仍仅用户页 1 条既有 unused eslint-disable warning。 + +- 风险与关注点: + - 改动仅影响角色管理页前端表格分页回调和 hook 组织顺序,不改变接口、schema、权限或 CRUD 语义。 diff --git a/web/src/app/admin/roles/page.tsx b/web/src/app/admin/roles/page.tsx index 3775f15..39f7bbe 100644 --- a/web/src/app/admin/roles/page.tsx +++ b/web/src/app/admin/roles/page.tsx @@ -690,6 +690,17 @@ export default function AdminRolesPage() { window.requestAnimationFrame(updateTableScrollY); }, [anyError, paginationCurrent, paginationPageSize, roles.length, rolesQuery.isFetching, updateTableScrollY]); + useEffect(() => { + return () => { + if (keywordDebounceTimeoutRef.current) { + clearTimeout(keywordDebounceTimeoutRef.current); + } + if (roleCodeCheckTimeoutRef.current) { + clearTimeout(roleCodeCheckTimeoutRef.current); + } + }; + }, []); + useEffect(() => { if (typeof window === "undefined") { return; @@ -725,17 +736,6 @@ export default function AdminRolesPage() { }; }, [updateTableScrollY]); - useEffect(() => { - return () => { - if (keywordDebounceTimeoutRef.current) { - clearTimeout(keywordDebounceTimeoutRef.current); - } - if (roleCodeCheckTimeoutRef.current) { - clearTimeout(roleCodeCheckTimeoutRef.current); - } - }; - }, []); - if (initializing) { return (