Skip to content

feat(web): open user editor from user and log tables#3411

Open
MisonL wants to merge 6 commits intoQuantumNous:mainfrom
MisonL:feat/clickable-user-attribute-panel
Open

feat(web): open user editor from user and log tables#3411
MisonL wants to merge 6 commits intoQuantumNous:mainfrom
MisonL:feat/clickable-user-attribute-panel

Conversation

@MisonL
Copy link

@MisonL MisonL commented Mar 23, 2026

📝 变更描述 / Description

  • 让用户表、使用日志、任务日志中的头像与用户名可以直接打开现有的用户编辑侧边栏。
  • 使用共享的编辑面板替换使用日志里的只读用户信息弹窗,统一入口与行为。
  • 修正隐藏挂载时的加载竞态,避免错误触发 /api/user/self 请求或覆盖目标用户数据。
  • 保持已删除用户不可通过快捷入口继续编辑。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix)
  • ✨ 新功能 (New feature)
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自撰写此描述,去除了 AI 原始输出的冗余。
  • 深度理解: 我已完全理解这些更改的工作原理及潜在影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过了测试或手动验证。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

  • git diff --check
  • bunx eslint src/components/table/users/UsersColumnDefs.jsx src/components/table/users/UsersTable.jsx src/components/table/users/modals/EditUserModal.jsx src/hooks/usage-logs/useUsageLogsData.jsx src/components/table/usage-logs/UsageLogsTable.jsx src/components/table/usage-logs/UsageLogsColumnDefs.jsx src/components/table/usage-logs/index.jsx src/hooks/task-logs/useTaskLogsData.js src/components/table/task-logs/TaskLogsTable.jsx src/components/table/task-logs/TaskLogsColumnDefs.jsx src/components/table/task-logs/index.jsx
  • bun run build

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces the read-only user-info modal with an editable user panel across task-logs, usage-logs, and users tables. Callback renamed from showUserInfoFunc to openEditUserPanel; hooks and components now expose showEditUser/editingUser/open/close handlers and updated refresh signatures.

Changes

Cohort / File(s) Summary
Task Logs: columns & table
web/src/components/table/task-logs/TaskLogsColumnDefs.jsx, web/src/components/table/task-logs/TaskLogsTable.jsx, web/src/components/table/task-logs/modals/ColumnSelectorModal.jsx
Renamed showUserInfoFuncopenEditUserPanel. Username renderer now conditionally clickable (Avatar/Text) only when record.user_id truthy; clicks stop propagation and call openEditUserPanel(record.user_id).
Task Logs: page
web/src/components/table/task-logs/index.jsx
Swapped in EditUserModal; wired visible, editingUser, close handler, and refresh callback from taskLogsData.
Usage Logs: columns & table
web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx, web/src/components/table/usage-logs/UsageLogsTable.jsx, web/src/components/table/usage-logs/modals/ColumnSelectorModal.jsx
Renamed showUserInfoFuncopenEditUserPanel. Username renderer uses Space with Avatar and Typography.Text; conditional click/cursor handling invokes openEditUserPanel(user_id) when present.
Usage Logs: page & modal removal
web/src/components/table/usage-logs/index.jsx, web/src/components/table/usage-logs/modals/UserInfoModal.jsx
Removed UserInfoModal and replaced with EditUserModal wired to new edit-user state/handlers; previous read-only modal deleted.
Users: columns, table, modal
web/src/components/table/users/UsersColumnDefs.jsx, web/src/components/table/users/UsersTable.jsx, web/src/components/table/users/modals/EditUserModal.jsx
Username rendering and “编辑” action now call openEditUserPanel. UsersTable adds openEditUserPanel(user) guard for deleted/null users. EditUserModal rewritten to use request-id guards to avoid stale async updates and to await props.refresh() on submit.
Hooks: task/usage logs
web/src/hooks/task-logs/useTaskLogsData.js, web/src/hooks/usage-logs/useUsageLogsData.jsx
Replaced show-user-info fetch/state with edit-user panel state: showEditUser, editingUser, openEditUserPanel(userId), closeEditUserPanel(). refresh signatures changed to accept page (and optional refresh flags for usage-logs).

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Table as Table (columns)
  participant Hook as Hook (useLogsData / useTaskLogsData)
  participant Modal as EditUserModal
  participant API as API

  User->>Table: click username/avatar
  Table->>Hook: openEditUserPanel(userId)
  Hook-->>Table: set editingUser, showEditUser = true
  Hook->>Modal: visible=true, editingUser.id
  Modal->>API: fetch user data (loadUser)
  API-->>Modal: return user data
  Modal->>User: render editable user form
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion
  • creamlike1024

Poem

🐰 I hop through logs with nimble cheer,
Clicks open panels, edits appear.
From read-only views to forms that mend,
The rabbit nudges: change and send.
Carrots of state — the updates clear!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature: enabling clickable user entries (usernames/avatars) in user and log tables to open the edit-user panel, which aligns with all documented changes across multiple table components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/table/task-logs/index.jsx`:
- Around line 55-60: Editing a user triggers taskLogsData.refresh which
currently reloads page 1; when rendering EditUserModal pass a refresh handler
that preserves the current page instead of the default reset—e.g., wire
EditUserModal's refresh prop to a wrapper that calls taskLogsData.refresh with
the current page (or call a new taskLogsData.refreshCurrentPage helper exposed
by useTaskLogsData) so saving in EditUserModal (editingUser / showEditUser)
reloads the same page rather than jumping back to page one.

In `@web/src/components/table/task-logs/TaskLogsColumnDefs.jsx`:
- Around line 304-325: The click handler currently calls event.stopPropagation()
unconditionally in handleOpen, preventing row clicks even when the user panel
shouldn’t open; update handleOpen (or the onClick props on Avatar and
Typography.Text) so that either (a) handleOpen returns immediately if !canOpen
and only calls event.stopPropagation() when canOpen is true, or (b) only attach
onClick handlers when canOpen is true; locate handleOpen, canOpen,
openEditUserPanel(record.user_id), Avatar and Typography.Text in
TaskLogsColumnDefs.jsx to make the change.

In `@web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx`:
- Around line 579-601: The cell click handler handleOpen always calls
event.stopPropagation(), preventing row clicks from propagating for deleted
users; update handleOpen (used by Avatar and Typography.Text) to only call
event.stopPropagation() when canOpen is true (i.e., record.user_id exists) and
otherwise allow the event to bubble so row expansion works; keep the early
return for the non-openable case and still call
openEditUserPanel(record.user_id) when canOpen.

In `@web/src/components/table/users/modals/EditUserModal.jsx`:
- Around line 118-145: The initialize function can leave stale form values when
loadUser fails or returns success: false; ensure the form is cleared to initial
state before attempting to load a different user and also on any
non-success/failure path by calling
formApiRef.current?.setValues(getInitValues()) (or a shallow reset using
getInitValues() merged with the new currentUserId if needed) immediately prior
to calling loadUser and again in the !success and catch branches; update
initialize and its error/non-success handling so form state is reset reliably
(references: initialize, loadUser, formApiRef, setValues, getInitValues,
currentUserId).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9891a950-b41a-4197-a359-730ae925eb74

📥 Commits

Reviewing files that changed from the base of the PR and between 9ae9040 and c13a6aa.

📒 Files selected for processing (14)
  • web/src/components/table/task-logs/TaskLogsColumnDefs.jsx
  • web/src/components/table/task-logs/TaskLogsTable.jsx
  • web/src/components/table/task-logs/index.jsx
  • web/src/components/table/task-logs/modals/ColumnSelectorModal.jsx
  • web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx
  • web/src/components/table/usage-logs/UsageLogsTable.jsx
  • web/src/components/table/usage-logs/index.jsx
  • web/src/components/table/usage-logs/modals/ColumnSelectorModal.jsx
  • web/src/components/table/usage-logs/modals/UserInfoModal.jsx
  • web/src/components/table/users/UsersColumnDefs.jsx
  • web/src/components/table/users/UsersTable.jsx
  • web/src/components/table/users/modals/EditUserModal.jsx
  • web/src/hooks/task-logs/useTaskLogsData.js
  • web/src/hooks/usage-logs/useUsageLogsData.jsx
💤 Files with no reviewable changes (1)
  • web/src/components/table/usage-logs/modals/UserInfoModal.jsx

@MisonL
Copy link
Author

MisonL commented Mar 23, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/table/users/modals/EditUserModal.jsx`:
- Around line 107-111: The problem is that loadUser() is called after
fetchGroups() completes even if the target changed, and loadUser() immediately
sets loading which can leave the modal stuck; fix by short-circuiting stale
calls: when starting initialize()/fetchGroups() create an abort token or a local
"currentRequestId" (or use a mounted boolean) and check it before calling
loadUser(currentUserId) and before setting state inside loadUser; update
loadUser and initialize to accept or reference that token and bail early
(return) if the token indicates the request is no longer current so stale
responses never flip loading/state for a newer target.

