Skip to content

fix(ui): land on a draft after deleting the active thread - #141

Merged
marmeladema merged 1 commit into
mainfrom
fix/delete-active-thread-opens-draft
Jul 28, 2026
Merged

fix(ui): land on a draft after deleting the active thread#141
marmeladema merged 1 commit into
mainfrom
fix/delete-active-thread-opens-draft

Conversation

@marmeladema

@marmeladema marmeladema commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Problem

Deleting the currently-open thread left the UI showing an empty transcript still titled with the deleted thread's name, with the composer hidden and a "No thread selected" status. The user had to manually open a new thread to keep working.

Fix

When the delete-thread confirmation handler determines the active view was the deleted thread (or a cascaded descendant), instead of clearThreadView it now:

  1. Removes giskard.lastThread from localStorage so a reload no longer resurrects the deleted thread.
  2. Calls openDraftThread(pid) — the same path the per-project "+" uses — to drop into a fresh draft in the same project: composer visible and focused, title reset to "New thread", draft explainer in the transcript, WebSocket torn down, state.threadId cleared.
  3. Calls applyProjectDefaultModel(pid, state.draftThread) (fire-and-forget, matching newThread) to resolve the project's default model in the background.
  4. Skips the modal's focus restoration so the composer input keeps focus (otherwise it would jump back to the deleted thread's row button).

The cross-project deletion guard is unchanged: deleting a thread in another project while viewing one here still leaves the active view untouched. clearThreadView is left intact for the archive path and clearProjectView, which legitimately leave no active thread.

Test

New active-thread deletion lands on a draft describe block in tests/e2e/tests/subagents.spec.ts: seeds an isolated project + thread server-side, opens it, deletes it via the row menu, and asserts the view is now a draft in the same project (composer/#input visible, #mbTitle contains "New thread", #transcript .draft-empty visible, no "No thread selected", giskard.lastThread is null).

Verification

  • New test passes.
  • Full subagents.spec.ts (8) passes — including the existing cross-project deletion and confirmation-card tests.
  • thread.spec.ts, thread-selection.spec.ts, draft-composer.spec.ts (18) pass — no regressions in draft/thread interactions.

No README/screenshots regeneration needed: no config keys, endpoints, or storage layout touched, and the screenshot generator captures a populated thread state, never the draft-after-delete state.

Summary by CodeRabbit

  • Bug Fixes
    • Deleting the currently open thread now takes you to a fresh draft in the same project (applying the project’s default model) instead of clearing the view.
    • Clears the saved “last opened thread” so a deleted thread won’t reappear after reload.
    • Adjusts modal focus restoration to account for the draft composer being opened.
  • Tests
    • Added an end-to-end Playwright test covering active thread deletion → draft landing, including focus and persistence behavior.
    • Updated the UI smoke test assertions to match the new deletion flow.

@coderabbitai

coderabbitai Bot commented Jul 28, 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
📝 Walkthrough

Walkthrough

Deleting the active thread now opens a fresh draft in the same project, clears giskard.lastThread, applies the project default model, and preserves composer focus. UI smoke and E2E tests verify the updated behavior.

Changes

Active thread deletion

Layer / File(s) Summary
Draft fallback after active deletion
crates/giskard-server/static/app.js
Active-thread deletion clears persisted thread state, opens a project draft with its default model, and skips modal focus restoration when the draft composer is focused.
Served-page deletion contract
crates/giskard-server/tests/ui.rs
Smoke-test assertions now require draft creation and project-default-model application after thread deletion.
End-to-end deletion validation
tests/e2e/tests/subagents.spec.ts
Seeds a project and persisted thread, deletes the active thread, and verifies the draft UI, composer focus, and giskard.lastThread cleanup.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DeleteHandler
  participant LocalStorage
  participant DraftThread
  participant ProjectModel
  participant Composer
  User->>DeleteHandler: Confirm active thread deletion
  DeleteHandler->>LocalStorage: Remove giskard.lastThread
  DeleteHandler->>DraftThread: Open draft in same project
  DeleteHandler->>ProjectModel: Apply project default model
  DraftThread->>Composer: Focus composer input
  DeleteHandler-->>User: Show New thread draft
Loading

Possibly related PRs

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main UI change: deleting the active thread now lands on a draft.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/delete-active-thread-opens-draft

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

@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 (1)
tests/e2e/tests/subagents.spec.ts (1)

414-418: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert composer focus after deletion.

The new handler intentionally avoids restoring modal focus, but this test only checks visibility. Assert #input is focused to protect that UX contract.

Proposed test addition
 await expect(page.locator("`#composer`")).toBeVisible();
 await expect(page.locator("`#input`")).toBeVisible();
+await expect(page.locator("`#input`")).toBeFocused();
 await expect(page.locator("`#mbTitle`")).toContainText("New thread");
🤖 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 `@tests/e2e/tests/subagents.spec.ts` around lines 414 - 418, Update the
deletion-flow assertions in the end-to-end test to verify that `#input` is
focused, not merely visible. Keep the existing visibility and transcript
assertions unchanged while adding the focus assertion for the composer input.
🤖 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.

Nitpick comments:
In `@tests/e2e/tests/subagents.spec.ts`:
- Around line 414-418: Update the deletion-flow assertions in the end-to-end
test to verify that `#input` is focused, not merely visible. Keep the existing
visibility and transcript assertions unchanged while adding the focus assertion
for the composer input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d22fb471-8705-4293-8af9-3edf3bf2ef1e

📥 Commits

Reviewing files that changed from the base of the PR and between 1e38742 and 2e60123.

📒 Files selected for processing (2)
  • crates/giskard-server/static/app.js
  • tests/e2e/tests/subagents.spec.ts

@marmeladema
marmeladema force-pushed the fix/delete-active-thread-opens-draft branch 3 times, most recently from a1e143e to b46b3b1 Compare July 28, 2026 10:47

@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: 1

🤖 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 `@crates/giskard-server/static/app.js`:
- Around line 1559-1563: Update the thread-loading flow around loadThreads and
the openedDraft condition so loadThreads returns whether refreshing succeeded.
Only evaluate knownThreadForId(pid, activeThread) when that refresh succeeded;
when it fails, rely solely on deletedIds while preserving the existing draft
behavior for confirmed missing threads.
🪄 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: Pro Plus

Run ID: f3a72283-4db3-4dda-af47-f06ed9be1771

📥 Commits

Reviewing files that changed from the base of the PR and between a1e143e and b46b3b1.

📒 Files selected for processing (3)
  • crates/giskard-server/static/app.js
  • crates/giskard-server/tests/ui.rs
  • tests/e2e/tests/subagents.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/giskard-server/tests/ui.rs
  • tests/e2e/tests/subagents.spec.ts

Comment thread crates/giskard-server/static/app.js
Deleting the currently-open thread left the view titled with the deleted
thread's name and an empty transcript ("No thread selected"). Open a fresh
draft in the same project instead, so the composer is ready for the next
conversation: tear down the WebSocket, reset the title to "New thread",
show the draft explainer, resolve the project's default model, and clear
giskard.lastThread so a reload no longer resurrects the deleted thread.
Skip the modal's focus restoration in this path so the composer input keeps
focus.

Update the Rust UI string assertion to match the new openDraftThread call
and add an #input focus assertion to the e2e test.
@marmeladema
marmeladema force-pushed the fix/delete-active-thread-opens-draft branch from b46b3b1 to 2ab131a Compare July 28, 2026 10:58
@marmeladema
marmeladema merged commit 59064fd into main Jul 28, 2026
5 checks passed
@marmeladema
marmeladema deleted the fix/delete-active-thread-opens-draft branch July 28, 2026 11:07
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