-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
init sidebar refactor #218
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import type { Workspace } from "@ctrlplane/db/schema"; | ||
import React from "react"; | ||
import { | ||
IconCategory, | ||
IconObjectScan, | ||
IconPlant, | ||
IconRocket, | ||
IconRun, | ||
IconShip, | ||
IconVariable, | ||
} from "@tabler/icons-react"; | ||
|
||
import { SidebarContent, SidebarHeader } from "@ctrlplane/ui/sidebar"; | ||
|
||
import { api } from "~/trpc/server"; | ||
import { AppSidebarHeader } from "./AppSidebarHeader"; | ||
import { AppSidebarPopover } from "./AppSidebarPopover"; | ||
import { SidebarWithPopover } from "./AppSidebarPopoverContext"; | ||
import { SidebarNavMain } from "./SidebarNavMain"; | ||
|
||
const navMain = (prefix: string) => [ | ||
{ | ||
title: "Systems", | ||
url: `${prefix}/systems`, | ||
icon: IconCategory, | ||
isActive: true, | ||
items: [ | ||
{ | ||
title: "Dependencies", | ||
url: `${prefix}/dependencies`, | ||
isActive: true, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "Resources", | ||
url: `${prefix}/resources`, | ||
popoverId: "resources", | ||
icon: IconObjectScan, | ||
isActive: true, | ||
items: [ | ||
{ | ||
title: "List", | ||
url: `${prefix}/targets`, | ||
}, | ||
{ | ||
title: "Providers", | ||
url: `${prefix}/target-providers`, | ||
}, | ||
{ | ||
title: "Groups", | ||
url: `${prefix}/target-metadata-groups`, | ||
}, | ||
{ | ||
title: "Views", | ||
url: `${prefix}/target-views`, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "Jobs", | ||
url: "#", | ||
icon: IconRocket, | ||
items: [ | ||
{ | ||
title: "Agents", | ||
url: "#", | ||
}, | ||
{ | ||
title: "Runs", | ||
url: "#", | ||
}, | ||
], | ||
}, | ||
]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Based on the findings, I can now provide a final response about the placeholder URLs in the navigation. Update navigation URLs to match implemented routes The placeholder URLs in {
title: "Jobs",
url: `${prefix}/job-agents`, // Update from "#"
icon: IconRocket,
items: [
{
title: "Agents",
url: `${prefix}/job-agents`, // Update from "#"
},
{
title: "Runs",
url: `${prefix}/jobs`, // Update from "#"
},
],
} The routes are fully implemented with corresponding pages:
🔗 Analysis chainReview and implement placeholder navigation URLs Several navigation items are using "#" as placeholder URLs. These should be implemented with proper routing paths. Would you like help implementing the proper routing paths based on the application's routing structure? Let me analyze the findings from the router definitions and navigation paths. The search results show that the application has well-defined routers in the backend ( Let me check the specific job-related pages and routes to verify the implementation. Let me try a different approach to check the job-related implementations. Let me check the actual page implementations to verify the routes. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Search for route definitions to ensure consistency
rg -g '*.ts*' 'createNextRouter|Route|router\.' -A 3
Length of output: 167700 Script: #!/bin/bash
# Search for job-related routes and pages
rg -g '*.tsx' -g '*.ts' 'jobs|agents|runs' apps/webservice/src/app/\[workspaceSlug\]/ -l
Length of output: 3748 Script: #!/bin/bash
# Check the job-related pages and routes
rg -g '*.tsx' -g '*.ts' 'page.tsx|layout.tsx' apps/webservice/src/app/\[workspaceSlug\]/\(job\)/ -A 5
Length of output: 101 Script: #!/bin/bash
# Check contents of job-related components
cat apps/webservice/src/app/\[workspaceSlug\]/\(job\)/jobs/JobsGettingStarted.tsx apps/webservice/src/app/\[workspaceSlug\]/\(job\)/job-agents/JobAgentsGettingStarted.tsx 2>/dev/null
# Also check for any route definitions in the job folder
find apps/webservice/src/app/\[workspaceSlug\]/\(job\)/ -type f -name "page.tsx" -o -name "layout.tsx" 2>/dev/null
Length of output: 3323 Script: #!/bin/bash
# Check the contents of the job-related pages
cat apps/webservice/src/app/\[workspaceSlug\]/\(job\)/jobs/page.tsx apps/webservice/src/app/\[workspaceSlug\]/\(job\)/job-agents/page.tsx apps/webservice/src/app/\[workspaceSlug\]/\(job\)/layout.tsx 2>/dev/null
Length of output: 5794 |
||
|
||
export const AppSidebar: React.FC<{ workspace: Workspace }> = async ({ | ||
workspace, | ||
}) => { | ||
const [workspaces, viewer, systems] = await Promise.all([ | ||
api.workspace.list(), | ||
api.user.viewer(), | ||
api.system.list({ workspaceId: workspace.id }), | ||
]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for API calls The Promise.all call lacks error handling, which could lead to unhandled rejections. Consider implementing proper error boundaries or try-catch blocks. - const [workspaces, viewer, systems] = await Promise.all([
- api.workspace.list(),
- api.user.viewer(),
- api.system.list({ workspaceId: workspace.id }),
- ]);
+ try {
+ const [workspaces, viewer, systems] = await Promise.all([
+ api.workspace.list(),
+ api.user.viewer(),
+ api.system.list({ workspaceId: workspace.id }),
+ ]);
+ } catch (error) {
+ // Consider implementing error boundary or error state
+ console.error('Failed to fetch sidebar data:', error);
+ throw error;
+ }
|
||
|
||
const navSystem = systems.items.map((s) => ({ | ||
title: s.name, | ||
url: "#", | ||
isActive: true, | ||
items: [ | ||
{ | ||
title: "Environments", | ||
icon: IconPlant, | ||
url: "#", | ||
}, | ||
{ | ||
title: "Deployements", | ||
icon: IconShip, | ||
url: "#", | ||
}, | ||
{ | ||
title: "Runbooks", | ||
icon: IconRun, | ||
url: "#", | ||
}, | ||
{ | ||
title: "Variable Sets", | ||
icon: IconVariable, | ||
url: "#", | ||
}, | ||
], | ||
})); | ||
|
||
return ( | ||
<SidebarWithPopover> | ||
<AppSidebarPopover /> | ||
<SidebarHeader> | ||
<AppSidebarHeader | ||
workspace={workspace} | ||
workspaces={workspaces} | ||
viewer={viewer} | ||
systems={systems.items} | ||
/> | ||
</SidebarHeader> | ||
<SidebarContent> | ||
<SidebarNavMain | ||
title="Workspace" | ||
items={navMain(`/${workspace.slug}`)} | ||
/> | ||
<SidebarNavMain title="Systems" items={navSystem} /> | ||
</SidebarContent> | ||
</SidebarWithPopover> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,8 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"use client"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { Workspace } from "@ctrlplane/db/schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useState } from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useParams } from "next/navigation"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { IconPlus } from "@tabler/icons-react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Button } from "@ctrlplane/ui/button"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -12,17 +15,35 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DropdownMenuTrigger, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "@ctrlplane/ui/dropdown-menu"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { api } from "~/trpc/react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { CreateDeploymentDialog } from "./_components/CreateDeployment"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { CreateReleaseDialog } from "./_components/CreateRelease"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { CreateSystemDialog } from "./_components/CreateSystem"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { CreateTargetDialog } from "./_components/CreateTarget"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { CreateSessionDialog } from "./_components/terminal/CreateDialogSession"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const SidebarCreateMenu: React.FC<{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const AppSidebarCreateMenu: React.FC<{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspace: Workspace; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deploymentId?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
systemId?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}> = (props) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}> = ({ workspace }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { deploymentSlug, workspaceSlug, systemSlug } = useParams<{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspaceSlug: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
systemSlug?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deploymentSlug?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const system = api.system.bySlug.useQuery( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ workspaceSlug, systemSlug: systemSlug ?? "" }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ enabled: systemSlug != null }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const deployment = api.deployment.bySlug.useQuery( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspaceSlug, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
systemSlug: systemSlug ?? "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deploymentSlug: deploymentSlug ?? "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ enabled: deploymentSlug != null && systemSlug != null }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [open, setOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenu open={open} onOpenChange={setOpen}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -42,19 +63,26 @@ export const SidebarCreateMenu: React.FC<{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuGroup> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateSystemDialog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspace={props.workspace} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspace={workspace} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onSuccess={() => setOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem onSelect={(e) => e.preventDefault()}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
New System | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</CreateSystemDialog> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateDeploymentDialog {...props} onSuccess={() => setOpen(false)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateDeploymentDialog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
systemId={system.data?.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onSuccess={() => setOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem onSelect={(e) => e.preventDefault()}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
New Deployment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</CreateDeploymentDialog> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateReleaseDialog {...props} onClose={() => setOpen(false)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateReleaseDialog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
systemId={system.data?.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deploymentId={deployment.data?.id} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onClose={() => setOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Prevent potential race conditions with query data. The dialogs might be opened before query data is available. Consider disabling the menu items when the required data is not yet loaded. <CreateDeploymentDialog
systemId={system.data?.id}
onSuccess={() => setOpen(false)}
>
- <DropdownMenuItem onSelect={(e) => e.preventDefault()}>
+ <DropdownMenuItem
+ onSelect={(e) => e.preventDefault()}
+ disabled={!system.data?.id}
+ >
New Deployment
</DropdownMenuItem>
</CreateDeploymentDialog>
<CreateReleaseDialog
systemId={system.data?.id}
deploymentId={deployment.data?.id}
onClose={() => setOpen(false)}
>
- <DropdownMenuItem onSelect={(e) => e.preventDefault()}>
+ <DropdownMenuItem
+ onSelect={(e) => e.preventDefault()}
+ disabled={!system.data?.id || !deployment.data?.id}
+ >
New Release
</DropdownMenuItem>
</CreateReleaseDialog> 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem onSelect={(e) => e.preventDefault()}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
New Release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -75,7 +103,10 @@ export const SidebarCreateMenu: React.FC<{ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuSeparator /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuGroup> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateTargetDialog {...props} onSuccess={() => setOpen(false)}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<CreateTargetDialog | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspace={workspace} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onSuccess={() => setOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<DropdownMenuItem onSelect={(e) => e.preventDefault()}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Bootstrap Target | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</DropdownMenuItem> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,9 +1,9 @@ | ||||||||||||||||||||||||
"use client"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import type { Workspace } from "@ctrlplane/db/schema"; | ||||||||||||||||||||||||
import type { System, Workspace } from "@ctrlplane/db/schema"; | ||||||||||||||||||||||||
import Link from "next/link"; | ||||||||||||||||||||||||
import { IconCheck, IconChevronDown } from "@tabler/icons-react"; | ||||||||||||||||||||||||
import { signOut, useSession } from "next-auth/react"; | ||||||||||||||||||||||||
import { IconCheck, IconChevronDown, IconSearch } from "@tabler/icons-react"; | ||||||||||||||||||||||||
import { signOut } from "next-auth/react"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import { Button } from "@ctrlplane/ui/button"; | ||||||||||||||||||||||||
import { | ||||||||||||||||||||||||
|
@@ -19,14 +19,17 @@ import { | |||||||||||||||||||||||
DropdownMenuSubTrigger, | ||||||||||||||||||||||||
DropdownMenuTrigger, | ||||||||||||||||||||||||
} from "@ctrlplane/ui/dropdown-menu"; | ||||||||||||||||||||||||
import { SidebarMenu, SidebarMenuItem } from "@ctrlplane/ui/sidebar"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import { api } from "~/trpc/react"; | ||||||||||||||||||||||||
import { SearchDialog } from "./_components/SearchDialog"; | ||||||||||||||||||||||||
import { AppSidebarCreateMenu } from "./AppSidebarCreateMenu"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
export const SidebarWorkspaceDropdown: React.FC<{ workspace: Workspace }> = ({ | ||||||||||||||||||||||||
workspace, | ||||||||||||||||||||||||
}) => { | ||||||||||||||||||||||||
const { data } = useSession(); | ||||||||||||||||||||||||
const workspaces = api.workspace.list.useQuery(); | ||||||||||||||||||||||||
const WorkspaceDropdown: React.FC<{ | ||||||||||||||||||||||||
workspace: Workspace; | ||||||||||||||||||||||||
workspaces: Workspace[]; | ||||||||||||||||||||||||
viewer: { email: string }; | ||||||||||||||||||||||||
}> = ({ workspace, workspaces, viewer }) => { | ||||||||||||||||||||||||
const update = api.profile.update.useMutation(); | ||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||
<DropdownMenu> | ||||||||||||||||||||||||
|
@@ -53,9 +56,9 @@ export const SidebarWorkspaceDropdown: React.FC<{ workspace: Workspace }> = ({ | |||||||||||||||||||||||
<DropdownMenuPortal> | ||||||||||||||||||||||||
<DropdownMenuSubContent className="w-[200px] bg-neutral-900"> | ||||||||||||||||||||||||
<DropdownMenuLabel className="font-normal text-muted-foreground"> | ||||||||||||||||||||||||
{data?.user.email} | ||||||||||||||||||||||||
{viewer.email} | ||||||||||||||||||||||||
</DropdownMenuLabel> | ||||||||||||||||||||||||
{workspaces.data?.map((ws) => ( | ||||||||||||||||||||||||
{workspaces.map((ws) => ( | ||||||||||||||||||||||||
<Link | ||||||||||||||||||||||||
key={ws.id} | ||||||||||||||||||||||||
href={`/${ws.slug}`} | ||||||||||||||||||||||||
|
@@ -85,3 +88,30 @@ export const SidebarWorkspaceDropdown: React.FC<{ workspace: Workspace }> = ({ | |||||||||||||||||||||||
</DropdownMenu> | ||||||||||||||||||||||||
); | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
export const AppSidebarHeader: React.FC<{ | ||||||||||||||||||||||||
systems: System[]; | ||||||||||||||||||||||||
workspace: Workspace; | ||||||||||||||||||||||||
workspaces: Workspace[]; | ||||||||||||||||||||||||
viewer: { email: string }; | ||||||||||||||||||||||||
}> = ({ workspace, workspaces, viewer }) => { | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Remove unused systems prop The export const AppSidebarHeader: React.FC<{
- systems: System[];
workspace: Workspace;
workspaces: Workspace[];
viewer: { email: string };
}> = ({ workspace, workspaces, viewer }) => { 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||
<SidebarMenu> | ||||||||||||||||||||||||
<SidebarMenuItem className="flex items-center gap-2"> | ||||||||||||||||||||||||
<div className="flex-grow overflow-x-auto"> | ||||||||||||||||||||||||
<WorkspaceDropdown | ||||||||||||||||||||||||
workspace={workspace} | ||||||||||||||||||||||||
workspaces={workspaces} | ||||||||||||||||||||||||
viewer={viewer} | ||||||||||||||||||||||||
/> | ||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||
<SearchDialog> | ||||||||||||||||||||||||
<Button variant="ghost" size="icon" className="h-6 w-6 flex-shrink-0"> | ||||||||||||||||||||||||
<IconSearch className="h-4 w-4" /> | ||||||||||||||||||||||||
</Button> | ||||||||||||||||||||||||
</SearchDialog> | ||||||||||||||||||||||||
<AppSidebarCreateMenu workspace={workspace} /> | ||||||||||||||||||||||||
</SidebarMenuItem> | ||||||||||||||||||||||||
</SidebarMenu> | ||||||||||||||||||||||||
); | ||||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
"use client"; | ||
|
||
import React from "react"; | ||
|
||
import { Popover, PopoverAnchor, PopoverContent } from "@ctrlplane/ui/popover"; | ||
|
||
import { useSidebarPopover } from "./AppSidebarPopoverContext"; | ||
|
||
export const AppSidebarPopover: React.FC = () => { | ||
const { activeSidebarItem } = useSidebarPopover(); | ||
return ( | ||
<Popover open={activeSidebarItem != null}> | ||
<PopoverAnchor className="w-full" /> | ||
<PopoverContent | ||
side="right" | ||
sideOffset={1} | ||
className="h-[100vh] w-[300px] border-y-0 border-l-0 bg-black" | ||
> | ||
{activeSidebarItem} | ||
</PopoverContent> | ||
</Popover> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove hardcoded
isActive
statesThe
isActive
property is hardcoded totrue
for multiple navigation items. This should be determined dynamically based on the current route.Consider implementing a utility function to determine the active state:
Also applies to: 31-31, 40-40, 89-89