Skip to content

fix(desktop): new v2 workspaces appear at top of their project in sidebar#3619

Merged
saddlepaddle merged 2 commits into
mainfrom
oi
Apr 22, 2026
Merged

fix(desktop): new v2 workspaces appear at top of their project in sidebar#3619
saddlepaddle merged 2 commits into
mainfrom
oi

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Apr 21, 2026

Summary

  • New v2 workspaces were being inserted at the bottom of their project's sidebar list because ensureSidebarWorkspaceRecord used getNextTabOrder (max + 1).
  • Added a getPrependTabOrder helper that returns min - 1 and switched the insert to use it, so newly created workspaces land at the top of the project.
  • Existing reorder ops normalize tabOrders back to positive sequential values on drag, so negative seeds from prepended inserts are transient.

Test plan

  • Create a new v2 workspace in a project that already has workspaces — verify it appears at the top of that project, not the bottom
  • Create a project that contains a section at the top; create a workspace — verify it appears above the section
  • Drag-reorder workspaces after creation and confirm order persists

Summary by cubic

New v2 workspaces now appear at the top of their project in the desktop sidebar. This makes new workspaces visible right away without changing existing order.

  • Bug Fixes
    • Added getPrependTabOrder (min − 1) and used it when creating a workspace to prepend it in the project list.
    • For empty projects, seed tabOrder at 1 to match reorder helpers; drag-reorder still normalizes values, so any negative seeds are temporary.

Written for commit 067526a. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed workspace ordering in the sidebar: newly created top-level (ungrouped) workspaces now appear at the top of the list instead of at the bottom.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b11788fc-48f2-4ea3-9a4d-b2941938211e

📥 Commits

Reviewing files that changed from the base of the PR and between 70bc9b5 and 067526a.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts

📝 Walkthrough

Walkthrough

New logic changes how top-level (ungrouped) workspace sidebar records get their tabOrder: instead of using the next maximum (getNextTabOrder), newly created top-level workspaces are assigned a value that precedes the current minimum via a new getPrependTabOrder helper.

Changes

Cohort / File(s) Summary
Sidebar Tab Order Logic
apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
Added getPrependTabOrder(items) to compute a tabOrder that is one less than the current minimum (returns 1 for empty input). Updated ensureSidebarWorkspaceRecord so newly created top-level (sidebarState.sectionId: null) workspace records use getPrependTabOrder instead of getNextTabOrder, changing insertion from append to prepend.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐇 I nibble code with hopping cheer,
New tabs now leap up front, not rear.
A little shift, a tiny art—
Prepend the work, a joyous start! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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
Title check ✅ Passed The title clearly and specifically describes the main change: new v2 workspaces now appear at the top of their project in the sidebar instead of the bottom.
Description check ✅ Passed The description includes a comprehensive summary, test plan with checkboxes, and detailed explanation of the fix. It covers the root cause, the solution, and expected behavior.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch oi

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.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 21, 2026

Greptile Summary

This PR fixes a UX bug where newly created v2 workspaces were appended to the bottom of their project's sidebar list instead of the top. The fix introduces a getPrependTabOrder helper that seeds the new workspace's tabOrder with min(existing tabOrders) - 1, guaranteeing it sorts before all current items. Negative tabOrder values are transient — any drag-reorder operation normalises everything back to sequential 1-based values via the existing reorderProjectChildren / reorderWorkspaces callbacks.

Key changes:

  • New getPrependTabOrder utility mirrors getNextTabOrder but returns min - 1 rather than max + 1, with a guard for the empty-array case.
  • ensureSidebarWorkspaceRecord switches from getNextTabOrder (append) to getPrependTabOrder (prepend) for the initial tabOrder assignment.
  • topLevelOrders already includes both ungrouped workspaces and top-level sections, so the prepend order correctly places new workspaces above any existing sections as well.

Confidence Score: 5/5

Safe to merge — the change is minimal, logically correct, and any transient tabOrder edge cases are self-healing on the next drag-reorder.

The fix is a small, focused two-function change. getPrependTabOrder correctly computes min - 1, the Number.POSITIVE_INFINITY seed for the reduce is the right choice for a min-reduction, and the empty-array guard is necessary and correct. No data loss or security risks. The only observation is a P2 style inconsistency where the empty-project case returns 0 instead of 1, which has no impact on correctness.

No files require special attention. The single changed file is self-contained.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts Adds getPrependTabOrder helper returning min - 1 and switches ensureSidebarWorkspaceRecord to use it, so new workspaces land at the top of their project in the sidebar instead of the bottom.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
Line: 15-22

