Skip to content

feat: drag-to-reorder assistants in the sidebar#324

Merged
hrayleung merged 2 commits into
masterfrom
feat/drag-assitants
May 11, 2026
Merged

feat: drag-to-reorder assistants in the sidebar#324
hrayleung merged 2 commits into
masterfrom
feat/drag-assitants

Conversation

@hrayleung
Copy link
Copy Markdown
Owner

@hrayleung hrayleung commented May 11, 2026

Summary

  • Pulls the Assistants section out of the conversation List so legacy .onDrag / .onDrop fire correctly — being a List child was silently dropping the drop callback.
  • Adds AssistantDragReorderModifier (uses public.text + NSString payload, the combination that survives macOS quirks documented in the file header) and applies it to both the grid and list assistant layouts.
  • Adds reorderAssistant(sourceID:onto:) on ContentView which renumbers AssistantEntity.sortOrder, bumps updatedAt, and persists via modelContext.save().
  • Drag-reorder is gated to the Custom sort option so it doesn't visually fight alphabetical / recent ordering, and a spring animation softens the swap.

Test plan

  • swift build clean
  • Open Jin, set Assistants sort to Custom, drag a tile in the grid layout — order updates and persists across relaunch
  • Same in the list layout
  • Switch sort to Alphabetical — drag is disabled (no targeting overlay)
  • Dropdown layout still works for selection / context menu

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Drag-and-drop reordering for assistant tiles—users can now customize the order of assistants in the sidebar.
  • Refactor

    • Restructured assistant sidebar layout and interaction patterns for improved usability.

Review Change Stack

Lifts the Assistants section out of the conversation List into its own
VStack so legacy `.onDrag` / `.onDrop` actually fire (the List ancestor
was killing the drop). Adds `AssistantDragReorderModifier` which uses
the `public.text` UTI with an NSString payload, and a
`reorderAssistant(sourceID:onto:)` helper that renumbers `sortOrder`
and persists via SwiftData. Drag is gated to the custom sort option so
it doesn't fight alphabetical/recent ordering.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@hrayleung has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f6157182-873f-45f2-9a57-ce3e33049870

📥 Commits

Reviewing files that changed from the base of the PR and between 85e6eb1 and 1670598.

📒 Files selected for processing (1)
  • Sources/UI/AssistantDragReorder.swift
📝 Walkthrough

Walkthrough

This PR adds drag-and-drop reordering for assistant tiles in the sidebar. It introduces a new AssistantDragReorderModifier that handles drag/drop interactions, implements reorder business logic to persist changes, refactors the sidebar from a Section to a composite assistantsArea with extracted header/body/button components, and wires the updated UI into the main sidebar view.

Changes

Drag-Reorder for Assistants

Layer / File(s) Summary
Reorder Business Logic
Sources/UI/ContentView+AssistantManagement.swift
Adds reorderAssistant(sourceID:onto:) method that reorders assistants by ID, updates sortOrder and updatedAt for affected items, and persists changes via modelContext.save().
Drag/Drop Modifier API
Sources/UI/AssistantDragReorder.swift
Introduces AssistantDragReorderModifier that conditionally enables drag/drop via NSItemProvider text payloads, renders drop-target highlights, validates source/target IDs, and dispatches onReorder callback. Provides View extension convenience method.
Sidebar Refactoring & Integration
Sources/UI/ContentView+SidebarSections.swift
Replaces monolithic assistantsSection with composite assistantsArea split into header/body/button views. Applies drag-reorder modifier to each assistant tile across dropdown/grid/list layouts. Converts selection from Button wrappers to tap gestures and adjusts context-menu and animation strategies per layout.
Sidebar Content Entry Point
Sources/UI/ContentView.swift
Updates sidebarContent List to render assistantsArea instead of assistantsSection before conversation list items.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • hrayleung/Jin#260: Modifies assistants sidebar layout and styling in ContentView+SidebarSections.swift in parallel with this reordering feature.
  • hrayleung/Jin#258: Updates assistants sidebar UI structure and AssistantTileView/layout changes in ContentView+SidebarSections.swift.

Poem

🐰 Tiles now dance at a rabbit's command,
Drag them around, reorder the band,
With modifiers swift and logic so keen,
The cleanest drag-drop you've ever seen!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: drag-to-reorder assistants in the sidebar' directly and clearly describes the main feature added: drag-and-drop reordering capability for assistants in the sidebar UI.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/drag-assitants

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

🤖 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 `@Sources/UI/AssistantDragReorder.swift`:
- Around line 4-10: Remove the hardcoded absolute path in the top-of-file
comment in AssistantDragReorder.swift (the "/Users/hinrayleung/.claude/..."
path) and replace it with a neutral reference or remove it entirely; update the
comment to either reference a generic document name (e.g., "internal diagnostic
notes") or a repo-relative path if the note is checked into source control,
ensuring no personal usernames or local filesystem paths remain in the file
header.

In `@Sources/UI/ContentView`+AssistantManagement.swift:
- Line 95: The silent discard of save errors via "try? modelContext.save()" can
make the function return true even when persistence failed; replace it with a
do-catch that calls "try modelContext.save()" and either propagate the thrown
error (make the enclosing function throws) or catch and log the error (e.g.,
with os_log or a logger) and return false on failure so callers know the save
did not succeed; update the surrounding function signature/return logic
accordingly to ensure failures are not ignored.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ccf8567f-b842-4ad8-b07b-afd24e1b1b82

📥 Commits

Reviewing files that changed from the base of the PR and between a7fa536 and 85e6eb1.

📒 Files selected for processing (4)
  • Sources/UI/AssistantDragReorder.swift
  • Sources/UI/ContentView+AssistantManagement.swift
  • Sources/UI/ContentView+SidebarSections.swift
  • Sources/UI/ContentView.swift

Comment thread Sources/UI/AssistantDragReorder.swift Outdated
}
guard changed else { return false }

try? modelContext.save()
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 | 🟠 Major | ⚡ Quick win

Handle save errors instead of silently ignoring them.

Using try? silently discards save failures, which means the function can return true even when changes weren't persisted. This creates a data-loss risk where the UI shows the new order but it's lost on app restart.

Proposed fix: propagate or log save errors
-        try? modelContext.save()
-        return true
+        do {
+            try modelContext.save()
+            return true
+        } catch {
+            print("⚠️ Failed to persist assistant reorder: \(error)")
+            return false
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try? modelContext.save()
do {
try modelContext.save()
return true
} catch {
print("⚠️ Failed to persist assistant reorder: \(error)")
return false
}
🤖 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 `@Sources/UI/ContentView`+AssistantManagement.swift at line 95, The silent
discard of save errors via "try? modelContext.save()" can make the function
return true even when persistence failed; replace it with a do-catch that calls
"try modelContext.save()" and either propagate the thrown error (make the
enclosing function throws) or catch and log the error (e.g., with os_log or a
logger) and return false on failure so callers know the save did not succeed;
update the surrounding function signature/return logic accordingly to ensure
failures are not ignored.

Per CodeRabbit: the previous comment referenced a developer-local plan
file that doesn't exist for other contributors. Keep the diagnostic
summary inline instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hrayleung hrayleung merged commit 2440296 into master May 11, 2026
3 checks passed
@hrayleung hrayleung deleted the feat/drag-assitants branch May 11, 2026 01:39
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