Skip to content

refactor(studio): consolidate four delete modals into generic BulkDeleteModal#467

Open
aray12 wants to merge 12 commits into
mainfrom
astd-32-merge-near-rebased
Open

refactor(studio): consolidate four delete modals into generic BulkDeleteModal#467
aray12 wants to merge 12 commits into
mainfrom
astd-32-merge-near-rebased

Conversation

@aray12

@aray12 aray12 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added a reusable bulk delete dialog across the app, with item counts, customizable titles, and clearer confirm/cancel behavior.
    • Expanded bulk deletion in dataset and job views so multiple items can be removed from one flow.
  • Bug Fixes

    • Improved error messages when bulk deletions fail.
    • Kept delete actions disabled while requests are still in progress.
    • Updated history session labels to show clearer, more consistent titles.

@aray12 aray12 requested review from a team as code owners June 25, 2026 18:19
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 21099325-04cb-4828-87cd-17f3ff4f90e2

📥 Commits

Reviewing files that changed from the base of the PR and between bd62185 and dca7ad2.

📒 Files selected for processing (4)
  • web/packages/studio/src/api/common/useMutateMany.ts
  • web/packages/studio/src/components/BulkDeleteModal/index.tsx
  • web/packages/studio/src/components/DatasetsTable/index.test.tsx
  • web/packages/studio/src/components/DatasetsTable/index.tsx
💤 Files with no reviewable changes (4)
  • web/packages/studio/src/components/DatasetsTable/index.tsx
  • web/packages/studio/src/api/common/useMutateMany.ts
  • web/packages/studio/src/components/DatasetsTable/index.test.tsx
  • web/packages/studio/src/components/BulkDeleteModal/index.tsx

📝 Walkthrough >BulkDeleteModal: success or throws

BulkDeleteModal->>Consumer: onClose()

</diagram>
</layer>
<layer id="fileset_and_dataset_bulk_delete" title="Fileset and dataset bulk delete">
<summary>`FilesetFileExplorer/BulkDeleteModal` and `DatasetBulkDeleteModal` delegate confirmation UI to the shared modal, derive delete targets from selected items, and update their tests and triggers for the new props.</summary>
<ranges>
range_c577ab82fcf1
range_6fc240a6ae26
range_71296f92ee07
range_ebd6e5af9e1e
range_c864ec9242e7
range_4d41d18bedd7
range_e996cda1a1fb
range_ce2f5a22bbcb
range_0b7e92a05994
range_efb6f30c7cdd
range_40fde00979c3
range_bb791c22182e
range_898f510e2500
range_b8cde6f80fcf
range_04c41dda816c
range_e61b154d622c
</ranges>
</layer>
<layer id="job_bulk_delete_views" title="Job bulk delete views">
<summary>`DataDesignerJobsDataView` and `SafeSynthesizerJobsDataView` bulk-delete jobs through mutation callbacks, reset their query caches on success, and clear selection when the modal closes.</summary>
<ranges>
range_3746d515ba71
range_d417227d39bb
range_1a2d166934ae
range_4aec62597d37
range_f464122f21b9
range_4e69f4432ca9
range_02b721bd3458
range_36614e7c9ba6
</ranges>
</layer>
</cohort>
<cohort id="experiment_sort_handling" title="Experiment sort handling">
<summary>Experiment group sort typing and derivation were simplified.</summary>
<layer id="experiment_group_sort_derivation" title="Experiment group sort derivation">
<summary>`ExperimentGroupDataView` removes local sort helpers, uses `DEFAULT_SORT = -created_at`, and derives `sortParam` with `getSortParamWithWhitelist`.</summary>
<ranges>
range_97501818071d
range_a9c8eb8e540b
range_c47931380b2c
</ranges>
</layer>
</cohort>
<cohort id="claude_history_labels" title="Claude Code history labels">
<summary>Claude Code history title generation was removed and the history session button now renders prompt text directly.</summary>
<layer id="history_title_helper_removal" title="History title helper removal">
<summary>`historyPanel/helpers.ts` removes `getHistorySessionTitle` and its helper functions.</summary>
<ranges>
range_67ef797acab2
range_cecb052945c4
</ranges>
</layer>
<layer id="history_session_button_label" title="History session button label">
<summary>`HistorySessionButton` now shows `session.first_prompt` with a fixed two-line title, and the history panel fixture no longer includes `chat_artifacts`.</summary>
<ranges>
range_e0e791a54c2d
range_abd5d1ee7b16
range_f8821ab99160
</ranges>
</layer>
</cohort>
</review_stack_artifact-->