Comment:
**Empty-project seed value is `0` while the rest of the codebase uses `1`-based ordering**

When `items` is empty (first workspace in a brand-new project) `getPrependTabOrder` returns `0`, whereas every other insertion helper (`getNextTabOrder`, `reorderProjectChildren`, `reorderWorkspaces`, `moveWorkspaceToSectionAtIndex`) normalises to `1`-based tabOrders on the next drag. This is functionally harmless — `0 < 1` so the workspace still sorts first — but it is a mild inconsistency worth documenting or aligning with `1`.

If you want to keep the `1`-based convention you could return `1` instead:
```suggestion
function getPrependTabOrder(items: Array<{ tabOrder: number }>): number {
	if (items.length === 0) return 1;
	const minTabOrder = items.reduce(
		(minValue, item) => Math.min(minValue, item.tabOrder),
		Number.POSITIVE_INFINITY,
	);
	return minTabOrder - 1;
}
```
This way the first workspace starts at `1`, the second at `0`, the third at `-1`, etc. — all still sorts correctly and matches the "index + 1" convention used by the reorder helpers.

Not blocking; leaving as a suggestion.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(desktop): place new v2 workspaces at..." | Re-trigger Greptile

Comment on lines +15 to +22
function getPrependTabOrder(items: Array<{ tabOrder: number }>): number {
if (items.length === 0) return 0;
const minTabOrder = items.reduce(
(minValue, item) => Math.min(minValue, item.tabOrder),
Number.POSITIVE_INFINITY,
);
return minTabOrder - 1;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Empty-project seed value is 0 while the rest of the codebase uses 1-based ordering

When items is empty (first workspace in a brand-new project) getPrependTabOrder returns 0, whereas every other insertion helper (getNextTabOrder, reorderProjectChildren, reorderWorkspaces, moveWorkspaceToSectionAtIndex) normalises to 1-based tabOrders on the next drag. This is functionally harmless — 0 < 1 so the workspace still sorts first — but it is a mild inconsistency worth documenting or aligning with 1.

If you want to keep the 1-based convention you could return 1 instead:

Suggested change
function getPrependTabOrder(items: Array<{ tabOrder: number }>): number {
if (items.length === 0) return 0;
const minTabOrder = items.reduce(
(minValue, item) => Math.min(minValue, item.tabOrder),
Number.POSITIVE_INFINITY,
);
return minTabOrder - 1;
}
function getPrependTabOrder(items: Array<{ tabOrder: number }>): number {
if (items.length === 0) return 1;
const minTabOrder = items.reduce(
(minValue, item) => Math.min(minValue, item.tabOrder),
Number.POSITIVE_INFINITY,
);
return minTabOrder - 1;
}

This way the first workspace starts at 1, the second at 0, the third at -1, etc. — all still sorts correctly and matches the "index + 1" convention used by the reorder helpers.

Not blocking; leaving as a suggestion.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
Line: 15-22

Comment:
**Empty-project seed value is `0` while the rest of the codebase uses `1`-based ordering**

When `items` is empty (first workspace in a brand-new project) `getPrependTabOrder` returns `0`, whereas every other insertion helper (`getNextTabOrder`, `reorderProjectChildren`, `reorderWorkspaces`, `moveWorkspaceToSectionAtIndex`) normalises to `1`-based tabOrders on the next drag. This is functionally harmless — `0 < 1` so the workspace still sorts first — but it is a mild inconsistency worth documenting or aligning with `1`.

If you want to keep the `1`-based convention you could return `1` instead:
```suggestion
function getPrependTabOrder(items: Array<{ tabOrder: number }>): number {
	if (items.length === 0) return 1;
	const minTabOrder = items.reduce(
		(minValue, item) => Math.min(minValue, item.tabOrder),
		Number.POSITIVE_INFINITY,
	);
	return minTabOrder - 1;
}
```
This way the first workspace starts at `1`, the second at `0`, the third at `-1`, etc. — all still sorts correctly and matches the "index + 1" convention used by the reorder helpers.

Not blocking; leaving as a suggestion.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

…sidebar

New workspaces were inserted with tabOrder = max + 1, burying them at the
bottom of the project's list. Prepend with min - 1 instead so freshly
created workspaces surface at the top without disturbing existing order.
@saddlepaddle saddlepaddle merged commit 2c6d6eb into main Apr 22, 2026
6 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

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