Skip to content

Top bar#184

Closed
Kitenite wants to merge 2 commits intomainfrom
pearl-glacier-85
Closed

Top bar#184
Kitenite wants to merge 2 commits intomainfrom
pearl-glacier-85

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Nov 29, 2025

Summary by CodeRabbit

  • New Features
    • Added a workspace top bar showing current workspace path, active branch, and associated project (with color dot). Truncated values show tooltips and defaults display when data is missing.
    • Added support to fetch detailed active-workspace information so the top bar can show project and worktree details.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented Nov 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
website Error Error Dec 1, 2025 0:22am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 29, 2025

Walkthrough

Added a tRPC procedure getActiveWithDetails returning the active workspace plus resolved worktree and project details. Introduced a new WorkspaceTopBar React component that queries this procedure and displays path, branch, and optional project. Integrated the top bar into WorkspaceView, changing its root layout to vertical flex.

Changes

Cohort / File(s) Summary
Backend: tRPC Router
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
Added public procedure getActiveWithDetails that fetches the active workspace, resolves associated worktree (or null) and project (id, name, color, mainRepoPath or null), and preserves existing error handling for missing active workspace.
UI Component: WorkspaceTopBar
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx, apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
New React component using trpc.workspaces.getActiveWithDetails.useQuery to render a top bar showing workspace path (truncated + tooltip), current branch (with tooltip), and optional right-aligned project segment with colored dot and name. Handles absent values with defaults.
Layout Integration
apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
Imported and placed WorkspaceTopBar above the main content; converted the root layout from horizontal to vertical flex and nested the existing Sidebar and ContentView under the new top bar with adjusted margins.

Sequence Diagram

sequenceDiagram
    participant UI as WorkspaceTopBar (React)
    participant Query as trpc.useQuery
    participant Router as getActiveWithDetails (tRPC)
    participant DB as Data Layer / ORM

    UI->>Query: mount -> trpc.workspaces.getActiveWithDetails.useQuery()
    Query->>Router: RPC call: getActiveWithDetails
    Router->>DB: fetch active workspace id / record
    DB-->>Router: returns workspace (or null)
    Router->>DB: if found -> resolve worktree & project relationships
    DB-->>Router: returns worktree (or null) and project (or null)
    Router-->>Query: respond with workspace + worktree + project
    Query-->>UI: hook updates with data or error
    UI->>UI: render path, branch, and optional project segment
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect getActiveWithDetails for correct null-handling and error cases.
  • Verify tRPC types/signatures and any required permissions/context.
  • Review WorkspaceTopBar for safe access of nested properties and UI responsiveness.
  • Confirm WorkspaceView layout change doesn't regress other views or CSS.

Possibly related PRs

Poem

🐇 I fetched the workspace, branch in tow,
A dot of color, a little glow,
Top bar hums — path and project sing,
Small changes make the workspace spring,
Hop, click, explore — new details grow. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided; the description section is entirely empty and does not follow the required template. Add a detailed description following the template, including a clear overview of changes, related issues, type of change, testing approach, and any relevant screenshots or notes.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Top bar' is vague and generic, using non-descriptive terminology that fails to convey meaningful details about the changeset. Revise the title to be more specific and descriptive. Consider: 'Add WorkspaceTopBar component with workspace details' or 'Add top bar to WorkspaceView displaying workspace and project info'.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pearl-glacier-85

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
Contributor

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

🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (1)

4-9: Consider handling loading and error states.

The component returns null when data is falsy, which includes loading, error, and no-active-workspace states. Consider destructuring additional query states for better UX:

 export function WorkspaceTopBar() {
-	const { data } = trpc.workspaces.getActiveWithDetails.useQuery();
+	const { data, isLoading, isError } = trpc.workspaces.getActiveWithDetails.useQuery();

-	if (!data) {
+	if (isLoading) {
+		return (
+			<div className="flex items-center gap-4 px-3 py-2 border-b border-border text-sm text-muted-foreground">
+				<span>Loading workspace...</span>
+			</div>
+		);
+	}
+
+	if (isError) {
+		return (
+			<div className="flex items-center gap-4 px-3 py-2 border-b border-border text-sm text-destructive">
+				<span>Failed to load workspace details</span>
+			</div>
+		);
+	}
+
+	if (!data) {
 		return null;
 	}

This provides visual feedback during loading and error states instead of silently hiding the top bar.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b4935d and d56db36.

📒 Files selected for processing (4)
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
**/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.tsx: Create one folder per component with structure: ComponentName/ComponentName.tsx + index.ts for barrel export
Co-locate tests next to the component file they test (e.g., ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nested components/ subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent's components/ folder
One component per file - avoid multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods using window.ipcRenderer.invoke() with object parameters - TypeScript will infer the exact response type automatically

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx
apps/desktop/src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in shared code like src/lib/electron-router-dom.ts - this code runs in both main and renderer processes

Files:

  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
🧠 Learnings (1)
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/index.ts
🧬 Code graph analysis (2)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)
apps/desktop/src/main/lib/db/index.ts (1)
  • db (19-26)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/index.tsx (1)
  • Sidebar (8-55)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/index.tsx (1)
  • ContentView (5-13)
🔇 Additional comments (3)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

211-246: LGTM! Clean extension of the existing pattern.

The new getActiveWithDetails procedure correctly mirrors the getActive implementation while enriching the response with related entities. The error handling is consistent, and returning partial project data (id, name, color, mainRepoPath) appropriately limits the API surface.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx (1)

82-89: LGTM! Clean layout integration.

The vertical flex conversion and top bar placement are well-structured. The mt-0 on the content wrapper appropriately aligns it with the new top bar.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (1)

13-14: Based on my verification, I have gathered sufficient evidence to provide a comprehensive analysis. Let me now generate the rewritten review comment.


Fallback strings reveal legitimate data integrity concern—workspaces can exist without associated worktrees.

The optional chaining in lines 13-14 handles a real state where worktree can be null. The getActiveWithDetails endpoint at line 236 of apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts explicitly returns worktree ?? null, and the canDelete endpoint warns "No associated worktree found" (line 331), confirming this is an acknowledged edge case.

Root cause: While workspaces and worktrees are always created together (lines 58-71), only the worktree is cleaned up if it exists during deletion (line 381: if (worktree) { data.worktrees.filter(...) }). If a worktree is manually removed from git or the database is corrupted, the workspace becomes orphaned with a dangling reference.

Consider adding a safeguard: either enforce that worktrees must always exist, or add a cleanup migration to detect and handle orphaned workspaces.

@Kitenite Kitenite changed the title pearl glacier 85 Top bar Nov 29, 2025
Copy link
Copy Markdown
Contributor

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

🧹 Nitpick comments (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (2)

4-9: Consider handling loading and error states explicitly.

The component returns null during loading and error states. While this matches the pattern in TopBar (see apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx), you might want to distinguish between these states for better UX—for example, showing a loading skeleton during data fetch or an error message on failure.

export function WorkspaceTopBar() {
	const { data, isLoading, error } = trpc.workspaces.getActiveWithDetails.useQuery();

	if (isLoading) {
		return <div className="px-3 py-2 text-sm text-muted-foreground">Loading...</div>;
	}

	if (error || !data) {
		return null;
	}
	// ... rest of component
}

28-39: Consider validating project color for better UX.

The project.color value is used directly in inline styles. While React's object-based inline styles are safe from injection, an invalid color value would fail silently. Consider validating that the color is a valid CSS color or providing a fallback.

const projectColor = project.color || '#888888'; // fallback color
// or validate: /^#[0-9A-F]{6}$/i.test(project.color) ? project.color : '#888888'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d56db36 and 316a53e.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
**/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.tsx: Create one folder per component with structure: ComponentName/ComponentName.tsx + index.ts for barrel export
Co-locate tests next to the component file they test (e.g., ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nested components/ subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent's components/ folder
One component per file - avoid multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods using window.ipcRenderer.invoke() with object parameters - TypeScript will infer the exact response type automatically

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx
🧬 Code graph analysis (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (1)
apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx (1)
  • TopBar (8-32)
🔇 Additional comments (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceTopBar/WorkspaceTopBar.tsx (3)

1-2: LGTM!

Imports follow the guidelines: using the alias path pattern for tRPC and appropriate icons for the UI.


11-14: LGTM!

Proper use of optional chaining and nullish coalescing to handle missing data with appropriate fallback values.


16-41: LGTM!

The JSX structure is well-organized with proper use of Tailwind utilities for layout, truncation, and accessibility (title attributes for tooltips). The conditional rendering of the project section is clean and appropriate.

@Kitenite Kitenite closed this Dec 1, 2025
@Kitenite Kitenite deleted the pearl-glacier-85 branch December 1, 2025 19:26
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