Skip to content

fix: repair audit log action i18n labels#1041

Merged
ding113 merged 2 commits into
devfrom
fix/audit-log-actions-i18n-20260420
Apr 20, 2026
Merged

fix: repair audit log action i18n labels#1041
ding113 merged 2 commits into
devfrom
fix/audit-log-actions-i18n-20260420

Conversation

@ding113

@ding113 ding113 commented Apr 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • fix audit log action i18n lookups by moving auditLogs.actions to nested locale objects that next-intl can resolve
  • route both audit log UI surfaces through a shared action/category label helper that uses t.has(...) before translating
  • add regression tests for translated action rendering, raw-action fallback, and locale/action coverage drift

Verification

  • bun run build
  • bun run lint
  • bun run lint:fix
  • bun run typecheck
  • bun run test
  • bunx vitest run 'src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx' 'tests/unit/i18n/audit-log-actions-messages.test.ts'

UI Verification

  • Component-level browser verification of the real AuditLogDetailSheet rendering with login.success sample data and production locale messages.
  • Local full-page runtime screenshot was not used because this checkout has no local DSN / REDIS_URL runtime configured.

Audit log i18n verification

Greptile Summary

This PR fixes a bug where next-intl could not resolve audit-log action labels stored as flat dotted keys (e.g. "login.success": "...") by restructuring all five locale files into proper nested objects and routing both UI surfaces through a new shared getAuditActionLabel / getAuditCategoryLabel helper that guards with t.has() before translating. New tests cover correct translation, raw-action fallback, and cross-locale key sync.

Confidence Score: 5/5

This PR is safe to merge — the fix is correct, well-tested, and all five locales are consistent.

The root cause (flat dotted keys unresolvable by next-intl) is addressed correctly by nesting the messages and using t.has() guards. All five locale files are updated consistently, both UI surfaces route through the shared helper, and new tests cover translation, fallback, and cross-locale drift. No P0 or P1 findings were identified.

No files require special attention.

Important Files Changed

Filename Overview
src/app/[locale]/dashboard/audit-logs/_components/audit-log-labels.ts New shared helper; correctly uses t.has() guard before resolving dotted action paths into next-intl's nested message tree.
messages/en/auditLogs.json Restructured actions from flat dotted keys to properly nested objects; all leaf keys present and consistent with other locales.
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx Updated to use shared label helpers; category and action labels now resolved through t.has() guard, removing direct inline t() calls for dynamic keys.
src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx Updated to use shared label helpers for both category and action columns; logic is clean and consistent with the detail sheet.
tests/unit/i18n/audit-log-actions-messages.test.ts Drift-guard test: verifies no dotted-key regressions, bidirectional sync across all five locales, and coverage of every emitted action type found via static regex scan.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[actionType from DB] --> B[getAuditActionLabel]
    B --> C[Build key with actions prefix]
    C --> D{t.has check}
    D -- found --> E[Return translated string]
    D -- missing --> F[Return raw actionType]
    E --> G[UI renders label]
    F --> G
Loading

Reviews (2): Last reviewed commit: "fix: align audit log imports with alias ..." | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

将 auditLogs 的 actions 翻译键从扁平点分隔字符串重构为按域嵌套的对象结构,新增集中化的标签转换助手并替换组件内联回退逻辑;添加针对组件渲染和 i18n 键一致性的测试。所有语言文件同步更新键的层级结构。

Changes

Cohort / File(s) Summary
翻译文件重构
messages/en/auditLogs.json, messages/ja/auditLogs.json, messages/ru/auditLogs.json, messages/zh-CN/auditLogs.json, messages/zh-TW/auditLogs.json
actions 下的平层点分隔键(如 login.successuser.createmodel_price.upsert)重组为按域的嵌套对象(如 actions.login.successactions.user.createactions.model_price.upsert)。值未改动,仅改变查找路径。
标签助手模块
src/app/[locale]/dashboard/audit-logs/_components/audit-log-labels.ts
新增 AuditLogTranslator 接口并导出 getAuditCategoryLabelgetAuditActionLabel,统一构建翻译键并在 t.has(key) 为假时回退到原始字符串。
组件变更
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx, src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx
移除组件内的 IIFE/try-catch 翻译与回退实现,改为调用新导出的助手函数以获得 category/action 标签。
测试新增
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx, tests/unit/i18n/audit-log-actions-messages.test.ts
新增组件级测试(模拟 i18n、UI 原语)以验证行为和回退;新增 i18n 单元测试以确保 actions 下不存在扁平点键,并校验各语言与 en 的叶子键集合一致且覆盖代码中发出的 action 类型。

Estimated code review effort

🎯 3 (中等复杂度) | ⏱️ ~25 分钟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题清晰简洁地概括了主要变更:修复审计日志操作的国际化标签问题,通过重构JSON结构为嵌套对象。
Description check ✅ Passed PR描述清晰地说明了变更内容:修复审计日志i18n查询问题,重构消息对象为嵌套结构,添加共享标签助手和回归测试。

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/audit-log-actions-i18n-20260420

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.

@github-actions github-actions Bot added bug Something isn't working area:i18n area:UI labels Apr 20, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the audit log translation structure by converting flat dotted keys into nested objects across all supported locales. It introduces helper functions for label retrieval and adds unit tests to ensure translation keys are synchronized and cover all emitted audit actions. The review feedback suggests improving the codebase's consistency by using English for comments, refining the test scanner to exclude test files, and enhancing regex patterns to support both single and double quotes.

}

export function getAuditActionLabel(t: AuditLogTranslator, actionType: string): string {
// next-intl 缺失文案时会返回完整 key 字符串,因此这里必须先用 has() 判断。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The comment is in Chinese, while the rest of the codebase and PR description are in English. For consistency and better maintainability in an international project, it's recommended to use English for code comments.

Suggested change
// next-intl 缺失文案时会返回完整 key 字符串,因此这里必须先用 has() 判断。
// next-intl returns the full key string when a translation is missing, so we use has() to check existence and provide a cleaner fallback.


function collectEmittedAuditActionTypes(): string[] {
const srcRoot = path.join(REPO_ROOT, "src");
const files = walkFiles(srcRoot).filter((file) => file.endsWith(".ts") || file.endsWith(".tsx"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The file walker currently includes all .ts and .tsx files, including test files. If a test file contains dummy calls to emitActionAudit or createAuditLogAsync, it will incorrectly require those dummy keys to be present in the translation files. It's better to exclude test files from this scan.

Suggested change
const files = walkFiles(srcRoot).filter((file) => file.endsWith(".ts") || file.endsWith(".tsx"));
const files = walkFiles(srcRoot).filter((file) => (file.endsWith(".ts") || file.endsWith(".tsx")) && !file.includes(".test.") && !file.includes(".spec."));

Comment on lines +54 to +55
/emitActionAudit\(\s*\{[\s\S]*?action:\s*"([^"]+)"/g,
/createAuditLogAsync\(\s*\{[\s\S]*?actionType:\s*"([^"]+)"/g,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The regex patterns only match double-quoted strings. In many TypeScript projects, single quotes are also used. Improving the regex to support both quote types will make the test more robust against style changes.

Suggested change
/emitActionAudit\(\s*\{[\s\S]*?action:\s*"([^"]+)"/g,
/createAuditLogAsync\(\s*\{[\s\S]*?actionType:\s*"([^"]+)"/g,
/emitActionAudit\(\s*\{[\s\S]*?action:\s*["']([^"']+)["']/g,
/createAuditLogAsync\(\s*\{[\s\S]*?actionType:\s*["']([^"']+)["']/g,

@github-actions github-actions Bot added the size/L Large PR (< 1000 lines) label Apr 20, 2026
Comment on lines +91 to +93
act(() => {
root.render(node);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Consider @testing-library/react instead of raw createRoot

The test uses createRoot + act directly for rendering and relies on inspecting document.body.textContent. If @testing-library/react is already a project dependency, render + screen.getByText would give more targeted assertions, cleaner teardown, and easier-to-read test output — without the manual container.remove() teardown dance.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
Line: 91-93

Comment:
**Consider `@testing-library/react` instead of raw `createRoot`**

The test uses `createRoot` + `act` directly for rendering and relies on inspecting `document.body.textContent`. If `@testing-library/react` is already a project dependency, `render` + `screen.getByText` would give more targeted assertions, cleaner teardown, and easier-to-read test output — without the manual `container.remove()` teardown dance.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +79 to +90
test("store actions in nested objects instead of dotted leaf keys", () => {
for (const locale of LOCALES) {
const dottedKeys = getDirectDottedKeys(readLocaleActionTree(locale));
expect(dottedKeys, `${locale} should not contain dotted direct keys under actions`).toEqual(
[]
);
}
});

test("stay in sync across locales and cover every emitted audit action type", () => {
const canonicalKeys = flattenLeafKeys(readLocaleActionTree("en")).sort();
const emittedKeys = collectEmittedAuditActionTypes();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Sync test direction only catches missing translations, not extra ones

expect(canonicalKeys).toEqual(emittedKeys) does enforce bidirectional coverage, which is good. However, collectEmittedAuditActionTypes only matches string-literal arguments to emitActionAudit / createAuditLogAsync. Any action type constructed dynamically (e.g. via template literal or concatenation) would be silently missed, leaving the test with a false sense of full coverage. A comment noting this limitation would help future maintainers.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/unit/i18n/audit-log-actions-messages.test.ts
Line: 79-90

Comment:
**Sync test direction only catches missing translations, not extra ones**

`expect(canonicalKeys).toEqual(emittedKeys)` does enforce bidirectional coverage, which is good. However, `collectEmittedAuditActionTypes` only matches string-literal arguments to `emitActionAudit` / `createAuditLogAsync`. Any action type constructed dynamically (e.g. via template literal or concatenation) would be silently missed, leaving the test with a false sense of full coverage. A comment noting this limitation would help future maintainers.

How can I resolve this? If you propose a fix, please make it concise.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx (1)

24-24: 请使用 @/ 路径别名导入共享 helper。

新增 import 仍是相对路径,和当前仓库规范不一致。

建议修改
-import { getAuditActionLabel, getAuditCategoryLabel } from "./audit-log-labels";
+import {
+  getAuditActionLabel,
+  getAuditCategoryLabel,
+} from "@/app/[locale]/dashboard/audit-logs/_components/audit-log-labels";

As per coding guidelines, **/*.{ts,tsx,js,jsx}: Use path alias @/ mapped to ./src/ for imports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx at
line 24, The import for getAuditActionLabel and getAuditCategoryLabel uses a
relative path; update it to use the project path alias by importing these
helpers via '@/...' instead of a relative path so it follows the repository
convention (replace the current "./audit-log-labels" import with an alias import
that resolves to the same module containing getAuditActionLabel and
getAuditCategoryLabel).
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx (1)

63-63: 请用 @/ 路径别名导入被测组件。

新增测试里的组件 import 也应遵循仓库统一 import 规范。

建议修改
-import { AuditLogDetailSheet } from "./audit-log-detail-sheet";
+import { AuditLogDetailSheet } from "@/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet";

As per coding guidelines, **/*.{ts,tsx,js,jsx}: Use path alias @/ mapped to ./src/ for imports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/`[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
at line 63, 测试文件中直接使用相对路径导入组件,应改为使用仓库约定的 `@/` 路径别名;在
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
中把 import { AuditLogDetailSheet } from "./audit-log-detail-sheet"; 替换为使用 `@/`
别名的导入(导入 AuditLogDetailSheet 组件),确保引入路径以 `@/` 开头并映射到 ./src/ 下,使测试遵循项目统一的 import
规范。
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx (1)

12-12: 请把新增 helper import 改成 @/ 路径别名。

这里新增的相对路径导入和仓库 import 规范不一致。

建议修改
-import { getAuditActionLabel, getAuditCategoryLabel } from "./audit-log-labels";
+import {
+  getAuditActionLabel,
+  getAuditCategoryLabel,
+} from "@/app/[locale]/dashboard/audit-logs/_components/audit-log-labels";

As per coding guidelines, **/*.{ts,tsx,js,jsx}: Use path alias @/ mapped to ./src/ for imports.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx
at line 12, The import for helpers getAuditActionLabel and getAuditCategoryLabel
uses a relative path; change it to use the repository path alias (@" mapped to
./src/) so it follows project conventions — replace the relative import from
"./audit-log-labels" with an alias-based import like
"@/app/[locale]/dashboard/audit-logs/_components/audit-log-labels" (keeping the
same exported symbols getAuditActionLabel and getAuditCategoryLabel) to conform
to the import rules.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@src/app/`[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx:
- Line 63: 测试文件中直接使用相对路径导入组件,应改为使用仓库约定的 `@/` 路径别名;在
src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
中把 import { AuditLogDetailSheet } from "./audit-log-detail-sheet"; 替换为使用 `@/`
别名的导入(导入 AuditLogDetailSheet 组件),确保引入路径以 `@/` 开头并映射到 ./src/ 下,使测试遵循项目统一的 import
规范。

In
`@src/app/`[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx:
- Line 12: The import for helpers getAuditActionLabel and getAuditCategoryLabel
uses a relative path; change it to use the repository path alias (@" mapped to
./src/) so it follows project conventions — replace the relative import from
"./audit-log-labels" with an alias-based import like
"@/app/[locale]/dashboard/audit-logs/_components/audit-log-labels" (keeping the
same exported symbols getAuditActionLabel and getAuditCategoryLabel) to conform
to the import rules.

In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx:
- Line 24: The import for getAuditActionLabel and getAuditCategoryLabel uses a
relative path; update it to use the project path alias by importing these
helpers via '@/...' instead of a relative path so it follows the repository
convention (replace the current "./audit-log-labels" import with an alias import
that resolves to the same module containing getAuditActionLabel and
getAuditCategoryLabel).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 50c68550-1c72-4925-b8e3-6647cb0de312

📥 Commits

Reviewing files that changed from the base of the PR and between 3eb1326 and e82f6b3.

📒 Files selected for processing (10)
  • messages/en/auditLogs.json
  • messages/ja/auditLogs.json
  • messages/ru/auditLogs.json
  • messages/zh-CN/auditLogs.json
  • messages/zh-TW/auditLogs.json
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-labels.ts
  • src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx
  • tests/unit/i18n/audit-log-actions-messages.test.ts

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review Summary

No significant issues identified in this PR. Changes restructure auditLogs.actions into nested objects and update the audit log UI to resolve dotted action keys via t.has() before translating. New unit tests guard against locale drift and missing action translations.

PR Size: L

  • Lines changed: 617
  • Files changed: 10
  • Split suggestions: (1) i18n message key reshaping + UI helper adoption, (2) tests (UI translation + locale/key sync)

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Automated review by Codex AI

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • Reviewed PR #1041 (“fix: repair audit log action i18n labels”) against the diff in gh pr diff.
  • Computed size as L (468 additions + 149 deletions = 617 lines; 10 files) and applied label size/L.
  • Posted the required summary review via gh pr review --comment; no inline comments were submitted because no diff-line issues met the >=80 confidence threshold.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review Summary

Clean, well-scoped i18n bug fix. Restructures audit log action translations from flat dotted keys to nested objects compatible with next-intl resolution, centralizes translation helpers with proper t.has() guards, and adds regression tests for both UI rendering and cross-locale drift detection.

PR Size: L

  • Lines changed: 617 (468 additions, 149 deletions)
  • Files changed: 10

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Review Coverage

  • Logic and correctness - Verified action key resolution, fallback behavior, and cross-locale consistency across all 5 locales
  • Security (OWASP Top 10) - No security surface; UI-only i18n rendering
  • Error handling - t.has() guard correctly replaces prior try/catch; no silent failures
  • Type safety - AuditLogTranslator structural type is compatible with useTranslations return
  • Documentation accuracy - Comment in audit-log-labels.ts accurately explains next-intl key-resolution behavior
  • Test coverage - Component test covers translated and fallback paths; drift test validates all emitted action types (verified via source audit: login, user, provider, provider_group, system_settings, key, notification, sensitive_word, model_price) match i18n keys across all 5 locales
  • Code clarity - Shared helpers eliminate duplicated try/catch blocks in both UI surfaces

Automated review by Claude AI

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx (2)

255-260: 细节建议:避免对同一 action 计算两次标签。

actionLabel(log.actionType)title 和内容中分别调用了一次,每次都会走一次 t.has + t 查找。可在行渲染开头计算一次局部变量后复用,虚拟列表下对成千上万行的重复查找可略微减负。非阻塞。

♻️ 建议改动
                 const operator = log.operatorUserName ?? t("adminTokenOperator");
+                const actionText = actionLabel(log.actionType);
...
                     <div
                       className="flex-[1.2] min-w-[140px] font-mono text-xs px-1.5 truncate"
-                      title={actionLabel(log.actionType)}
+                      title={actionText}
                     >
-                      {actionLabel(log.actionType)}
+                      {actionText}
                     </div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx around
lines 255 - 260, 在渲染行时避免重复调用 actionLabel(log.actionType):在该行渲染开始处为
actionLabel(log.actionType) 计算一次局部变量(例如 const label =
actionLabel(log.actionType)),然后在 title 和内容处复用该变量,替换掉两处对 actionLabel 的重复调用(参见组件中的
actionLabel 和 log 用法);这样在虚拟列表大量行时能减少重复的 t.has/t 查找开销。

115-121: LGTM,可选小优化。

categoryLabel / actionLabel 目前只是对 helper 的薄封装,直接在渲染处调用 getAuditCategoryLabel(t, ...) / getAuditActionLabel(t, ...) 也可(或将其用 useCallback 记忆化以与组件内其他回调保持一致)。当前写法无功能问题,属于可延后的代码整洁性微调。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx around
lines 115 - 121, The wrappers categoryLabel and actionLabel are thin
passthroughs around getAuditCategoryLabel(t, ...) and getAuditActionLabel(t,
...); replace their usage in the render with direct calls to
getAuditCategoryLabel(t, cat) and getAuditActionLabel(t, actionType) or, if you
prefer to keep named callbacks, memoize them with React's useCallback (e.g.,
const categoryLabel = useCallback((cat) => getAuditCategoryLabel(t, cat), [t])
and similarly for actionLabel) so the code is either simplified or consistent
with other memoized callbacks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/app/`[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx:
- Around line 255-260: 在渲染行时避免重复调用 actionLabel(log.actionType):在该行渲染开始处为
actionLabel(log.actionType) 计算一次局部变量(例如 const label =
actionLabel(log.actionType)),然后在 title 和内容处复用该变量,替换掉两处对 actionLabel 的重复调用(参见组件中的
actionLabel 和 log 用法);这样在虚拟列表大量行时能减少重复的 t.has/t 查找开销。
- Around line 115-121: The wrappers categoryLabel and actionLabel are thin
passthroughs around getAuditCategoryLabel(t, ...) and getAuditActionLabel(t,
...); replace their usage in the render with direct calls to
getAuditCategoryLabel(t, cat) and getAuditActionLabel(t, actionType) or, if you
prefer to keep named callbacks, memoize them with React's useCallback (e.g.,
const categoryLabel = useCallback((cat) => getAuditCategoryLabel(t, cat), [t])
and similarly for actionLabel) so the code is either simplified or consistent
with other memoized callbacks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a22307de-37a0-42c2-9c55-0aa6bb594aea

📥 Commits

Reviewing files that changed from the base of the PR and between e82f6b3 and d236ce5.

📒 Files selected for processing (3)
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.tsx
  • src/app/[locale]/dashboard/audit-logs/_components/audit-logs-view.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/[locale]/dashboard/audit-logs/_components/audit-log-detail-sheet.test.tsx

@github-actions

Copy link
Copy Markdown
Contributor

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

@ding113
ding113 merged commit 6a74fe6 into dev Apr 20, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Claude Code Hub Roadmap Apr 20, 2026
@ding113
ding113 deleted the fix/audit-log-actions-i18n-20260420 branch May 13, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n area:UI bug Something isn't working size/L Large PR (< 1000 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant