Skip to content

fix: add shouldIgnoreRowClick guard to all unprotected tables#4562

Open
GanJiaKouN16 wants to merge 2 commits into
Agenta-AI:mainfrom
GanJiaKouN16:fix/table-row-click-behavior
Open

fix: add shouldIgnoreRowClick guard to all unprotected tables#4562
GanJiaKouN16 wants to merge 2 commits into
Agenta-AI:mainfrom
GanJiaKouN16:fix/table-row-click-behavior

Conversation

@GanJiaKouN16
Copy link
Copy Markdown

Summary

Fixes #3254 — several tables with row-level click navigation were missing the shouldIgnoreRowClick guard, causing clicks on interactive elements (checkboxes, dropdowns, buttons) to accidentally trigger row navigation.

Changes

Consolidated shared utility

  • packages/agenta-ui/.../useTableManager.tsx and oss/.../useTableManager.tsx: Expanded shouldIgnoreRowClick with broader selectors (merges extra selectors from EvaluationRunsTablePOC: [role='button'], [role='menuitem'], [role='checkbox'], .ant-btn, select, etc.). Exported INTERACTIVE_ROW_SELECTORS constant for reuse.
  • packages/agenta-ui/.../useEntityTableState.ts: Updated to use consolidated selectors instead of its own narrower list.

Tables fixed (6 previously unprotected)

Table File Fix
ObservabilityTable (Traces) observability/.../ObservabilityTable/index.tsx Added shouldIgnoreRowClick guard
SessionsTable observability/.../SessionsTable/index.tsx Added shouldIgnoreRowClick guard
PromptsPage prompts/PromptsPage.tsx Added shouldIgnoreRowClick guard
TestcasesTableShell TestcasesTableNew/.../TestcasesTableShell.tsx Added shouldIgnoreRowClick guard
EntityTable agenta-entity-ui/.../EntityTable.tsx Added shouldIgnoreRowClick guard
ScenarioListView agenta-annotation-ui/.../ScenarioListView.tsx Replaced partial data-ivt-stop-row-click check with full shouldIgnoreRowClick

Cleanup

  • navigationActions.ts: Removed duplicate shouldIgnoreRowClick and unused MouseEvent import.
  • EvaluationRunsTable/index.tsx: Updated import to use shared utility from InfiniteVirtualTable.

Testing

  • No logic changes to already-protected tables (TestsetsTable, EvaluatorsTable, RegistryTable, AnnotationQueuesView, EvaluationRunsTablePOC)
  • Each fix follows the same pattern: onClick: (event) => { if (shouldIgnoreRowClick(event)) return; ... }
  • The consolidated selector list is a superset of all previous implementations, so no previously-blocked elements will be unblocked

Closes #3254

Wire the existing GenerateResetLinkModal and PasswordResetLinkModal
into the Actions dropdown in the workspace members table.

- Add 'Reset password' menu item for workspace members (not self)
- Add resetPassword API function in profile service
- Show confirmation dialog before generating the reset link
- Display the generated password reset link with copy functionality

Closes Agenta-AI#2572
Several tables with row-level click navigation were missing the
shouldIgnoreRowClick guard, causing clicks on interactive elements
(checkboxes, dropdowns, buttons) to accidentally trigger row navigation.

Changes:
- Consolidate shouldIgnoreRowClick with broader selector list (merges
  EvaluationRunsTablePOC's extra selectors: [role='button'],
  [role='menuitem'], [role='checkbox'], .ant-btn, etc.)
- Export INTERACTIVE_ROW_SELECTORS constant for reuse
- Add guard to ObservabilityTable (traces)
- Add guard to SessionsTable
- Add guard to PromptsPage
- Add guard to TestcasesTableShell
- Add guard to EntityTable
- Replace partial data-ivt-stop-row-click check in ScenarioListView
  with full shouldIgnoreRowClick
- Update useEntityTableState to use consolidated selectors
- Remove duplicate shouldIgnoreRowClick from navigationActions.ts
- Update EvaluationRunsTablePOC to import from shared utility

Closes Agenta-AI#3254
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 6, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

Someone is attempting to deploy a commit to the agenta projects Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 6, 2026

CLA assistant check
All committers have signed the CLA.

@dosubot dosubot Bot added Bug Report Something isn't working Frontend labels Jun 6, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Password reset workflow for workspace members added to member management.
  • Bug Fixes

    • Unified and improved table row-click handling across the app to avoid unintended navigation when interacting with buttons, inputs, checkboxes, menus or other interactive elements; expanded detection to cover more UI patterns for consistent behavior.

Walkthrough

Centralizes interactive-element selectors into INTERACTIVE_ROW_SELECTORS, refactors shouldIgnoreRowClick to use a single closest() check, applies the guard across OSS and package table components, and adds a workspace member reset-password API plus a two-step modal UI.

Changes

Interactive Row Click Filtering Refactoring

Layer / File(s) Summary
Core selector consolidation and helper refactor
web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
Adds INTERACTIVE_ROW_SELECTORS and refactors shouldIgnoreRowClick to use event.target.closest(INTERACTIVE_ROW_SELECTORS) with a null-safe target guard.
Remove local helper and rewire imports
web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts, web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
Removes local shouldIgnoreRowClick and its MouseEvent type import; EvaluationRunsTable now imports shouldIgnoreRowClick from the centralized InfiniteVirtualTable module.
Apply row-click guard to OSS tables
web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx, web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx, web/oss/src/components/pages/observability/components/SessionsTable/index.tsx, web/oss/src/components/pages/prompts/PromptsPage.tsx
Row click handlers updated to accept the click event and return early when shouldIgnoreRowClick(event) is true, preventing interactive-element clicks from triggering navigation or selection.
Apply guard to packages and centralize selector derivation
web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx, web/packages/agenta-entity-ui/src/shared/EntityTable.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
Package components import and use shouldIgnoreRowClick; useEntityTableState now derives default interactive selectors from INTERACTIVE_ROW_SELECTORS instead of a hardcoded list.

Workspace Member Reset Password Feature

Layer / File(s) Summary
Reset password API service
web/oss/src/services/profile/index.ts
Adds resetPassword(userId) which POSTs to api/profile/reset-password with user_id query param and returns the reset link string.
Reset password workflow UI
web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
Imports Key icon and resetPassword, adds GenerateResetLinkModal and PasswordResetLinkModal, introduces modal state and loading flow, implements handleResetPassword, adds conditional "Reset password" menu item, and renders both modals with callbacks and link data.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as WorkspaceManage Actions
  participant Modal1 as GenerateResetLinkModal
  participant API as resetPassword Service
  participant Modal2 as PasswordResetLinkModal

  User->>UI: Click "Reset password" menu item
  UI->>Modal1: Show generate modal
  User->>Modal1: Confirm generate
  Modal1->>API: POST /api/profile/reset-password?user_id=...
  API-->>Modal1: Return reset link
  Modal1->>UI: onOk callback
  UI->>UI: Store link, update modal states
  UI->>Modal2: Show reset link modal
  Modal2-->>User: Display reset link
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding shouldIgnoreRowClick guards to unprotected tables to fix row click behavior issues.
Description check ✅ Passed The description is well-related to the changeset, detailing the consolidated utility changes, tables fixed, cleanup work, and testing approach.
Linked Issues check ✅ Passed The PR successfully addresses issue #3254 by adding shouldIgnoreRowClick guards to six unprotected tables and consolidating selectors to prevent accidental navigation on interactive element clicks.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing row click behavior: consolidating shouldIgnoreRowClick utility, adding guards to unprotected tables, and removing duplicate code.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 60.00%.

✏️ 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
Copy Markdown

@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

🧹 Nitpick comments (1)
web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts (1)

232-251: 💤 Low value

Consider refactoring to use single closest() call for consistency and performance.

The current implementation iterates through selectors and calls closest() multiple times:

const isInteractive = interactiveSelectors.some((selector) =>
    target.closest(selector),
)

For consistency with shouldIgnoreRowClick (which uses a single closest() call against the joined selector string), consider:

const interactiveSelectorString = useMemo(
    () => [...DEFAULT_INTERACTIVE_SELECTORS, ...excludeClickSelectors].join(", "),
    [excludeClickSelectors],
)

// In buildRowHandlers:
const isInteractive = Boolean(target.closest(interactiveSelectorString))

This matches the pattern in useTableManager.tsx and avoids multiple DOM traversals.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e74ab297-ae30-41a7-ad31-bdd07856a672

📥 Commits

Reviewing files that changed from the base of the PR and between 98b8a9d and 6dfce59.

📒 Files selected for processing (13)
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/oss/src/components/pages/observability/components/SessionsTable/index.tsx
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
  • web/oss/src/services/profile/index.ts
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
💤 Files with no reviewable changes (1)
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts

Comment on lines +207 to +220
<GenerateResetLinkModal
open={generateResetLinkOpen}
username={user.username}
onCancel={() => setGenerateResetLinkOpen(false)}
onOk={handleResetPassword}
confirmLoading={resetLoading}
/>