In `@web/src/hooks/usage-logs/useUsageLogsData.jsx`:
- Around line 776-780: The refresh helper currently always calls handleEyeClick
which reopens stats; change refresh to accept an optional flag (e.g.,
refreshStats = true) and only call handleEyeClick when refreshStats is true,
keeping setActivePage and await loadLogs(page, pageSize) unchanged; update the
EditUserModal.submit call site to invoke refresh(page, { refreshStats: false }
or refresh(page, false) depending on your chosen param shape so saving a user
only refreshes the table and does not open stats.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 66d796aa-31b3-4958-86b0-73d29bfac73a

📥 Commits

Reviewing files that changed from the base of the PR and between c13a6aa and 20b1048.

📒 Files selected for processing (7)
  • web/src/components/table/task-logs/TaskLogsColumnDefs.jsx
  • web/src/components/table/task-logs/index.jsx
  • web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx
  • web/src/components/table/usage-logs/index.jsx
  • web/src/components/table/users/modals/EditUserModal.jsx
  • web/src/hooks/task-logs/useTaskLogsData.js
  • web/src/hooks/usage-logs/useUsageLogsData.jsx
✅ Files skipped from review due to trivial changes (2)
  • web/src/components/table/task-logs/index.jsx
  • web/src/components/table/usage-logs/index.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx
  • web/src/components/table/task-logs/TaskLogsColumnDefs.jsx
  • web/src/hooks/task-logs/useTaskLogsData.js

@MisonL
Copy link
Author

MisonL commented Mar 23, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/hooks/usage-logs/useUsageLogsData.jsx`:
- Around line 333-335: The current validation uses a falsy check on userId which
incorrectly rejects numeric zero; update the check in useUsageLogsData.jsx
(where userId is validated) to only treat null or undefined as missing rather
than any falsy value — replace the '!userId' condition with a
null/undefined-specific check so valid IDs like 0 are allowed, and keep the
existing showError(t('用户信息缺失')) and early return behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2b71684f-dd92-4132-9184-3a53dbd9817b

📥 Commits

Reviewing files that changed from the base of the PR and between 6217a9d and 85df723.

📒 Files selected for processing (2)
  • web/src/components/table/usage-logs/index.jsx
  • web/src/hooks/usage-logs/useUsageLogsData.jsx

@MisonL
Copy link
Author

MisonL commented Mar 24, 2026

CodeRabbit follow-up fixes

已补充修复 usage logs 中的 refresh 行为:

  • refresh() 改为接收 refreshStats 选项,默认保持原行为。
  • 从用户编辑提交后的刷新调用改为 refreshStats: false,只刷新表格,不再误触发 stats 弹层重新打开。
  • 同时把 stats 刷新调用改为 await handleEyeClick(),避免异步顺序不稳定。

已验证:

  • cd web && bunx eslint src/hooks/usage-logs/useUsageLogsData.jsx src/components/table/usage-logs/index.jsx

commit: 85df7233

@MisonL
Copy link
Author

MisonL commented Mar 24, 2026

CodeRabbit follow-up fixes

补充处理了新增的 userId 判空评论:

  • openEditUserPanel 里的校验从 !userId 改成只拦 null/undefined
  • 这样数值 0 不会再被误判成“用户信息缺失”

已验证:

  • cd web && bunx eslint src/hooks/usage-logs/useUsageLogsData.jsx src/components/table/usage-logs/index.jsx

commit: 5801aa13

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/hooks/usage-logs/useUsageLogsData.jsx`:
- Around line 776-779: The change made `refresh(page = activePage, ...)` causes
calls to refresh() (e.g., from UsageLogsFilters.jsx filter reset) to inherit the
current activePage instead of resetting to page 1; revert to a
backward-compatible behavior by changing the refresh signature to treat an
omitted page as request to reset to page 1 (for example use page = undefined or
no default and inside refresh set page = (page === undefined ? 1 : page)),
update logic in the refresh function (useUsageLogsData.jsx -> refresh) to set
page to 1 when page is undefined, and keep calls that pass an explicit page
unaffected.
- Around line 329-339: openEditUserPanel correctly passes id: 0 but
EditUserModal determines edit mode using Boolean(userId), which treats 0 as
false; update the modal's edit detection (in EditUserModal.jsx around the
component's mode logic) to check for id !== null && id !== undefined (or use
typeof id !== 'undefined' && id !== null) instead of Boolean(userId), or
alternatively accept an explicit flag (e.g., isEdit) from setEditingUser —
adjust the code path that reads the prop (userId / editingUser.id) so a valid id
of 0 is recognized as edit mode.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f50f45d-00a5-4bd1-813b-16e9a6d25446

📥 Commits

Reviewing files that changed from the base of the PR and between 85df723 and 5801aa1.

📒 Files selected for processing (1)
  • web/src/hooks/usage-logs/useUsageLogsData.jsx

@MisonL
Copy link
Author

MisonL commented Mar 24, 2026

CodeRabbit follow-up fixes

补充收口了这轮新增的两个 follow-up 问题:

  • EditUserModal 的编辑态判断从 Boolean(userId) 改成 nullish check,避免合法的 userId = 0 落到 create mode。
  • refresh() 的默认页码恢复为第 1 页,避免筛选器重置/切换时不再回到第一页的回归;需要保留当前页的场景仍继续显式传 activePage

已验证:

  • cd web && bunx eslint src/hooks/usage-logs/useUsageLogsData.jsx src/components/table/usage-logs/index.jsx src/components/table/users/modals/EditUserModal.jsx

commit: 223fcadd

@MisonL MisonL force-pushed the feat/clickable-user-attribute-panel branch from ac584df to ea7a437 Compare March 26, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant