Repository navigation
Conversation
📝 WalkthroughWalkthroughProject groups now support nested parent relationships across persistence, IPC, RPC, preload, runtime, and renderer state APIs. Creation handles invalid parents with nullable results, while updates validate parent targets and prevent cycles. The sidebar adds subgroup creation, movement between valid groups, and movement to root, with localized labels. Persistence, renderer, RPC, and end-to-end tests cover these flows and their visual nesting behavior. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/renderer/src/components/sidebar/WorktreeList.tsx (1)
4397-4420: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winExtract
getProjectGroupSubtreeIdsout of the.filtercallback.
getProjectGroupSubtreeIdsiterates over all project groups to build a subtree map. Calling it inside.filterrecomputes this map for every group during every render of the row, resulting inO(V * N^2)allocations per frame (where V is the number of visible headers and N is the total number of groups).Wrap the logic in an IIFE to evaluate the subtree IDs once per row render, reducing the complexity to
O(V * N).⚡ Proposed performance refactor
- <DropdownMenuSubContent> - {projectGroups - .filter( - (group) => - !getProjectGroupSubtreeIds( - projectGroups, - row.projectGroup!.id as string - ).has(group.id) - ) - .map((group) => ( - <DropdownMenuItem - key={group.id} - onSelect={() => - handleMoveProjectGroup( - row.projectGroup!.id as string, - group.id - ) - } - > - <span className="max-w-48 truncate">{group.name}</span> - </DropdownMenuItem> - ))} - </DropdownMenuSubContent> + <DropdownMenuSubContent> + {(() => { + const subtreeIds = getProjectGroupSubtreeIds( + projectGroups, + row.projectGroup!.id as string + ) + return projectGroups + .filter((group) => !subtreeIds.has(group.id)) + .map((group) => ( + <DropdownMenuItem + key={group.id} + onSelect={() => + handleMoveProjectGroup( + row.projectGroup!.id as string, + group.id + ) + } + > + <span className="max-w-48 truncate">{group.name}</span> + </DropdownMenuItem> + )) + })()} + </DropdownMenuSubContent>
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 53c95ecf-64ff-4a2b-a3b9-ded2846c88c7
📒 Files selected for processing (16)
src/main/ipc/repos.tssrc/main/persistence.test.tssrc/main/persistence.tssrc/main/runtime/orca-runtime.tssrc/main/runtime/rpc/methods/repo.test.tssrc/main/runtime/rpc/methods/repo.tssrc/preload/api-types.tssrc/renderer/src/components/sidebar/WorktreeList.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/store/slices/repos-project-groups.test.tssrc/renderer/src/store/slices/repos.tstests/e2e/project-group-nesting.spec.ts
👮 Files not reviewed due to content moderation or server errors (8)
- src/main/runtime/rpc/methods/repo.ts
- src/preload/api-types.ts
- src/main/runtime/orca-runtime.ts
- src/renderer/src/store/slices/repos.ts
- src/main/runtime/rpc/methods/repo.test.ts
- src/renderer/src/i18n/locales/en.json
- src/renderer/src/i18n/locales/es.json
- src/renderer/src/i18n/locales/ja.json
|
Closing in favor of #8939 — I missed that you'd already called this on #8785 and had a PR up. Yours covers the drag half too, which mine deliberately skipped. One thing that might be useful: I'd written an e2e spec at |
Summary
New subgroup,Move to group, andMove to rootactions to project-group header menus so manual group organization can match Orca's existing nested renderer.parentGroupIdthrough the existing create and update transport, with persistence rejecting self, descendant, and missing-parent assignments.Refs #8785.
Screenshots
No screenshot. Local headed Electron proof stayed deferred in this session after visible Orca windows and firewall prompts disrupted the desktop.
Testing
pnpm lintpnpm typecheckpnpm testpnpm buildFocused validation to run:
pnpm exec vitest run --config config/vitest.config.ts src/main/persistence.test.ts src/main/ipc/repos-remote.test.ts src/main/runtime/rpc/methods/repo.test.ts src/renderer/src/store/slices/repos-project-groups.test.ts src/renderer/src/components/sidebar/worktree-list-groups.test.tspnpm run typecheck:nodepnpm run typecheck:webpnpm run verify:localization-catalog && pnpm run verify:localization-coveragepnpm exec oxlint --config config/oxlint-react-doctor.json src/main/ipc/repos.ts src/main/persistence.ts src/main/runtime/orca-runtime.ts src/main/runtime/rpc/methods/repo.ts src/preload/api-types.ts src/renderer/src/components/sidebar/WorktreeList.tsx src/renderer/src/store/slices/repos.ts tests/e2e/project-group-nesting.spec.tspnpm run test:e2e:headful -- tests/e2e/project-group-nesting.spec.ts --workers=1, intentionally not rerun because this session is avoiding visible Electron workAI Review Report
tests/e2e/project-group-nesting.spec.tsis rerun in a non-disruptive environment.Security Audit
IPC and runtime callers now preserve the full three-state
parentGroupIdcontract into persistence, and persistence remains the final validation owner for self, descendant, missing-parent, and invalid-create rejection. Failed create and update attempts returnnullwithout partial mutation or notification side effects.Notes
This slice intentionally references the broader issue instead of closing it. Drag-to-nest and drag-to-root behavior remain outside scope. Hierarchy depth remains arbitrary and follows Orca's existing recursive renderer.
Local headed Electron proof was deferred in this session after disruptive Orca windows and firewall prompts during UI-owner verification. The branch carries the narrow Playwright coverage, but screenshot-backed rendered-layout proof remains pending until it can be rerun in a non-disruptive environment.