<PasswordResetLinkModal
open={resetLinkOpen}
username={user.username}
generatedLink={resetLink}
onCancel={() => setResetLinkOpen(false)}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the modal components use EnhancedModal or raw antd Modal

fd -e tsx -e ts 'GenerateResetLinkModal|PasswordResetLinkModal' web/oss/src/components/pages/settings/WorkspaceManage/Modals/ --exec cat {}

Repository: Agenta-AI/agenta

Length of output: 4194


Switch WorkspaceManage reset modals to EnhancedModal

  • web/oss/src/components/pages/settings/WorkspaceManage/Modals/GenerateResetLinkModal.tsx imports and renders Modal from antd (should use EnhancedModal from @agenta/ui).
  • web/oss/src/components/pages/settings/WorkspaceManage/Modals/PasswordResetLinkModal.tsx imports and renders Modal from antd (should use EnhancedModal from @agenta/ui).

Source: Coding guidelines

Comment on lines +60 to +72
/**
* Generate a password reset link for a user (admin action).
* Returns the reset password link string.
*/
export const resetPassword = async (userId: string): Promise<string> => {
const base = getBaseUrl()
const url = new URL("api/profile/reset-password", base)
url.searchParams.set("user_id", userId)
const data = await fetchJson<string>(url, {
method: "POST",
})
return data
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the Fern-generated client exports a method for password reset

rg -n -C3 'resetUserPassword|reset.*password' --type=ts --iglob '**/agenta-api-client/**'

Repository: Agenta-AI/agenta

Length of output: 5484


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Find ResetUserPasswordRequest shape and response handling
rg -n --type=ts 'ResetUserPasswordRequest' web/packages/agenta-api-client/src/generated/api -S

Repository: Agenta-AI/agenta

Length of output: 809


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the request interface
echo "---- ResetUserPasswordRequest.ts ----"
sed -n '1,120p' web/packages/agenta-api-client/src/generated/api/resources/users/client/requests/ResetUserPasswordRequest.ts

# Read the relevant portion of UsersClient.resetUserPassword
echo "---- Client.ts (resetUserPassword) ----"
sed -n '130,260p' web/packages/agenta-api-client/src/generated/api/resources/users/client/Client.ts

Repository: Agenta-AI/agenta

Length of output: 4067


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n --type=ts --type=tsx '\.resetUserPassword\(' web/oss web/ee web -S

Repository: Agenta-AI/agenta

Length of output: 88


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n '\.resetUserPassword\(' -S --glob '**/*.ts' --glob '**/*.tsx' web/oss web/ee

Repository: Agenta-AI/agenta

Length of output: 42


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n 'resetUserPassword' -S --glob '**/*.ts' --glob '**/*.tsx' web/oss web/ee

Repository: Agenta-AI/agenta

Length of output: 42


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n --glob '**/*.ts' --glob '**/*.tsx' 'getAgentaSdkClient\(\{host: getAgentaApiUrl\(\)\}\)' web/oss web/ee

Repository: Agenta-AI/agenta

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,120p' web/oss/src/components/pages/_app/index.tsx

Repository: Agenta-AI/agenta

Length of output: 3896


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n 'ResetUserPasswordResponse|resetUserPassword.*Response|reset password' web/packages/agenta-api-client/src/generated/api/resources/users/client -S

Repository: Agenta-AI/agenta

Length of output: 233


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n 'reset-password|ResetUserPassword' web/packages/agenta-api-client/src/generated/api -S

Repository: Agenta-AI/agenta

Length of output: 1139


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n 'profile/reset-password|reset_password|resetUserPassword' web/packages/agenta-api-client/src/generated/api -S

Repository: Agenta-AI/agenta

Length of output: 1066


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Find how the SDK responses are consumed (e.g., `.data`)
rg -n --glob '**/*.ts' --glob '**/*.tsx' \
  '\.data(\b|$)|rawResponse|HttpResponsePromise' web/oss/src web/ee/src \
  || true

Repository: Agenta-AI/agenta

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Find how the SDK client return values are consumed (e.g., awaiting and reading `.data`)
rg -n --glob '**/*.ts' --glob '**/*.tsx' 'getAgentaSdkClient\(' web/oss web/ee

Repository: Agenta-AI/agenta

Length of output: 153


Use the Fern-generated client for resetPassword

resetPassword manually builds the URL and uses fetchJson, but the Fern SDK already exposes client.users.resetUserPassword({ user_id }) for the POST profile/reset-password endpoint. Refactor to call that method via getAgentaSdkClient({ host: getAgentaApiUrl() }) and keep the return value consistent with the current Promise<string> contract.

Source: Coding guidelines

@GanJiaKouN16 GanJiaKouN16 force-pushed the fix/table-row-click-behavior branch from 6dfce59 to 445fc3f Compare June 6, 2026 16:01
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts (1)

232-251: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Refactor to follow the centralized click detection pattern and improve efficiency.

The inline click detection logic duplicates the pattern already centralized in shouldIgnoreRowClick. The current implementation calls closest() multiple times (once per selector), while the centralized helper passes the full comma-separated selector string to a single closest() call, which is more efficient and consistent.

Since this hook supports custom excludeClickSelectors, combine them with INTERACTIVE_ROW_SELECTORS into a single selector string and follow the same pattern as shouldIgnoreRowClick.

♻️ Proposed refactor to align with centralized pattern
-    // Combine selectors for interactive elements
-    const interactiveSelectors = useMemo(
-        () => [...DEFAULT_INTERACTIVE_SELECTORS, ...excludeClickSelectors],
-        [excludeClickSelectors],
+    // Combine default and custom selectors into a single selector string for efficient matching
+    const combinedSelectors = useMemo(
+        () =>
+            excludeClickSelectors.length > 0
+                ? `${INTERACTIVE_ROW_SELECTORS}, ${excludeClickSelectors.join(", ")}`
+                : INTERACTIVE_ROW_SELECTORS,
+        [excludeClickSelectors],
     )
 
     // Build row handlers for click events
     const buildRowHandlers = useCallback(
         (record: TRow) => {
             const isNavigable = !record.__isSkeleton
 
             return {
                 onClick: (event: MouseEvent<HTMLTableRowElement>) => {
                     if (!isNavigable || !onRowClick) return
 
-                    // Check if clicking on interactive elements
+                    // Check if clicking on interactive elements (follows shouldIgnoreRowClick pattern)
                     const target = event.target as HTMLElement
-                    const isInteractive = interactiveSelectors.some((selector) =>
-                        target.closest(selector),
-                    )
+                    if (!target) return
+                    const isInteractive = target.closest(combinedSelectors)
                     if (isInteractive) return
 
                     onRowClick(record)
                 },
                 className: "entity-table__row",
                 style: {
                     cursor: isNavigable && onRowClick ? "pointer" : "default",
                     height: rowHeight,
                     minHeight: rowHeight,
                 } as CSSProperties,
             }
         },
-        [onRowClick, rowHeight, interactiveSelectors],
+        [onRowClick, rowHeight, combinedSelectors],
     )

This approach:

  • Uses a single closest() call instead of looping through selectors
  • Follows the same pattern as the centralized shouldIgnoreRowClick
  • Adds a defensive null check on target
  • Maintains support for custom excludeClickSelectors

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7741bd1a-d2b5-42c7-981d-2ad00b0172e7

📥 Commits

Reviewing files that changed from the base of the PR and between 6dfce59 and 445fc3f.

📒 Files selected for processing (13)
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/oss/src/components/pages/observability/components/SessionsTable/index.tsx
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
  • web/oss/src/services/profile/index.ts
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
💤 Files with no reviewable changes (1)
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • web/oss/src/components/pages/observability/components/SessionsTable/index.tsx
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/services/profile/index.ts
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx

Comment on lines +100 to +104
const handleResetPassword = async () => {
setResetLoading(true)
try {
const link = await resetPassword(user.id)
setGenerateResetLinkOpen(false)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Route reset-password through the Fern SDK client, not the manual fetch path.

This handler now depends on a new API call path, but resetPassword is implemented with manual URL + fetchJson instead of the Fern client contract used in web/**/*.{ts,tsx}. Please migrate that service call to getAgentaSdkClient({host: getAgentaApiUrl()}) and pass params via {queryParams: {...}} before merge.

As per coding guidelines, all new frontend API code must go through the Fern-generated client and use {queryParams} rather than axios/fetch-style params.

Source: Coding guidelines

Comment on lines +215 to +220
<PasswordResetLinkModal
open={resetLinkOpen}
username={user.username}
generatedLink={resetLink}
onCancel={() => setResetLinkOpen(false)}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear the generated reset link when closing the modal.

On Line 219, close only toggles resetLinkOpen; the reset URL remains in state. Since this is a sensitive token, clear it on close (and optionally before a new generation) to reduce in-memory retention.

Suggested patch
             <PasswordResetLinkModal
                 open={resetLinkOpen}
                 username={user.username}
                 generatedLink={resetLink}
-                onCancel={() => setResetLinkOpen(false)}
+                onCancel={() => {
+                    setResetLinkOpen(false)
+                    setResetLink("")
+                }}
             />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Report Something isn't working Frontend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[UI/UX] Improve click behavior in tables

2 participants