From 6d33035669e37a39296ee982cc220433a3126e92 Mon Sep 17 00:00:00 2001 From: djknaeckebrot Date: Mon, 23 Dec 2024 12:12:34 +0100 Subject: [PATCH 1/3] refactor: make trigger a dropdowitem --- .../components/dashboard/compose/delete-compose.tsx | 11 ++++++++--- .../components/dashboard/compose/update-compose.tsx | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/apps/dokploy/components/dashboard/compose/delete-compose.tsx b/apps/dokploy/components/dashboard/compose/delete-compose.tsx index 3bdcc6bfa..8f9c7d1ab 100644 --- a/apps/dokploy/components/dashboard/compose/delete-compose.tsx +++ b/apps/dokploy/components/dashboard/compose/delete-compose.tsx @@ -9,6 +9,7 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; +import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import { Form, FormControl, @@ -76,10 +77,14 @@ export const DeleteCompose = ({ composeId }: Props) => { return ( - - + Delete + diff --git a/apps/dokploy/components/dashboard/compose/update-compose.tsx b/apps/dokploy/components/dashboard/compose/update-compose.tsx index 5991c03da..acd5d344d 100644 --- a/apps/dokploy/components/dashboard/compose/update-compose.tsx +++ b/apps/dokploy/components/dashboard/compose/update-compose.tsx @@ -9,6 +9,7 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; +import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import { Form, FormControl, @@ -90,10 +91,14 @@ export const UpdateCompose = ({ composeId }: Props) => { return ( - - + Edit + From ea51294e6d911914a2fef51ba072cfcd7aa37718 Mon Sep 17 00:00:00 2001 From: djknaeckebrot Date: Mon, 23 Dec 2024 12:13:00 +0100 Subject: [PATCH 2/3] refactor: add optional value so we can reuse the component --- .../components/dashboard/project/add-database.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx index aaf4940b0..1ba947f4a 100644 --- a/apps/dokploy/components/dashboard/project/add-database.tsx +++ b/apps/dokploy/components/dashboard/project/add-database.tsx @@ -149,9 +149,14 @@ type AddDatabase = z.infer; interface Props { projectId: string; projectName?: string; + dropdownItemName?: string; } -export const AddDatabase = ({ projectId, projectName }: Props) => { +export const AddDatabase = ({ + projectId, + projectName, + dropdownItemName, +}: Props) => { const utils = api.useUtils(); const [visible, setVisible] = useState(false); const slug = slugify(projectName); @@ -278,7 +283,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => { onSelect={(e) => e.preventDefault()} > - Database + {dropdownItemName ?? "Database"} From 3f7eefba38a545330ec115d65003b62dcda5f864 Mon Sep 17 00:00:00 2001 From: djknaeckebrot Date: Mon, 23 Dec 2024 12:13:57 +0100 Subject: [PATCH 3/3] feat: alert when database it detected and offer to move into dedicated database service --- .../services/compose/[composeId].tsx | 73 ++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx index a4cb855cc..5cd2bcc93 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx @@ -8,14 +8,24 @@ import { ShowGeneralCompose } from "@/components/dashboard/compose/general/show" import { ShowDockerLogsCompose } from "@/components/dashboard/compose/logs/show"; import { ShowMonitoringCompose } from "@/components/dashboard/compose/monitoring/show"; import { UpdateCompose } from "@/components/dashboard/compose/update-compose"; +import { AddDatabase } from "@/components/dashboard/project/add-database"; import { ProjectLayout } from "@/components/layouts/project-layout"; import { StatusTooltip } from "@/components/shared/status-tooltip"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, } from "@/components/ui/breadcrumb"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Label } from "@/components/ui/label"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { @@ -29,8 +39,13 @@ import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; -import { CircuitBoard, ServerOff } from "lucide-react"; -import { HelpCircle } from "lucide-react"; +import { + CircuitBoard, + Database, + HelpCircle, + ServerOff, + Settings, +} from "lucide-react"; import type { GetServerSidePropsContext, InferGetServerSidePropsType, @@ -38,7 +53,7 @@ import type { import Head from "next/head"; import Link from "next/link"; import { useRouter } from "next/router"; -import React, { useState, useEffect, type ReactElement } from "react"; +import { type ReactElement, useEffect, useState } from "react"; import superjson from "superjson"; type TabState = @@ -56,6 +71,7 @@ const Service = ( const router = useRouter(); const { projectId } = router.query; const [tab, setTab] = useState(activeTab); + const databaseKeywords = ["mysql", "mariadb", "postgres", "mongodb", "redis"]; useEffect(() => { if (router.query.tab) { @@ -70,6 +86,10 @@ const Service = ( }, ); + const hasDatabaseService = databaseKeywords.some((db) => + data?.composeFile.toLowerCase().includes(db), + ); + const { data: auth } = api.auth.get.useQuery(); const { data: user } = api.user.byAuthId.useQuery( { @@ -102,6 +122,18 @@ const Service = ( {data?.name} + {hasDatabaseService && ( + + + Heads up! + + It looks like this compose file contains a database service. If + you want to use features like data persistence, backups, and + security, we recommend you to create a dedicated database service. + + + )} + Compose: {data?.name} - {data?.project.name} | Dokploy @@ -218,12 +250,35 @@ const Service = ( <TabsTrigger value="domains">Domains</TabsTrigger> <TabsTrigger value="advanced">Advanced</TabsTrigger> </TabsList> - <div className="flex flex-row gap-2"> - <UpdateCompose composeId={composeId} /> - - {(auth?.rol === "admin" || user?.canDeleteServices) && ( - <DeleteCompose composeId={composeId} /> - )} + <div className="flex flex-row gap-4 flex-wrap"> + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button> + <Settings className="h-4 w-4" /> + Edit + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent + className="w-[200px] space-y-2" + align="end" + > + <DropdownMenuLabel className="text-sm font-normal "> + Actions + </DropdownMenuLabel> + <DropdownMenuSeparator /> + <UpdateCompose composeId={composeId} /> + {(auth?.rol === "admin" || user?.canDeleteServices) && ( + <DeleteCompose composeId={composeId} /> + )} + {hasDatabaseService && ( + <AddDatabase + projectId={data!.projectId} + projectName={data!.project.name} + dropdownItemName="Add Database" + /> + )} + </DropdownMenuContent> + </DropdownMenu> </div> </div>