feat(desktop): add workspace settings section with project/workspace navigation#247
feat(desktop): add workspace settings section with project/workspace navigation#247
Conversation
…navigation Add a new Workspace settings section that allows users to view and edit workspace details including name, branch, path, and scripts configuration. The settings sidebar now shows a hierarchical project/workspace list for easy navigation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@Kitenite has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 27 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. 📒 Files selected for processing (14)
WalkthroughThe PR introduces a workspace settings section with inline renaming capability and config file preview. Backend TRPC endpoints now embed associated project and worktree data in workspace responses. The settings navigation is refactored to use TRPC-driven workspace grouping, and the SettingsSection type is expanded to include the new workspace section. Changes
Sequence DiagramsequenceDiagram
participant User
participant SettingsSidebar
participant TRPC
participant SettingsContent
participant WorkspaceSettings
participant ConfigFilePreview
User->>SettingsSidebar: Click workspace item
SettingsSidebar->>TRPC: Fetch grouped workspaces & activeWorkspace
TRPC-->>SettingsSidebar: Return workspaces with project & worktree data
SettingsSidebar->>SettingsSidebar: setActiveWorkspace, switch to workspace section
SettingsSidebar->>SettingsContent: Render (activeSection = "workspace")
SettingsContent->>WorkspaceSettings: Render component
WorkspaceSettings->>TRPC: Query active workspace + config file path
TRPC-->>WorkspaceSettings: Return workspace (with project/worktree) + configFilePath
WorkspaceSettings->>ConfigFilePreview: Render config preview (if project exists)
ConfigFilePreview-->>WorkspaceSettings: Display template & config path
WorkspaceSettings-->>User: Show settings UI with rename, branch, scripts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 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 |
Show the actual config.json content if it exists, otherwise display the template. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1)
20-40: Issue: Duplicate "Workspace" entry in GENERAL_SECTIONS.The
GENERAL_SECTIONSarray includes a "workspace" entry (lines 25-29), but workspaces are already handled separately in the dynamic "Projects & Workspaces" section (lines 87-140). This creates duplication and potential confusion in the UI, as clicking on the General > Workspace item would navigate to the workspace section but wouldn't match any specific workspace.Consider removing the "workspace" entry from
GENERAL_SECTIONS:const GENERAL_SECTIONS: { id: SettingsSection; label: string; icon: React.ReactNode; }[] = [ - { - id: "workspace", - label: "Workspace", - icon: <HiOutlineFolder className="h-4 w-4" />, - }, { id: "appearance", label: "Appearance", icon: <HiOutlinePaintBrush className="h-4 w-4" />, }, { id: "keyboard", label: "Keyboard Shortcuts", icon: <HiOutlineCommandLine className="h-4 w-4" />, }, ];
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1)
81-121: Branch, path, and scripts/config preview sections are straightforward and robust
- Branch and “Needs Rebase” badge are correctly guarded by
activeWorkspace.worktreeandgitStatus?.needsRebase, so they won’t render when metadata is absent.- The path section always shows
activeWorkspace.worktreePathin a monospace, breakable line, which is appropriate for filesystem paths.- The Scripts section is correctly conditional on
activeWorkspace.project, andConfigFilePreviewreceives both the project name and the (possibly undefined)configFilePath, matching the provided component contract.If you later see very long branch names or paths in practice, consider truncation with a tooltip, but what you have here is fine for this PR.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts(1 hunks)apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx(1 hunks)apps/desktop/src/renderer/components/ConfigFilePreview/index.ts(1 hunks)apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx(2 hunks)apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx(3 hunks)apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx(1 hunks)apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts(1 hunks)apps/desktop/src/renderer/stores/app-state.ts(2 hunks)apps/desktop/src/shared/constants.ts(1 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/components/ConfigFilePreview/index.tsapps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: Please use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary
Files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.tsapps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Avoid usinganytype - 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/components/ConfigFilePreview/index.tsapps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.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/components/ConfigFilePreview/index.tsapps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
**/components/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/components/**/*.tsx: Create one folder per component with structure:ComponentName/ComponentName.tsx+index.tsfor 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 nestedcomponents/subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent'scomponents/folder
One component per file - avoid multi-component files
Files:
apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.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/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.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 (7)
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to **/components/**/*.tsx : Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.tsapps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to **/components/**/*.tsx : One component per file - avoid multi-component files
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to **/components/**/*.tsx : Co-locate tests next to the component file they test (e.g., `ComponentName.test.tsx`)
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/index.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to **/*.{ts,tsx} : Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Applied to files:
apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary
Applied to files:
apps/desktop/src/renderer/stores/app-state.ts
🧬 Code graph analysis (4)
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (3)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/useWorkspaceRename.ts (1)
useWorkspaceRename(4-64)packages/ui/src/components/input.tsx (1)
Input(29-29)apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx (1)
ConfigFilePreview(18-62)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (2)
apps/desktop/src/renderer/stores/app-state.ts (1)
SettingsSection(5-5)packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2)
apps/desktop/src/main/lib/db/index.ts (1)
db(18-25)apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts (1)
getWorktreePath(6-9)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1)
WorkspaceSettings(12-125)apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts (1)
WorkspaceSettings(1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (15)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)
4-4: LGTM: Clean integration of WorkspaceSettings.The import and conditional rendering follow the established pattern for other settings sections.
Also applies to: 13-13
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts (1)
1-1: LGTM: Standard barrel export.Follows the established component structure pattern.
apps/desktop/src/renderer/components/ConfigFilePreview/index.ts (1)
1-4: LGTM: Proper barrel export pattern.Correctly exports both the component and its props type.
apps/desktop/src/shared/constants.ts (2)
24-27: LGTM: Project-level constants added.The new constants
PROJECT_SUPERSET_DIR_NAMEandCONFIG_FILE_NAMEare well-defined. Note thatPROJECT_SUPERSET_DIR_NAMEis intentionally not environment-dependent, unlikeSUPERSET_DIR_NAME.
32-36: CONFIG_TEMPLATE structure correctly matches the SetupConfig schema.The template structure is accurate. The
SetupConfiginterface (apps/desktop/src/shared/types.ts:130-133) defines bothsetupandteardownas optional string arrays. The template provides empty arrays for both, which aligns perfectly with the expected schema. The parsing logic in setup.ts and teardown.ts validates that these fields are arrays when present, and the template satisfies these requirements.apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx (2)
23-25: LGTM: External link handling is appropriate.The use of
window.openwith"_blank"is appropriate for opening documentation in a new tab. The URL is constructed from a trusted constant.
39-39: OpenInButton correctly handles undefined paths — no action required.The component properly handles the optional
pathprop through multiple defensive checks: the prop type explicitly allowsstring | undefined, buttons are disabled when path is falsy (disabled={!path}), and all handler functions early return if path is undefined. This approach prevents mutations from being triggered with invalid paths.apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (3)
73-73: Consider: Panel width increased from default.The sidebar width changed from the default to
w-56(14rem/224px). Verify this accommodates longer project/workspace names without excessive truncation.
94-139: LGTM: Well-structured workspace navigation.The dynamic project/workspace navigation with expand/collapse functionality is well-implemented:
- Proper use of state for expanded projects
- Color badges for visual project identification
- Nested structure with appropriate indentation
- Active state highlighting
50-53: No action needed - the code is correct as written.The
activeWorkspace?.projectIdexpression correctly handles the case whereactiveWorkspaceisnullorprojectIdis undefined. WhenprojectIdis falsy, the ternary returns an empty array[](not[undefined]) which is passed to the Set constructor. TheuseStateinitializer is properly structured as a function, so it runs only once on mount and won't re-execute on every render.apps/desktop/src/renderer/stores/app-state.ts (1)
5-5: LGTM: Workspace-first settings approach.The addition of
"workspace"toSettingsSectiontype and changing the default from"appearance"to"workspace"at line 23 aligns well with the PR objective to prioritize workspace settings. Verification confirms that "appearance" is only referenced in UI components (SettingsContent.tsx, SettingsSidebar.tsx) as a selectable option, not assumed as a default elsewhere. Code follows zustand patterns correctly with proper state management.apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)
226-246: No breaking changes; new fields actively used by consumers.The enriched
getActiveresponse is backward compatible and already being utilized. Consumers likeWorkspaceSettingsaccess the newproject(id, name) andworktree(branch, gitStatus) fields, as well asworktreePath. Note thatgetAllGroupedreturns a different shape with onlyworktreePathenrichment, not the full project/worktree objects—verify this intentional divergence aligns with client needs.apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (3)
1-11: Imports and aliases align with desktop renderer guidelinesImports use the configured aliases (
renderer/...,@superset/ui/input) and avoid Node.js modules in renderer code, matching the documented patterns. No changes needed.As per coding guidelines, this follows the expected alias and renderer-module rules.
13-24: TRPC data fetching and dependent query wiring look correctUsing
trpc.workspaces.getActive.useQuery()as the source of truth and gatingtrpc.config.getConfigFilePath.useQuery()withenabled: !!activeWorkspace?.projectIdis a good pattern for dependent data; passingactiveWorkspace?.projectId ?? ""avoids undefined while still preventing calls when there is no project. InitializinguseWorkspaceRenamefromactiveWorkspace?.id/name ?? ""is safe given the early returns for loading/empty states.Please just confirm that the
config.getConfigFilePathinput schema is happy with an empty string when the query is disabled (React Query should never invoke the procedure in that case, but it’s worth aligning expectations with the router definition).
26-48: Loading and empty workspace states are handled cleanlySkeleton content while
isLoadingis true and a clear “No active workspace selected” message whenactiveWorkspaceis missing give good feedback without leaking implementation details. Copyable text (select-text) is a nice touch for consistency with the main view.
- Add ProjectSettings component showing project name, repo path, and scripts config - Move scripts/config section from WorkspaceSettings to ProjectSettings - Update SettingsSidebar to show project hierarchy with Project Settings and Workspaces - Workspaces are now shown as children of projects in the settings sidebar 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…debar 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…lapse - Clicking project name now opens project settings directly - Separate chevron button handles expand/collapse of workspaces - Removed "Project Settings" child item 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
UI Improvements
✏️ Tip: You can customize this high-level summary in your review settings.