## Walkthrough

Introduces a generic `BulkDeleteModal<T>` component and migrates `DatasetBulkDeleteModal`, `FilesetFileExplorer/BulkDeleteModal`, `DataDesignerJobsDataView`, and `SafeSynthesizerJobsDataView` to use it. Removes per-feature `DeleteJobModal` files. `useMutateMany` gains an `action` option. `ExperimentGroupDataView` sort helpers are removed. `getHistorySessionTitle` is removed and `HistorySessionButton` renders `first_prompt` directly.

## Changes

**Bulk Delete Modal Migration**

| Layer / File(s) | Summary |
|---|---|
| **Shared `BulkDeleteModal` and `useMutateMany`** <br> `src/components/BulkDeleteModal/index.tsx`, `src/api/common/useMutateMany.ts` | New generic `BulkDeleteModal<T>` resolves dynamic titles, manages inline delete errors, and delegates to `DeleteConfirmationModal`. `useMutateMany` adds optional `action` string and handles non-`Error` rejections. |
| **Fileset and dataset bulk delete** <br> `src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.tsx`, `src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx`, `.../*.test.tsx`, `src/components/DatasetsTable/index.tsx`, `src/routes/FilesetListRoute/index.test.tsx` | Both fileset and dataset delete modals delegate to `GenericBulkDeleteModal`, introduce trigger cloning via `cloneElement`, and remove inline `Modal`/`Flex`/`logger` usage. Tests swap mocks to `@studio/components/BulkDeleteModal` and update assertions for pending state. `DatasetsTable` trigger button gains `aria-label`. |
| **Job bulk delete views** <br> `src/components/dataViews/DataDesignerJobsDataView/index.tsx`, `src/components/dataViews/SafeSynthesizerJobsDataView/index.tsx`, `src/components/dataViews/DataDesignerJobsDataView/DeleteJobModal.tsx`, `src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.tsx`, `src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.test.tsx` | Both data views replace per-item `DeleteJobModal` with `BulkDeleteModal`, add `handleDeleteJobs` with concurrent `mutateAsync` calls and query cache resets on success. Old `DeleteJobModal` files removed entirely. |

**Experiment Sort Simplification**

| Layer / File(s) | Summary |
|---|---|
| **`ExperimentGroupDataView` sort** <br> `src/components/dataViews/ExperimentGroupDataView/index.tsx` | Removes `SORT_PARAMS`/`SORT_PARAM_SET`/`getExperimentSortParam` helpers; derives `sortParam` via `getSortParamWithWhitelist` with a plain `DEFAULT_SORT` string. |

**Claude Code History Labels**

| Layer / File(s) | Summary |
|---|---|
| **Remove `getHistorySessionTitle`** <br> `src/routes/agents/ClaudeCodeChatRoute/historyPanel/helpers.ts`, `historyPanel/helpers.test.ts` | Removes exported `getHistorySessionTitle` and all private helpers; deletes the test file. |
| **`HistorySessionButton` renders `first_prompt`** <br> `src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx`, `ClaudeCodeHistoryPanel.test.tsx` | Button renders `session.first_prompt` with a fallback and builds a two-line `title`; fixture drops `chat_artifacts`. |

## Possibly related PRs

- [NVIDIA-NeMo/nemo-platform#457](https://github.com/NVIDIA-NeMo/nemo-platform/pull/457): Directly inverse change — adds `getHistorySessionTitle` and wires `HistorySessionButton` to use it, the exact function this PR removes.

## Suggested reviewers

- steramae-nvidia

</details>

<!-- walkthrough_end -->
<!-- pre_merge_checks_walkthrough_start -->

<details>
<summary>🚥 Pre-merge checks | ✅ 5</summary>

<details>
<summary>✅ Passed checks (5 passed)</summary>

|         Check name         | Status   | Explanation                                                                                                     |
| :------------------------: | :------- | :-------------------------------------------------------------------------------------------------------------- |
|      Description Check     | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                     |
|         Title check        | ✅ Passed | The title accurately summarizes the main change: replacing several delete modals with a shared BulkDeleteModal. |
|     Docstring Coverage     | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.                            |
|     Linked Issues check    | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                        |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                        |

</details>

</details>

<!-- pre_merge_checks_walkthrough_end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

<details>
<summary>📝 Generate docstrings</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId": "3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch

</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit unit tests in branch `astd-32-merge-near-rebased`

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---




<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>

<!-- tips_end -->

@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.

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (1)
web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx (1)

14-17: 📐 Maintainability & Code Quality | 🟡 Minor

Restore pending-state coverage. EvaluationJobBulkDeleteModal still disables Cancel/Delete and shows Deleting... via isPending, but the test file no longer exercises that state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx`
around lines 14 - 17, The BulkDeleteModal tests no longer cover the pending
deletion state exposed by useDatasetFilesDelete. Update the test suite in
BulkDeleteModal/index.test.tsx to mock and assert the isPending path for
EvaluationJobBulkDeleteModal, verifying that Cancel/Delete are disabled and the
label changes to “Deleting...” when useDatasetFilesDelete returns
isPending=true. Use the existing useDatasetFilesDelete mock and the
EvaluationJobBulkDeleteModal render path to restore this coverage.
🧹 Nitpick comments (1)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/useExperimentGroupExperiments.ts (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use import type for ListExperimentsSort.

It's referenced only in a type position (the L122 assertion).

As per coding guidelines: "Use import type for type-only imports in TypeScript." (Skip if it shares a value-import statement.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/useExperimentGroupExperiments.ts`
at line 15, The import of ListExperimentsSort in useExperimentGroupExperiments
is type-only, so update the existing import statement to use import type for it
rather than a value import. Locate the usage in useExperimentGroupExperiments
and keep it as a type import since it is only referenced in the L122 assertion
and does not need a runtime import.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/index.tsx`:
- Around line 63-75: The bulk delete flow in handleDeleteJobs currently filters
out jobs missing workspace, which can make the operation appear successful while
leaving selected rows undeleted. Update the DataDesignerJobsDataView deletion
logic to validate every selected DataDesignerJob before calling
deleteJobMutation.mutateAsync, and if any job lacks a workspace (or name), throw
an error instead of skipping it so the failure is surfaced to the user.

In
`@web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/index.tsx`:
- Around line 72-84: The bulk delete flow in handleDeleteJobs currently filters
incomplete rows but still relies on non-null assertions, and Promise.all will
reject on the first failure while other deletions continue. Update
SafeSynthesizerJobsDataView’s handleDeleteJobs to use a proper type guard that
narrows jobs with both workspace and name, validate the full selection up front
and abort the batch if any row is incomplete, and adjust the deletion loop so
all valid jobs are handled with clear per-job error reporting without masking
missing identifiers.

In
`@web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.tsx`:
- Around line 45-47: The BulkDeleteModal trigger wiring is overwriting any
existing click behavior and still relies on an `any` cast. Update the `trigger`
logic in `BulkDeleteModal` to properly type the `isValidElement` guard for
`slotTrigger`, then compose the cloned element’s existing `onClick` with
`openTrigger` instead of replacing it, so both handlers run in order without
using `any`.

In
`@web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx`:
- Line 23: The HistorySessionButton tooltip is currently showing only the
timestamp, which hides the session prompt and makes similar sessions hard to
distinguish. Update the title prop in HistorySessionButton so it includes the
full prompt again along with the timestamp, using the session data already
available in this component, while keeping the visible label unchanged.

In
`@web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx`:
- Line 34: The delete modal is reusing a create-oriented error message from
useMutateMany, so delete failures can surface as “Failed to create...”. Update
DatasetBulkDeleteModal to use a delete-specific error aggregator or extend
useMutateMany to accept an action label, and make sure the error text shown from
deleteDatasets is phrased for deletes rather than creates.
- Around line 36-44: The handleDelete flow in DatasetBulkDeleteModal currently
filters out datasets missing workspace or name and still calls
onConfirmSuccess(), which can report success after silently skipping selections.
Update handleDelete to validate the full datasets array up front, and if any
FilesetOutput is missing workspace or name, fail the operation instead of
proceeding; only call deleteDatasets and onConfirmSuccess() when every selected
dataset is valid. Use the existing handleDelete, deleteDatasets, and
onConfirmSuccess symbols to locate the change.
- Around line 49-51: The DatasetBulkDeleteModal trigger currently overwrites any
existing onClick on slotTrigger when cloning it in the trigger setup, so update
the cloneElement usage to compose the existing click handler with openTrigger
instead of replacing it, and remove the unnecessary React.ReactElement<any> cast
by using a properly typed element in this path.

---

Outside diff comments:
In
`@web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx`:
- Around line 14-17: The BulkDeleteModal tests no longer cover the pending
deletion state exposed by useDatasetFilesDelete. Update the test suite in
BulkDeleteModal/index.test.tsx to mock and assert the isPending path for
EvaluationJobBulkDeleteModal, verifying that Cancel/Delete are disabled and the
label changes to “Deleting...” when useDatasetFilesDelete returns
isPending=true. Use the existing useDatasetFilesDelete mock and the
EvaluationJobBulkDeleteModal render path to restore this coverage.

---

Nitpick comments:
In
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/useExperimentGroupExperiments.ts`:
- Line 15: The import of ListExperimentsSort in useExperimentGroupExperiments is
type-only, so update the existing import statement to use import type for it
rather than a value import. Locate the usage in useExperimentGroupExperiments
and keep it as a type import since it is only referenced in the L122 assertion
and does not need a runtime import.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 218ee35b-5c93-4b87-9658-5613d05a6475

📥 Commits

Reviewing files that changed from the base of the PR and between e5608bf and 38f8bb4.

📒 Files selected for processing (19)
  • web/packages/studio/src/components/BulkDeleteModal/index.tsx
  • web/packages/studio/src/components/DatasetsTable/index.test.tsx
  • web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/DeleteJobModal.tsx
  • web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/index.tsx
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/useExperimentGroupExperiments.ts
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.test.tsx
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.tsx
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/index.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/extractFilePathsFromDirectory.ts
  • web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.test.tsx
  • web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx
  • web/packages/studio/src/routes/FilesetListRoute/index.test.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/ClaudeCodeHistoryPanel.test.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/helpers.test.ts
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/helpers.ts
💤 Files with no reviewable changes (6)
  • web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/DeleteJobModal.tsx
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/helpers.test.ts
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/DeleteJobModal.test.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/ClaudeCodeHistoryPanel.test.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/helpers.ts

Comment thread web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx Outdated
Comment thread web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx Outdated
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 21936/28740 76.3% 61.0%
Integration Tests 12599/27420 46.0% 19.3%

@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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx (1)

11-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract props into an interface and add an explicit return type.

This exported component still uses an inline object shape and inferred JSX return, which breaks the TypeScript rules used under web/**/*.tsx.

Suggested refactor
+interface HistorySessionButtonProps {
+  active: boolean;
+  onSelect: () => void;
+  session: ClaudeCodeHistorySession;
+}
+
 export const HistorySessionButton = ({
   active,
   onSelect,
   session,
-}: {
-  active: boolean;
-  onSelect: () => void;
-  session: ClaudeCodeHistorySession;
-}) => (
+}: HistorySessionButtonProps): React.JSX.Element => (

As per coding guidelines, "Prefer interface over type for object shapes and contracts in TypeScript" and "Use explicit return types for public APIs and complex functions in TypeScript".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx`
around lines 11 - 19, Extract the props from HistorySessionButton into a named
interface instead of the inline object type, then update the exported component
signature to use that interface and add an explicit JSX return type. Keep the
refactor scoped to HistorySessionButton so the public API is clear and the
component satisfies the TypeScript rules under web/**/*.tsx.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/packages/studio/src/api/common/useMutateMany.ts`:
- Around line 33-35: The error aggregation in useMutateMany assumes every
rejection has a message property, which breaks when a failure reason is null, a
string, or a plain object. Update the failedItems handling in useMutateMany to
safely normalize each failure.reason into a readable string before joining, and
preserve the existing action/items summary in the thrown Error. Use the
failure.reason and failedItems mapping logic as the place to add a non-Error
guard.

In
`@web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx`:
- Around line 303-305: The pending-state assertion in BulkDeleteModal should
verify both actions, not just the Cancel button. Update the test around the
dialog assertions to also check the primary Delete button in the same state
after the mutation starts, using the existing dialog and button queries in
BulkDeleteModal/index.test.tsx so the test fails if Delete remains enabled
during loading.

---

Nitpick comments:
In
`@web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx`:
- Around line 11-19: Extract the props from HistorySessionButton into a named
interface instead of the inline object type, then update the exported component
signature to use that interface and add an explicit JSX return type. Keep the
refactor scoped to HistorySessionButton so the public API is clear and the
component satisfies the TypeScript rules under web/**/*.tsx.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 130adc4c-0503-4c70-b723-3d8e2feed404

📥 Commits

Reviewing files that changed from the base of the PR and between e62d85c and 47a442f.

📒 Files selected for processing (7)
  • web/packages/studio/src/api/common/useMutateMany.ts
  • web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/index.tsx
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/index.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.test.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.tsx
  • web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx
  • web/packages/studio/src/routes/agents/ClaudeCodeChatRoute/historyPanel/HistorySessionButton.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/packages/studio/src/components/dataViews/DataDesignerJobsDataView/index.tsx
  • web/packages/studio/src/components/dataViews/SafeSynthesizerJobsDataView/index.tsx
  • web/packages/studio/src/routes/FilesetListRoute/DatasetBulkDeleteModal/index.tsx
  • web/packages/studio/src/components/filesets/FilesetFileExplorer/BulkDeleteModal/index.tsx

Comment thread web/packages/studio/src/api/common/useMutateMany.ts Outdated
aray12 added 12 commits June 29, 2026 16:15
…eteModal

Signed-off-by: Alex Ray <alray@nvidia.com>
Three fixes:
- Remove stale ListExperimentsSort import (not in regenerated SDK since the
  spec defines sort as free-form string); use ListExperimentsParams['sort']
  cast instead so the cast derives from whatever the SDK generates
- Add aria-label="Delete selected datasets" to the bulk delete trigger in
  DatasetsTable so the existing test selector still finds it
- Fix loading-state test in DatasetBulkDeleteModal: reuse pre-click button
  reference instead of re-querying, since LoadingButton appends a spinner
  with aria-label="Loading..." which changes the accessible name

Signed-off-by: Alex Ray <alray@nvidia.com>
…ew bulk delete

Validates all selected jobs have workspace and name before starting any
deletions, rather than silently filtering out invalid rows and reporting
success on a partial batch.

Signed-off-by: Alex Ray <alray@nvidia.com>
…aView bulk delete

Same up-front validation as the DataDesigner fix: aborts the entire
batch with an error if any selected job is missing workspace or name,
rather than silently skipping invalid rows.

Signed-off-by: Alex Ray <alray@nvidia.com>
…eleteModal

Replace the cloneElement override that dropped any existing onClick with
one that calls the original handler first, then opens the modal. Removes
the React.ReactElement<any> cast by typing via isValidElement<TriggerProps>.

Signed-off-by: Alex Ray <alray@nvidia.com>
…t skip

- Compose slotTrigger's existing onClick with openTrigger instead of
  replacing it; removes React.ReactElement<any> cast.
- Throw an error if any selected dataset lacks workspace or name rather
  than silently skipping and reporting success on a partial batch.

Signed-off-by: Alex Ray <alray@nvidia.com>
Add an optional `action` param (default "create") so callers can pass
"delete" and get a correctly-phrased error instead of "Failed to create
N items". Update DatasetBulkDeleteModal to pass action: 'delete'.

Signed-off-by: Alex Ray <alray@nvidia.com>
The visible label is line-clamped to 2 lines, so sessions with similar
prefixes become hard to distinguish. Include the first prompt alongside
the timestamp in the title attribute so hovering reveals the full text.

Signed-off-by: Alex Ray <alray@nvidia.com>
…BulkDeleteModal

Add a test that holds the delete mutation in-flight and asserts the
Cancel button is disabled, exercising the isPending path that was
dropped during the consolidation refactor.

Signed-off-by: Alex Ray <alray@nvidia.com>
failure.reason.message crashes when a promise rejects with a non-Error
value. Normalize via instanceof check with String() fallback.

Signed-off-by: Alex Ray <alray@nvidia.com>
The delete button's accessible name becomes "Delete Loading..." when the
spinner mounts, so use /delete/i to match both states. Adds the missing
assertion for the submit button alongside the existing Cancel check.

Signed-off-by: Alex Ray <alray@nvidia.com>
… return type

Extract inline props into a named interface and annotate the component
with an explicit React.JSX.Element return type per TypeScript guidelines.

Signed-off-by: Alex Ray <alray@nvidia.com>
@aray12 aray12 force-pushed the astd-32-merge-near-rebased branch from bd62185 to dca7ad2 Compare June 29, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant