From 3e356e6890e43c1e6c96df2dc2a9bf5894a90795 Mon Sep 17 00:00:00 2001 From: Bima42 Date: Sun, 14 Dec 2025 17:01:44 +0100 Subject: [PATCH] feat: being able to switch environments in sidebar --- .../components/shared/breadcrumb-sidebar.tsx | 50 +++++++++++++++---- .../environment/[environmentId].tsx | 11 ++++ .../services/compose/[composeId].tsx | 10 +++- .../services/mariadb/[mariadbId].tsx | 11 +++- .../services/mongo/[mongoId].tsx | 10 +++- .../services/mysql/[mysqlId].tsx | 10 +++- .../services/postgres/[postgresId].tsx | 10 +++- .../services/redis/[redisId].tsx | 10 +++- 8 files changed, 106 insertions(+), 16 deletions(-) diff --git a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx index 7bde4761e..c3428e301 100644 --- a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx +++ b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx @@ -1,22 +1,36 @@ import Link from "next/link"; import { Fragment } from "react"; +import { ChevronDown } from "lucide-react"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, + BreadcrumbPage, } from "@/components/ui/breadcrumb"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Separator } from "@/components/ui/separator"; import { SidebarTrigger } from "@/components/ui/sidebar"; -interface Props { - list: { +interface BreadcrumbEntry { + name: string; + href?: string; + dropdownItems?: { name: string; - href?: string; + href: string; }[]; } +interface Props { + list: BreadcrumbEntry[]; +} + export const BreadcrumbSidebar = ({ list }: Props) => { return (
@@ -29,13 +43,29 @@ export const BreadcrumbSidebar = ({ list }: Props) => { {list.map((item, index) => ( - - {item.href ? ( - {item?.name} - ) : ( - item?.name - )} - + {item.dropdownItems && item.dropdownItems.length > 0 ? ( + + + {item.name} + + + + {item.dropdownItems.map((subItem) => ( + + {subItem.name} + + ))} + + + ) : ( + + {item.href ? ( + {item?.name} + ) : ( + {item?.name} + )} + + )} {index + 1 < list.length && ( diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx index a2e54ad51..dcc34cec2 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx @@ -279,6 +279,16 @@ const EnvironmentPage = ( const [isBulkActionLoading, setIsBulkActionLoading] = useState(false); const { projectId, environmentId } = props; const { data: auth } = api.user.get.useQuery(); + + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: projectId, + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; + const [sortBy, setSortBy] = useState(() => { if (typeof window !== "undefined") { return localStorage.getItem("servicesSort") || "lastDeploy-desc"; @@ -863,6 +873,7 @@ const EnvironmentPage = ( }, { name: currentEnvironment.name, + dropdownItems: environmentDropdownItems, }, ]} /> diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx index df7cb9a9c..56b4b5d0c 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/compose/[composeId].tsx @@ -80,6 +80,14 @@ const Service = ( const { data: auth } = api.user.get.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; return (
@@ -92,7 +100,7 @@ const Service = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "", diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx index e5133a9bb..d47fbd14d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mariadb/[mariadbId].tsx @@ -62,6 +62,15 @@ const Mariadb = ( const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; + return (
@@ -73,7 +82,7 @@ const Mariadb = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "", diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx index 2de7350b7..660315d5a 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mongo/[mongoId].tsx @@ -61,6 +61,14 @@ const Mongo = ( const { data: auth } = api.user.get.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; return (
@@ -73,7 +81,7 @@ const Mongo = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "", diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx index 23227f385..7f4cc791c 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/mysql/[mysqlId].tsx @@ -60,6 +60,14 @@ const MySql = ( const { data: auth } = api.user.get.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; return (
@@ -72,7 +80,7 @@ const MySql = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "", diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx index 8fe7742e3..a34f7b7ee 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/postgres/[postgresId].tsx @@ -60,6 +60,14 @@ const Postgresql = ( const { data: auth } = api.user.get.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; return (
@@ -72,7 +80,7 @@ const Postgresql = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "", diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx index 14c873094..72a513fba 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/redis/[redisId].tsx @@ -60,6 +60,14 @@ const Redis = ( const { data: auth } = api.user.get.useQuery(); const { data: isCloud } = api.settings.isCloud.useQuery(); + const { data: environments } = api.environment.byProjectId.useQuery({ + projectId: data?.environment?.projectId || "", + }); + const environmentDropdownItems = + environments?.map((env) => ({ + name: env.name, + href: `/dashboard/project/${projectId}/environment/${env.environmentId}`, + })) || []; return (
@@ -72,7 +80,7 @@ const Redis = ( }, { name: data?.environment?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}`, + dropdownItems: environmentDropdownItems, }, { name: data?.name || "",