Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 6, 2026

Choose a reason for hiding this comment

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

P2: The "Add Repository" button is rendered as an interactive <button> element but has no onClick handler attached, so clicking it does nothing. The previous "New Workspace" button this replaced had onClick={() => openModal()}. Either wire up the intended action or disable the button and add a TODO comment if this is a placeholder.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx, line 40:

<comment>The "Add Repository" button is rendered as an interactive `<button>` element but has no `onClick` handler attached, so clicking it does nothing. The previous "New Workspace" button this replaced had `onClick={() => openModal()}`. Either wire up the intended action or disable the button and add a TODO comment if this is a placeholder.</comment>

<file context>
@@ -16,89 +9,42 @@ interface DashboardSidebarHeaderProps {
+			<Tooltip delayDuration={300}>
+				<TooltipTrigger asChild>
+					<button
+						type="button"
+						className="flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
+					>
</file context>
Fix with Cubic

import { cn } from "@superset/ui/utils";
import { useMatchRoute, useNavigate } from "@tanstack/react-router";
import { LuLayers, LuPlus } from "react-icons/lu";
import { LuFolderPlus, LuPlus } from "react-icons/lu";
import { useHotkeyDisplay } from "renderer/hotkeys";
import {
STROKE_WIDTH,
STROKE_WIDTH_THICK,
} from "renderer/screens/main/components/WorkspaceSidebar/constants";
import { OrganizationDropdown } from "renderer/routes/_authenticated/_dashboard/components/TopBar/components/OrganizationDropdown";
import { STROKE_WIDTH_THICK } from "renderer/screens/main/components/WorkspaceSidebar/constants";
import { useOpenNewWorkspaceModal } from "renderer/stores/new-workspace-modal";

interface DashboardSidebarHeaderProps {
Expand All @@ -16,35 +13,24 @@ interface DashboardSidebarHeaderProps {
export function DashboardSidebarHeader({
isCollapsed = false,
}: DashboardSidebarHeaderProps) {
const navigate = useNavigate();
const matchRoute = useMatchRoute();
const openModal = useOpenNewWorkspaceModal();
const shortcutText = useHotkeyDisplay("NEW_WORKSPACE").text;
const isWorkspacesPageOpen = !!matchRoute({ to: "/v2-workspaces" });

const handleWorkspacesClick = () => {
navigate({ to: "/v2-workspaces" });
};

if (isCollapsed) {
return (
<div className="flex flex-col items-center gap-2 border-b border-border py-2">
<OrganizationDropdown variant="collapsed" />

<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<button
type="button"
onClick={handleWorkspacesClick}
className={cn(
"flex size-8 items-center justify-center rounded-md transition-colors",
isWorkspacesPageOpen
? "bg-accent text-foreground"
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
)}
className="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
>
<LuLayers className="size-4" strokeWidth={STROKE_WIDTH} />
<LuFolderPlus className="size-4" />
</button>
</TooltipTrigger>
<TooltipContent side="right">Workspaces</TooltipContent>
<TooltipContent side="right">Add Repository</TooltipContent>
</Tooltip>
Comment on lines 26 to 34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 "Add Repository" button has no onClick handler

The LuFolderPlus button in both the collapsed (lines 19-27) and expanded (lines 38-47) states is rendered as an interactive button but has no onClick handler attached. Clicking it does nothing. If this is intended as a placeholder, it should at minimum be disabled or noted with a TODO comment. If it's meant to open a modal or navigate somewhere, the handler is missing.

Collapsed state:

Suggested change
<button
type="button"
onClick={() => openModal()}
className="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
>
<LuPlus className="size-4" strokeWidth={STROKE_WIDTH_THICK} />
<LuFolderPlus className="size-4" />
</button>
</TooltipTrigger>
<TooltipContent side="right">
New Workspace ({shortcutText})
</TooltipContent>
<TooltipContent side="right">Add Repository</TooltipContent>
</Tooltip>
<button
type="button"
onClick={() => { /* TODO: open add repository flow */ }}
className="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
>

Comment on lines 24 to 34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't expose Add Repository as a no-op.

Both variants render a focusable, actionable-looking button, but there is no click handler, navigation target, or disabled state, so the new action does nothing. Please either wire it to the add-repository flow or render it disabled/hidden until that behavior lands; once it is interactive, it should also get an explicit aria-label.

Also applies to: 37-47

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx`
around lines 17 - 27, The "Add Repository" button in DashboardSidebarHeader is
currently a focusable no-op (TooltipTrigger/button with LuFolderPlus) and must
either be wired or disabled: either hook its onClick to the add-repository flow
(e.g., call the existing openAddRepositoryModal or router navigation function
from the surrounding DashboardSidebarHeader component) and add an explicit
aria-label like "Add repository", or render the button as non-interactive until
implemented by adding disabled and aria-disabled attributes and ensuring
TooltipContent reflects that state; apply the same fix to the second identical
instance (the other Tooltip/button block).


<Tooltip delayDuration={300}>
Expand All @@ -67,21 +53,22 @@ export function DashboardSidebarHeader({

return (
<div className="flex flex-col gap-1 border-b border-border px-2 pt-2 pb-2">
<button
type="button"
onClick={handleWorkspacesClick}
className={cn(
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium transition-colors",
isWorkspacesPageOpen
? "bg-accent text-foreground"
: "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
)}
>
<div className="flex size-5 items-center justify-center">
<LuLayers className="size-4" strokeWidth={STROKE_WIDTH} />
<div className="flex items-center gap-1">
<div className="flex-1 min-w-0">
<OrganizationDropdown variant="expanded" />
</div>
<span className="flex-1 text-left">Workspaces</span>
</button>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<button
type="button"
className="flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
>
<LuFolderPlus className="size-4" />
</button>
</TooltipTrigger>
<TooltipContent side="right">Add Repository</TooltipContent>
</Tooltip>
</div>

<button
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import { cn } from "@superset/ui/utils";
import { type ComponentPropsWithoutRef, forwardRef } from "react";
import { HiChevronRight, HiMiniPlus } from "react-icons/hi2";
import { LuPencil } from "react-icons/lu";
import { ProjectThumbnail } from "renderer/routes/_authenticated/components/ProjectThumbnail";
import { RenameInput } from "renderer/screens/main/components/WorkspaceSidebar/RenameInput";

Expand Down Expand Up @@ -52,6 +51,7 @@ export const DashboardSidebarProjectRow = forwardRef<
role={isRenaming ? undefined : "button"}
tabIndex={isRenaming ? undefined : 0}
onClick={isRenaming ? undefined : onToggleCollapse}
Comment on lines 51 to 53
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Expose expanded/collapsed state on the interactive row.

Since the row is now the collapse control (role="button"), it should report state with aria-expanded for screen reader users.

Suggested fix
 				role={isRenaming ? undefined : "button"}
 				tabIndex={isRenaming ? undefined : 0}
+				aria-expanded={isRenaming ? undefined : !isCollapsed}
📝 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
role={isRenaming ? undefined : "button"}
tabIndex={isRenaming ? undefined : 0}
onClick={isRenaming ? undefined : onToggleCollapse}
role={isRenaming ? undefined : "button"}
tabIndex={isRenaming ? undefined : 0}
aria-expanded={isRenaming ? undefined : !isCollapsed}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarProjectRow/DashboardSidebarProjectRow.tsx`
around lines 51 - 53, The interactive row in DashboardSidebarProjectRow
currently gets role="button" but doesn't expose its state to assistive tech;
when rendering the clickable row (i.e., when isRenaming is false and
onToggleCollapse is used), add an aria-expanded attribute that reflects the
collapse state (use the same state variable used by the collapse logic—e.g.,
isCollapsed or isExpanded—so aria-expanded={isRenaming ? undefined :
!isCollapsed} or aria-expanded={isRenaming ? undefined : isExpanded}) so screen
readers can know whether the section is expanded or collapsed.

onDoubleClick={isRenaming ? undefined : onStartRename}
Comment on lines 53 to +54
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent duplicate collapse toggles on double-click rename.

Double-click emits click events first, so this path can fire onToggleCollapse multiple times before onStartRename, causing extra state churn/flicker.

Suggested fix
-				onClick={isRenaming ? undefined : onToggleCollapse}
+				onClick={
+					isRenaming
+						? undefined
+						: (event) => {
+								// Ignore multi-clicks; double-click is reserved for rename.
+								if (event.detail > 1) return;
+								onToggleCollapse();
+							}
+				}
 				onDoubleClick={isRenaming ? undefined : onStartRename}
📝 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
onClick={isRenaming ? undefined : onToggleCollapse}
onDoubleClick={isRenaming ? undefined : onStartRename}
onClick={
isRenaming
? undefined
: (event) => {
// Ignore multi-clicks; double-click is reserved for rename.
if (event.detail > 1) return;
onToggleCollapse();
}
}
onDoubleClick={isRenaming ? undefined : onStartRename}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarProjectRow/DashboardSidebarProjectRow.tsx`
around lines 53 - 54, Double-click currently triggers onClick (onToggleCollapse)
before onDoubleClick (onStartRename), causing duplicate toggles; update
DashboardSidebarProjectRow so onClick ignores clicks that are part of a
double-click by adding a short-lived suppression flag: create a ref (e.g.
suppressClickRef) checked at the top of onToggleCollapse wrapper to return early
if set, set suppressClickRef.current = true at the start of onStartRename (or
its wrapper) and clear it after a short timeout (e.g. 200ms) or once rename mode
is entered; keep using isRenaming to disable handlers otherwise and reference
the existing onToggleCollapse, onStartRename and isRenaming symbols when
applying the change.

onKeyDown={
isRenaming
? undefined
Expand All @@ -70,10 +70,21 @@ export const DashboardSidebarProjectRow = forwardRef<
{...props}
>
<div className="flex min-w-0 flex-1 items-center gap-2 py-0.5">
<ProjectThumbnail
projectName={projectName}
githubOwner={githubOwner}
/>
<div className="relative shrink-0 size-5 flex items-center justify-center">
<span className="group-hover:opacity-0 transition-opacity duration-150">
<ProjectThumbnail
projectName={projectName}
githubOwner={githubOwner}
className="size-4"
/>
</span>
<HiChevronRight
className={cn(
"absolute inset-0 m-auto size-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-all duration-150",
!isCollapsed && "rotate-90",
)}
/>
</div>
{isRenaming ? (
<RenameInput
value={renameValue}
Expand All @@ -85,26 +96,11 @@ export const DashboardSidebarProjectRow = forwardRef<
) : (
<span className="truncate">{projectName}</span>
)}
<div className="grid shrink-0 items-center [&>*]:col-start-1 [&>*]:row-start-1">
{!isRenaming && (
<span className="text-xs font-normal tabular-nums text-muted-foreground transition-all duration-150 group-hover:scale-95 group-hover:opacity-0">
({totalWorkspaceCount})
</span>
)}
{!isRenaming && (
<button
type="button"
onClick={(event) => {
event.stopPropagation();
onStartRename();
}}
className="flex items-center justify-center opacity-0 scale-90 text-muted-foreground transition-all duration-150 group-hover:scale-100 group-hover:opacity-100 hover:text-foreground"
aria-label="Rename project"
>
<LuPencil className="size-3.5 transition-transform duration-150 group-hover:rotate-[-8deg]" />
</button>
)}
</div>
{!isRenaming && (
<span className="shrink-0 text-xs font-normal tabular-nums text-muted-foreground">
({totalWorkspaceCount})
</span>
)}
</div>

<Tooltip delayDuration={500}>
Expand All @@ -125,24 +121,6 @@ export const DashboardSidebarProjectRow = forwardRef<
New workspace
</TooltipContent>
</Tooltip>

<button
type="button"
onClick={(event) => {
event.stopPropagation();
onToggleCollapse();
}}
onContextMenu={(event) => event.stopPropagation()}
aria-expanded={!isCollapsed}
className="p-1 rounded hover:bg-muted transition-colors shrink-0 ml-1"
>
<HiChevronRight
className={cn(
"size-3.5 text-muted-foreground transition-transform duration-150",
!isCollapsed && "rotate-90",
)}
/>
</button>
</div>
);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { cn } from "@superset/ui/utils";
import { LuCloud, LuFolderGit2, LuLaptop } from "react-icons/lu";
import { LuCloud, LuGitMerge, LuLaptop } from "react-icons/lu";
import { AsciiSpinner } from "renderer/screens/main/components/AsciiSpinner";
import { StatusIndicator } from "renderer/screens/main/components/StatusIndicator";
import type { ActivePaneStatus } from "shared/tabs-types";
Expand Down Expand Up @@ -50,7 +50,7 @@ export function DashboardSidebarWorkspaceIcon({
strokeWidth={1.75}
/>
) : (
<LuFolderGit2
<LuGitMerge
className={cn(
"size-4 transition-colors",
variant === "expanded" && "transition-colors",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { FEATURE_FLAGS } from "@superset/shared/constants";
import { useMatchRoute, useParams } from "@tanstack/react-router";
import { useFeatureFlagEnabled } from "posthog-js/react";
import { HiOutlineWifi } from "react-icons/hi2";
import { useOnlineStatus } from "renderer/hooks/useOnlineStatus";
import { electronTrpc } from "renderer/lib/electron-trpc";
Expand All @@ -7,6 +9,7 @@ import { NavigationControls } from "./components/NavigationControls";
import { OpenInMenuButton } from "./components/OpenInMenuButton";
import { OrganizationDropdown } from "./components/OrganizationDropdown";
import { ResourceConsumption } from "./components/ResourceConsumption";
import { RightSidebarToggle } from "./components/RightSidebarToggle";
import { SearchBarTrigger } from "./components/SearchBarTrigger";
import { SidebarToggle } from "./components/SidebarToggle";
import { V2WorkspaceOpenInButton } from "./components/V2WorkspaceOpenInButton";
Expand All @@ -28,6 +31,8 @@ export function TopBar() {
{ enabled: !!workspaceId && !isV2WorkspaceRoute },
);
const isOnline = useOnlineStatus();
const isV2CloudEnabled =
useFeatureFlagEnabled(FEATURE_FLAGS.V2_CLOUD) ?? false;
// Default to Mac layout while loading to avoid overlap with traffic lights
const isMac = platform === undefined || platform === "darwin";

Expand Down Expand Up @@ -82,7 +87,10 @@ export function TopBar() {
projectId={workspace.project?.id}
/>
) : null}
<OrganizationDropdown />
{!isV2CloudEnabled && <OrganizationDropdown />}
{isV2WorkspaceRoute && (
<RightSidebarToggle workspaceId={v2WorkspaceId} />
)}
{!isMac && <WindowControls />}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ import { authClient } from "renderer/lib/auth-client";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider";

export function OrganizationDropdown() {
export function OrganizationDropdown({
variant = "topbar",
}: {
variant?: "topbar" | "expanded" | "collapsed";
}) {
const { data: session } = authClient.useSession();
const collections = useCollections();
const signOutMutation = electronTrpc.auth.signOut.useMutation();
Expand Down Expand Up @@ -65,27 +69,60 @@ export function OrganizationDropdown() {
const userName = session?.user?.name;
const displayName = activeOrganization?.name ?? userName ?? "Organization";

const triggerButton =
variant === "collapsed" ? (
<button
type="button"
className="flex size-8 items-center justify-center rounded-md transition-colors text-muted-foreground hover:bg-accent/50 hover:text-foreground"
aria-label="Organization menu"
>
<Avatar
size="xs"
fullName={activeOrganization?.name}
image={activeOrganization?.logo}
className="rounded size-4"
/>
</button>
) : variant === "expanded" ? (
<button
type="button"
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground min-w-0"
aria-label="Organization menu"
>
<Avatar
size="xs"
fullName={activeOrganization?.name}
image={activeOrganization?.logo}
className="rounded size-4 shrink-0"
/>
<span className="truncate">{displayName}</span>
<HiChevronUpDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
</button>
Comment on lines +87 to +100
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read it
cat -n "apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/OrganizationDropdown/OrganizationDropdown.tsx" | head -110 | tail -40

Repository: superset-sh/superset

Length of output: 1767


Make the expanded label shrinkable.

In a flex row, the span needs min-w-0 to shrink below its content width and enable the truncate class to work. Without it, long organization names will push the chevron instead of ellipsizing. Adding flex-1 allows the label to grow and fill available space.

Suggested fix
-				<span className="truncate">{displayName}</span>
+				<span className="min-w-0 flex-1 truncate">{displayName}</span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/OrganizationDropdown/OrganizationDropdown.tsx`
around lines 87 - 100, The span showing the organization label in
OrganizationDropdown doesn't shrink because it lacks the min-w-0/flex rules;
update the span that renders displayName inside the button (in
OrganizationDropdown) to include "min-w-0 flex-1" (keeping the existing
"truncate") so long names ellipsize instead of pushing the chevron; no other
structural changes needed.

) : (
<button
type="button"
className="no-drag flex items-center gap-1.5 h-6 px-1.5 rounded border border-border/60 bg-secondary/50 hover:bg-secondary hover:border-border transition-all duration-150 ease-out focus:outline-none focus:ring-1 focus:ring-ring"
aria-label="Organization menu"
>
<Avatar
size="xs"
fullName={activeOrganization?.name}
image={activeOrganization?.logo}
className="rounded size-4"
/>
<span className="text-xs font-medium truncate max-w-32">
{displayName}
</span>
<HiChevronUpDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
</button>
);

const contentAlign = variant === "topbar" ? "end" : "start";

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
type="button"
className="no-drag flex items-center gap-1.5 h-6 px-1.5 rounded border border-border/60 bg-secondary/50 hover:bg-secondary hover:border-border transition-all duration-150 ease-out focus:outline-none focus:ring-1 focus:ring-ring"
aria-label="Organization menu"
>
<Avatar
size="xs"
fullName={activeOrganization?.name}
image={activeOrganization?.logo}
className="rounded size-4"
/>
<span className="text-xs font-medium truncate max-w-32">
{displayName}
</span>
<HiChevronUpDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuTrigger asChild>{triggerButton}</DropdownMenuTrigger>
<DropdownMenuContent align={contentAlign} className="w-56">
{/* Organization */}
<DropdownMenuItem
onSelect={() => navigate({ to: "/settings/account" })}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import {
LuPanelRight,
LuPanelRightClose,
LuPanelRightOpen,
} from "react-icons/lu";
import { HotkeyLabel } from "renderer/hotkeys";
import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider";

export function RightSidebarToggle({ workspaceId }: { workspaceId: string }) {
const collections = useCollections();
const localState = collections.v2WorkspaceLocalState.get(workspaceId);
const isOpen = localState?.rightSidebarOpen ?? false;

const toggle = () => {
collections.v2WorkspaceLocalState.update(workspaceId, (draft) => {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 6, 2026

Choose a reason for hiding this comment

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

P2: Guard v2WorkspaceLocalState.update with an existence check before toggling right sidebar state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/RightSidebarToggle/RightSidebarToggle.tsx, line 20:

<comment>Guard `v2WorkspaceLocalState.update` with an existence check before toggling right sidebar state.</comment>

<file context>
@@ -0,0 +1,59 @@
+	const isOpen = localState?.rightSidebarOpen ?? false;
+
+	const toggle = () => {
+		collections.v2WorkspaceLocalState.update(workspaceId, (draft) => {
+			draft.rightSidebarOpen = !draft.rightSidebarOpen;
+		});
</file context>
Fix with Cubic

draft.rightSidebarOpen = !draft.rightSidebarOpen;
});
};

const getToggleIcon = (isHovering: boolean) => {
if (!isOpen) {
return isHovering ? (
<LuPanelRightOpen className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRight className="size-4" strokeWidth={1.5} />
);
}
return isHovering ? (
<LuPanelRightClose className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRight className="size-4" strokeWidth={1.5} />
);
};
Comment on lines +21 to +34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Open state has no distinct resting icon

The getToggleIcon function returns LuPanelRight (a neutral icon) for both isOpen=false and isOpen=true when not hovering. This means the button looks identical whether the sidebar is open or closed at rest, giving the user no visual feedback about the current state.

Consider returning LuPanelRightOpen when the sidebar is open and not hovering, to mirror typical toggle button conventions:

Suggested change
const getToggleIcon = (isHovering: boolean) => {
if (!isOpen) {
return isHovering ? (
<LuPanelRightOpen className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRight className="size-4" strokeWidth={1.5} />
);
}
return isHovering ? (
<LuPanelRightClose className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRight className="size-4" strokeWidth={1.5} />
);
};
const getToggleIcon = (isHovering: boolean) => {
if (!isOpen) {
return isHovering ? (
<LuPanelRightOpen className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRight className="size-4" strokeWidth={1.5} />
);
}
return isHovering ? (
<LuPanelRightClose className="size-4" strokeWidth={1.5} />
) : (
<LuPanelRightOpen className="size-4" strokeWidth={1.5} />
);
};

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


return (
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<button
type="button"
onClick={toggle}
className="no-drag group flex items-center justify-center size-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
>
<span className="group-hover:hidden">{getToggleIcon(false)}</span>
<span className="hidden group-hover:block">
{getToggleIcon(true)}
</span>
</button>
</TooltipTrigger>
<TooltipContent side="left">
<HotkeyLabel label="Toggle sidebar" id="TOGGLE_SIDEBAR" />
Comment on lines +39 to +51
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Give the new icon button a specific accessible name and state.

Right now this is an unnamed icon-only control, and "Toggle sidebar" is ambiguous because the top bar already has a left SidebarToggle. Please expose it as the right-sidebar toggle and report its pressed state.

Suggested fix
 				<button
 					type="button"
 					onClick={toggle}
+					aria-label="Toggle right sidebar"
+					aria-pressed={isOpen}
 					className="no-drag group flex items-center justify-center size-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
 				>
@@
 			<TooltipContent side="left">
-				<HotkeyLabel label="Toggle sidebar" id="TOGGLE_SIDEBAR" />
+				<HotkeyLabel label="Toggle right sidebar" id="TOGGLE_SIDEBAR" />
 			</TooltipContent>
📝 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
<button
type="button"
onClick={toggle}
className="no-drag group flex items-center justify-center size-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
>
<span className="group-hover:hidden">{getToggleIcon(false)}</span>
<span className="hidden group-hover:block">
{getToggleIcon(true)}
</span>
</button>
</TooltipTrigger>
<TooltipContent side="left">
<HotkeyLabel label="Toggle sidebar" id="TOGGLE_SIDEBAR" />
<button
type="button"
onClick={toggle}
aria-label="Toggle right sidebar"
aria-pressed={isOpen}
className="no-drag group flex items-center justify-center size-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
>
<span className="group-hover:hidden">{getToggleIcon(false)}</span>
<span className="hidden group-hover:block">
{getToggleIcon(true)}
</span>
</button>
</TooltipTrigger>
<TooltipContent side="left">
<HotkeyLabel label="Toggle right sidebar" id="TOGGLE_SIDEBAR" />
</TooltipContent>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/RightSidebarToggle/RightSidebarToggle.tsx`
around lines 43 - 55, The right-sidebar icon button is currently unnamed and
ambiguous; update the RightSidebarToggle component to provide an explicit
accessible name and state by adding an aria-label like "Toggle right sidebar"
and an aria-pressed attribute bound to the current open/closed state (the same
boolean passed into getToggleIcon/toggle). Also update the HotkeyLabel
invocation to use "Toggle right sidebar" and a unique id (e.g.,
"TOGGLE_RIGHT_SIDEBAR") so the tooltip and keyboard hint match the control;
ensure you reference the button element, the toggle handler, and the
getToggleIcon(boolean) usage when making these changes.

</TooltipContent>
</Tooltip>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RightSidebarToggle } from "./RightSidebarToggle";
Loading
Loading