From 1a9f131d398e95fe1b7f1b2d1fbbf34081016fef Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Mon, 1 Sep 2025 21:18:56 -0600 Subject: [PATCH] refactor: enhance environment selector with service presence checks and alert notifications; update navigation links to include environment context for improved user experience --- .../project/advanced-environment-selector.tsx | 14 +++++++++++++- .../dokploy/components/dashboard/projects/show.tsx | 2 +- .../components/shared/breadcrumb-sidebar.tsx | 8 ++++---- .../[projectId]/environment/[environmentId].tsx | 1 - .../services/application/[applicationId].tsx | 1 - .../services/compose/[composeId].tsx | 1 - .../services/mariadb/[mariadbId].tsx | 1 - .../[environmentId]/services/mongo/[mongoId].tsx | 1 - .../[environmentId]/services/mysql/[mysqlId].tsx | 1 - .../services/postgres/[postgresId].tsx | 2 -- .../[environmentId]/services/redis/[redisId].tsx | 1 - packages/server/src/services/environment.ts | 12 ++++++++++-- 12 files changed, 28 insertions(+), 17 deletions(-) diff --git a/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx b/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx index fa7ab47e9..5246df5dd 100644 --- a/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx +++ b/apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx @@ -24,6 +24,7 @@ import { Textarea } from "@/components/ui/textarea"; import { toast } from "sonner"; import { ChevronDownIcon, PlusIcon, PencilIcon, TrashIcon } from "lucide-react"; import { Badge } from "@/components/ui/badge"; +import { AlertBlock } from "@/components/shared/alert-block"; interface Environment { environmentId: string; @@ -54,6 +55,11 @@ export const AdvancedEnvironmentSelector = ({ const [description, setDescription] = useState(""); // API mutations + const { data: environment } = api.environment.one.useQuery({ environmentId: currentEnvironmentId || "" },{ + enabled: !!currentEnvironmentId, + }); + + const haveServices = environment && (environment?.mariadb?.length > 0 || environment?.mongo?.length > 0 || environment?.mysql?.length > 0 || environment?.postgres?.length > 0 || environment?.redis?.length > 0 || environment?.applications?.length > 0 || environment?.compose?.length > 0); const createEnvironment = api.environment.create.useMutation(); const updateEnvironment = api.environment.update.useMutation(); const deleteEnvironment = api.environment.remove.useMutation(); @@ -356,6 +362,12 @@ export const AdvancedEnvironmentSelector = ({ This action cannot be undone and will also delete all services in this environment. + + {haveServices && ( + + This environment have active services, please delete them first. + + )} diff --git a/apps/dokploy/components/dashboard/projects/show.tsx b/apps/dokploy/components/dashboard/projects/show.tsx index bba892857..a3b5d1ff9 100644 --- a/apps/dokploy/components/dashboard/projects/show.tsx +++ b/apps/dokploy/components/dashboard/projects/show.tsx @@ -216,7 +216,7 @@ export const ShowProjects = () => { className="w-full lg:max-w-md" > {haveServicesWithDomains ? ( diff --git a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx index ed30dfaad..7bde4761e 100644 --- a/apps/dokploy/components/shared/breadcrumb-sidebar.tsx +++ b/apps/dokploy/components/shared/breadcrumb-sidebar.tsx @@ -13,7 +13,7 @@ import { SidebarTrigger } from "@/components/ui/sidebar"; interface Props { list: { name: string; - href: string; + href?: string; }[]; } @@ -29,11 +29,11 @@ export const BreadcrumbSidebar = ({ list }: Props) => { {list.map((item, index) => ( - + {item.href ? ( - {item.name} + {item?.name} ) : ( - item.name + item?.name )} diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx index 7a6e69867..5586d90fe 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId].tsx @@ -757,7 +757,6 @@ const EnvironmentPage = ( }, { name: currentEnvironment.name, - href: `/dashboard/project/${projectId}/environment/${environmentId}`, }, ]} /> diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/application/[applicationId].tsx index 2a1c22b1b..b88f1ad3e 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/environment/[environmentId]/services/application/[applicationId].tsx @@ -106,7 +106,6 @@ const Service = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/application/${applicationId}`, }, ]} /> 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 c586dc66c..23ddb34e4 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 @@ -97,7 +97,6 @@ const Service = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/compose/${composeId}`, }, ]} /> 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 3bb18fe4e..b268beec8 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 @@ -78,7 +78,6 @@ const Mariadb = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mariadb/${mariadbId}`, }, ]} /> 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 8d250a7d3..046666550 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 @@ -78,7 +78,6 @@ const Mongo = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mongo/${mongoId}`, }, ]} /> 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 093453a0d..d940c21b8 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 @@ -77,7 +77,6 @@ const MySql = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/mysql/${mysqlId}`, }, ]} /> 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 41522516e..ed04f8205 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 @@ -78,8 +78,6 @@ const Postgresql = ( }, { name: data?.name || "", - href: - `/dashboard/project/${projectId}/environment/${environmentId}/services/postgres/${postgresId}`, }, ]} /> 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 c7c79237f..891df9dac 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 @@ -78,7 +78,6 @@ const Redis = ( }, { name: data?.name || "", - href: `/dashboard/project/${projectId}/environment/${environmentId}/services/redis/${redisId}`, }, ]} /> diff --git a/packages/server/src/services/environment.ts b/packages/server/src/services/environment.ts index b88cfe2f2..45341fecf 100644 --- a/packages/server/src/services/environment.ts +++ b/packages/server/src/services/environment.ts @@ -62,13 +62,21 @@ export const findEnvironmentsByProjectId = async (projectId: string) => { }; export const deleteEnvironment = async (environmentId: string) => { - const environment = await db + + const currentEnvironment = await findEnvironmentById(environmentId); + if (currentEnvironment.name === "production") { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "You cannot delete the production environment", + }); + } + const deletedEnvironment = await db .delete(environments) .where(eq(environments.environmentId, environmentId)) .returning() .then((value) => value[0]); - return environment; + return deletedEnvironment; }; export const updateEnvironmentById = async (