From f0278f354b7346f84e79d9573a909063531a8cc1 Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Mon, 11 Aug 2025 09:56:49 +0300 Subject: [PATCH 01/36] Added support for Basic Auth present in the GitLab URLs --- .../pages/api/providers/gitlab/callback.ts | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/dokploy/pages/api/providers/gitlab/callback.ts b/apps/dokploy/pages/api/providers/gitlab/callback.ts index e32e0a7ad..cb51da9d2 100644 --- a/apps/dokploy/pages/api/providers/gitlab/callback.ts +++ b/apps/dokploy/pages/api/providers/gitlab/callback.ts @@ -12,12 +12,29 @@ export default async function handler( } const gitlab = await findGitlabById(gitlabId as string); + const gitlabUrl = new URL(gitlab.gitlabUrl) - const response = await fetch(`${gitlab.gitlabUrl}/oauth/token`, { + const headers: HeadersInit = { + "Content-Type": "application/x-www-form-urlencoded" + } + + // In case of basic auth being present in the URL, we need to remove it from the URL + // and add it to the Authorization header. + if (gitlabUrl.username && gitlabUrl.password) { + headers.Authorization = `Basic ${Buffer.from(`${gitlabUrl.username}:${gitlabUrl.password}`).toString("base64")}`; + } + + const url = (gitlabUrl.username && gitlabUrl.password) + ? new URL(gitlabUrl, { + ...gitlabUrl, + username: "", + password: "", + }).toString() + : gitlabUrl.toString(); + + const response = await fetch(`${url}/oauth/token`, { method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, + headers, body: new URLSearchParams({ client_id: gitlab.applicationId as string, client_secret: gitlab.secret as string, From a4bbcea28210ae7b27b90848a583593542ad11f4 Mon Sep 17 00:00:00 2001 From: Bob Mannino Date: Mon, 11 Aug 2025 18:25:38 +0100 Subject: [PATCH 02/36] add keyboard shortcuts for compose/redis/postgres pages --- apps/dokploy/hooks/use-keyboard-nav.tsx | 67 +++++++++++++++---- .../services/application/[applicationId].tsx | 4 +- .../services/compose/[composeId].tsx | 2 + .../services/postgres/[postgresId].tsx | 2 + .../[projectId]/services/redis/[redisId].tsx | 2 + 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index d24064c31..3d4d052c6 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -3,7 +3,26 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; -const SHORTCUTS = { +const PAGES = ["compose", "application", "postgres", "redis"] as const; +type Page = typeof PAGES[number]; + +type Shortcuts = Record; +type ShortcutsDictionary = Record; + +const COMPOSE_SHORTCUTS: Shortcuts = { + g: "general", + e: "environment", + u: "domains", + d: "deployments", + b: "backups", + s: "schedules", + v: "volumeBackups", + l: "logs", + m: "monitoring", + a: "advanced", +}; + +const APPLICATION_SHORTCUTS: Shortcuts = { g: "general", e: "environment", u: "domains", @@ -16,22 +35,40 @@ const SHORTCUTS = { a: "advanced", }; +const POSTGRES_SHORTCUTS: Shortcuts = { + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + b: "backups", + a: "advanced", +}; + +const REDIS_SHORTCUTS: Shortcuts = { + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + a: "advanced", +}; + +const SHORTCUTS: ShortcutsDictionary = { + application: APPLICATION_SHORTCUTS, + compose: COMPOSE_SHORTCUTS, + postgres: POSTGRES_SHORTCUTS, + redis: REDIS_SHORTCUTS, +}; + /** - * Use this to register keyboard shortcuts for the application page. Each - * shortcut must be prefixed with `g` (like GitHub). + * Use this to register keyboard shortcuts for different pages. Each shortcut + * must be prefixed with `g` (like GitHub). * + * @example * - `g g` "General", * - `g e` "Environment", * - `g u` "Domains", - * - `g p` "Preview Deployments", - * - `g s` "Schedules", - * - `g v` "Volume Backups", - * - `g d` "Deployments", - * - `g l` "Logs", - * - `g m` "Monitoring", - * - `g a` "Advanced" */ -export function UseKeyboardNavForApplications() { +export function UseKeyboardNav({ forPage }: { forPage: Page }) { const [isModPressed, setModPressed] = useState(false); const [timer, setTimer] = useState(null); @@ -39,6 +76,8 @@ export function UseKeyboardNavForApplications() { const router = useRouter(); const pathname = usePathname(); + const shortcuts = SHORTCUTS[forPage]; + const updateSearchParam = useCallback( (name: string, value: string) => { const params = new URLSearchParams(sp.toString()); @@ -55,10 +94,10 @@ export function UseKeyboardNavForApplications() { if (timer) clearTimeout(timer); setModPressed(false); - if (key in SHORTCUTS) { - const tab = SHORTCUTS[key as keyof typeof SHORTCUTS]; + if (key in shortcuts) { + const tab = shortcuts[key]!; router.push( - `${pathname}?${updateSearchParam("tab", tab.toLowerCase())}`, + `${pathname}?${updateSearchParam("tab", tab)}`, ); } } else { diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx index 104b1ff7b..305a931ce 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx @@ -51,7 +51,7 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; -import { UseKeyboardNavForApplications } from "@/hooks/use-keyboard-nav"; +import { UseKeyboardNav } from "@/hooks/use-keyboard-nav"; import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; @@ -92,7 +92,7 @@ const Service = ( return (
- + + + + Date: Mon, 11 Aug 2025 19:15:54 +0100 Subject: [PATCH 03/36] format --- apps/dokploy/hooks/use-keyboard-nav.tsx | 148 ++++++++++++------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index 3d4d052c6..3a99dbc61 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -10,46 +10,46 @@ type Shortcuts = Record; type ShortcutsDictionary = Record; const COMPOSE_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - u: "domains", - d: "deployments", - b: "backups", - s: "schedules", - v: "volumeBackups", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + u: "domains", + d: "deployments", + b: "backups", + s: "schedules", + v: "volumeBackups", + l: "logs", + m: "monitoring", + a: "advanced", }; const APPLICATION_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - u: "domains", - p: "preview-deployments", - s: "schedules", - v: "volume-backups", - d: "deployments", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + u: "domains", + p: "preview-deployments", + s: "schedules", + v: "volume-backups", + d: "deployments", + l: "logs", + m: "monitoring", + a: "advanced", }; const POSTGRES_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - l: "logs", - m: "monitoring", - b: "backups", - a: "advanced", + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + b: "backups", + a: "advanced", }; const REDIS_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + a: "advanced", }; const SHORTCUTS: ShortcutsDictionary = { @@ -60,57 +60,57 @@ const SHORTCUTS: ShortcutsDictionary = { }; /** - * Use this to register keyboard shortcuts for different pages. Each shortcut - * must be prefixed with `g` (like GitHub). - * - * @example - * - `g g` "General", - * - `g e` "Environment", - * - `g u` "Domains", - */ +* Use this to register keyboard shortcuts for different pages. Each shortcut +* must be prefixed with `g` (like GitHub). +* +* @example +* - `g g` "General", +* - `g e` "Environment", +* - `g u` "Domains", +*/ export function UseKeyboardNav({ forPage }: { forPage: Page }) { - const [isModPressed, setModPressed] = useState(false); - const [timer, setTimer] = useState(null); + const [isModPressed, setModPressed] = useState(false); + const [timer, setTimer] = useState(null); - const sp = useSearchParams(); - const router = useRouter(); - const pathname = usePathname(); + const sp = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); const shortcuts = SHORTCUTS[forPage]; - const updateSearchParam = useCallback( - (name: string, value: string) => { - const params = new URLSearchParams(sp.toString()); - params.set(name, value); + const updateSearchParam = useCallback( + (name: string, value: string) => { + const params = new URLSearchParams(sp.toString()); + params.set(name, value); - return params.toString(); - }, - [sp], - ); + return params.toString(); + }, + [sp], + ); - useEffect(() => { - const handleKeyDown = ({ key }: KeyboardEvent) => { - if (isModPressed) { - if (timer) clearTimeout(timer); - setModPressed(false); + useEffect(() => { + const handleKeyDown = ({ key }: KeyboardEvent) => { + if (isModPressed) { + if (timer) clearTimeout(timer); + setModPressed(false); - if (key in shortcuts) { - const tab = shortcuts[key]!; - router.push( - `${pathname}?${updateSearchParam("tab", tab)}`, - ); - } - } else { - if (key === "g") { - setModPressed(true); - setTimer(setTimeout(() => setModPressed(false), 5000)); - } - } - }; + if (key in shortcuts) { + const tab = shortcuts[key]!; + router.push( + `${pathname}?${updateSearchParam("tab", tab)}`, + ); + } + } else { + if (key === "g") { + setModPressed(true); + setTimer(setTimeout(() => setModPressed(false), 5000)); + } + } + }; - window.addEventListener("keydown", handleKeyDown); - return () => window.removeEventListener("keydown", handleKeyDown); - }, [isModPressed, timer, updateSearchParam, router, pathname]); + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [isModPressed, timer, updateSearchParam, router, pathname]); - return null; + return null; } From 957d1b5966ba709600057253259b7af62ef6246d Mon Sep 17 00:00:00 2001 From: Bob Mannino Date: Mon, 11 Aug 2025 19:28:29 +0100 Subject: [PATCH 04/36] add mysql keyboard shortcuts --- apps/dokploy/hooks/use-keyboard-nav.tsx | 3 ++- .../dashboard/project/[projectId]/services/mysql/[mysqlId].tsx | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index 3a99dbc61..7aa9adf6c 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -3,7 +3,7 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; -const PAGES = ["compose", "application", "postgres", "redis"] as const; +const PAGES = ["compose", "application", "postgres", "redis", "mysql"] as const; type Page = typeof PAGES[number]; type Shortcuts = Record; @@ -57,6 +57,7 @@ const SHORTCUTS: ShortcutsDictionary = { compose: COMPOSE_SHORTCUTS, postgres: POSTGRES_SHORTCUTS, redis: REDIS_SHORTCUTS, + mysql: POSTGRES_SHORTCUTS, }; /** diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx index 11efc6528..d9fbe07e8 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mysql/[mysqlId].tsx @@ -29,6 +29,7 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; +import { UseKeyboardNav } from "@/hooks/use-keyboard-nav"; import { cn } from "@/lib/utils"; import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; @@ -62,6 +63,7 @@ const MySql = ( return (
+ Date: Mon, 11 Aug 2025 18:28:50 +0000 Subject: [PATCH 05/36] [autofix.ci] apply automated fixes --- apps/dokploy/hooks/use-keyboard-nav.tsx | 160 +++++++++--------- .../services/application/[applicationId].tsx | 2 +- .../services/compose/[composeId].tsx | 2 +- .../[projectId]/services/mysql/[mysqlId].tsx | 2 +- .../services/postgres/[postgresId].tsx | 2 +- .../[projectId]/services/redis/[redisId].tsx | 2 +- 6 files changed, 84 insertions(+), 86 deletions(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index 7aa9adf6c..be9e206a9 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -4,114 +4,112 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; const PAGES = ["compose", "application", "postgres", "redis", "mysql"] as const; -type Page = typeof PAGES[number]; +type Page = (typeof PAGES)[number]; type Shortcuts = Record; type ShortcutsDictionary = Record; const COMPOSE_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - u: "domains", - d: "deployments", - b: "backups", - s: "schedules", - v: "volumeBackups", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + u: "domains", + d: "deployments", + b: "backups", + s: "schedules", + v: "volumeBackups", + l: "logs", + m: "monitoring", + a: "advanced", }; const APPLICATION_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - u: "domains", - p: "preview-deployments", - s: "schedules", - v: "volume-backups", - d: "deployments", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + u: "domains", + p: "preview-deployments", + s: "schedules", + v: "volume-backups", + d: "deployments", + l: "logs", + m: "monitoring", + a: "advanced", }; const POSTGRES_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - l: "logs", - m: "monitoring", - b: "backups", - a: "advanced", + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + b: "backups", + a: "advanced", }; const REDIS_SHORTCUTS: Shortcuts = { - g: "general", - e: "environment", - l: "logs", - m: "monitoring", - a: "advanced", + g: "general", + e: "environment", + l: "logs", + m: "monitoring", + a: "advanced", }; const SHORTCUTS: ShortcutsDictionary = { - application: APPLICATION_SHORTCUTS, - compose: COMPOSE_SHORTCUTS, - postgres: POSTGRES_SHORTCUTS, - redis: REDIS_SHORTCUTS, - mysql: POSTGRES_SHORTCUTS, + application: APPLICATION_SHORTCUTS, + compose: COMPOSE_SHORTCUTS, + postgres: POSTGRES_SHORTCUTS, + redis: REDIS_SHORTCUTS, + mysql: POSTGRES_SHORTCUTS, }; /** -* Use this to register keyboard shortcuts for different pages. Each shortcut -* must be prefixed with `g` (like GitHub). -* -* @example -* - `g g` "General", -* - `g e` "Environment", -* - `g u` "Domains", -*/ + * Use this to register keyboard shortcuts for different pages. Each shortcut + * must be prefixed with `g` (like GitHub). + * + * @example + * - `g g` "General", + * - `g e` "Environment", + * - `g u` "Domains", + */ export function UseKeyboardNav({ forPage }: { forPage: Page }) { - const [isModPressed, setModPressed] = useState(false); - const [timer, setTimer] = useState(null); + const [isModPressed, setModPressed] = useState(false); + const [timer, setTimer] = useState(null); - const sp = useSearchParams(); - const router = useRouter(); - const pathname = usePathname(); + const sp = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); - const shortcuts = SHORTCUTS[forPage]; + const shortcuts = SHORTCUTS[forPage]; - const updateSearchParam = useCallback( - (name: string, value: string) => { - const params = new URLSearchParams(sp.toString()); - params.set(name, value); + const updateSearchParam = useCallback( + (name: string, value: string) => { + const params = new URLSearchParams(sp.toString()); + params.set(name, value); - return params.toString(); - }, - [sp], - ); + return params.toString(); + }, + [sp], + ); - useEffect(() => { - const handleKeyDown = ({ key }: KeyboardEvent) => { - if (isModPressed) { - if (timer) clearTimeout(timer); - setModPressed(false); + useEffect(() => { + const handleKeyDown = ({ key }: KeyboardEvent) => { + if (isModPressed) { + if (timer) clearTimeout(timer); + setModPressed(false); - if (key in shortcuts) { - const tab = shortcuts[key]!; - router.push( - `${pathname}?${updateSearchParam("tab", tab)}`, - ); - } - } else { - if (key === "g") { - setModPressed(true); - setTimer(setTimeout(() => setModPressed(false), 5000)); - } - } - }; + if (key in shortcuts) { + const tab = shortcuts[key]!; + router.push(`${pathname}?${updateSearchParam("tab", tab)}`); + } + } else { + if (key === "g") { + setModPressed(true); + setTimer(setTimeout(() => setModPressed(false), 5000)); + } + } + }; - window.addEventListener("keydown", handleKeyDown); - return () => window.removeEventListener("keydown", handleKeyDown); - }, [isModPressed, timer, updateSearchParam, router, pathname]); + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [isModPressed, timer, updateSearchParam, router, pathname]); - return null; + return null; } diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx index 305a931ce..09766130d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx @@ -92,7 +92,7 @@ const Service = ( return (
- + - + - + - + - + Date: Mon, 11 Aug 2025 19:33:25 +0100 Subject: [PATCH 06/36] add mariadb/mongodb keyboard shortcuts --- apps/dokploy/hooks/use-keyboard-nav.tsx | 4 +++- .../project/[projectId]/services/mariadb/[mariadbId].tsx | 2 ++ .../project/[projectId]/services/mongo/[mongoId].tsx | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index be9e206a9..cc9a32496 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -3,7 +3,7 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; -const PAGES = ["compose", "application", "postgres", "redis", "mysql"] as const; +const PAGES = ["compose", "application", "postgres", "redis", "mysql", "mariadb", "mongodb"] as const; type Page = (typeof PAGES)[number]; type Shortcuts = Record; @@ -58,6 +58,8 @@ const SHORTCUTS: ShortcutsDictionary = { postgres: POSTGRES_SHORTCUTS, redis: REDIS_SHORTCUTS, mysql: POSTGRES_SHORTCUTS, + mariadb: POSTGRES_SHORTCUTS, + mongodb: POSTGRES_SHORTCUTS, }; /** diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx index d6745a241..a10bca422 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx @@ -29,6 +29,7 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; +import { UseKeyboardNav } from "@/hooks/use-keyboard-nav"; import { cn } from "@/lib/utils"; import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; @@ -63,6 +64,7 @@ const Mariadb = ( return (
+ + Date: Mon, 11 Aug 2025 18:33:47 +0000 Subject: [PATCH 07/36] [autofix.ci] apply automated fixes --- apps/dokploy/hooks/use-keyboard-nav.tsx | 10 +++++++++- .../[projectId]/services/mariadb/[mariadbId].tsx | 2 +- .../project/[projectId]/services/mongo/[mongoId].tsx | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index cc9a32496..d9dc75bd6 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -3,7 +3,15 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; -const PAGES = ["compose", "application", "postgres", "redis", "mysql", "mariadb", "mongodb"] as const; +const PAGES = [ + "compose", + "application", + "postgres", + "redis", + "mysql", + "mariadb", + "mongodb", +] as const; type Page = (typeof PAGES)[number]; type Shortcuts = Record; diff --git a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx index a10bca422..ba17aadac 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx @@ -64,7 +64,7 @@ const Mariadb = ( return (
- + - + Date: Tue, 12 Aug 2025 18:13:04 +0100 Subject: [PATCH 08/36] fix: do not navigate if typing in input/textarea/select fixes #2367 --- apps/dokploy/hooks/use-keyboard-nav.tsx | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index d9dc75bd6..768c47b67 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -100,7 +100,20 @@ export function UseKeyboardNav({ forPage }: { forPage: Page }) { ); useEffect(() => { - const handleKeyDown = ({ key }: KeyboardEvent) => { + const handleKeyDown = ({ key, target }: KeyboardEvent) => { + const active = target as HTMLElement | null; + + if (active) { + const tag = active.tagName; + if ( + active.isContentEditable || + tag === "INPUT" || + tag === "TEXTAREA" || + tag === "SELECT" || + active.getAttribute("role") === "textbox" + ) return; + } + if (isModPressed) { if (timer) clearTimeout(timer); setModPressed(false); @@ -109,11 +122,9 @@ export function UseKeyboardNav({ forPage }: { forPage: Page }) { const tab = shortcuts[key]!; router.push(`${pathname}?${updateSearchParam("tab", tab)}`); } - } else { - if (key === "g") { - setModPressed(true); - setTimer(setTimeout(() => setModPressed(false), 5000)); - } + } else if (key === "g") { + setModPressed(true); + setTimer(setTimeout(() => setModPressed(false), 5000)); } }; From a41137aaccb4c6d395a53e0b799ba349cc88fbe5 Mon Sep 17 00:00:00 2001 From: Bob Mannino Date: Tue, 12 Aug 2025 18:15:35 +0100 Subject: [PATCH 09/36] reduce time waiting for second nav key to 1.5s --- apps/dokploy/hooks/use-keyboard-nav.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index 768c47b67..1070dd702 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -124,7 +124,7 @@ export function UseKeyboardNav({ forPage }: { forPage: Page }) { } } else if (key === "g") { setModPressed(true); - setTimer(setTimeout(() => setModPressed(false), 5000)); + setTimer(setTimeout(() => setModPressed(false), 1500)); } }; From 83e8c82c4ac4d8367d9faa177bf1557e108a741b Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:16:10 +0000 Subject: [PATCH 10/36] [autofix.ci] apply automated fixes --- apps/dokploy/hooks/use-keyboard-nav.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/hooks/use-keyboard-nav.tsx b/apps/dokploy/hooks/use-keyboard-nav.tsx index 1070dd702..95f38d7e2 100644 --- a/apps/dokploy/hooks/use-keyboard-nav.tsx +++ b/apps/dokploy/hooks/use-keyboard-nav.tsx @@ -111,7 +111,8 @@ export function UseKeyboardNav({ forPage }: { forPage: Page }) { tag === "TEXTAREA" || tag === "SELECT" || active.getAttribute("role") === "textbox" - ) return; + ) + return; } if (isModPressed) { From 6248abd88e8cb5d60d643651b758874610472f57 Mon Sep 17 00:00:00 2001 From: Vyacheslav Scherbinin Date: Wed, 13 Aug 2025 10:05:16 +0700 Subject: [PATCH 11/36] fix(ui): pointer events transparent modal overlay --- apps/dokploy/components/ui/dialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/ui/dialog.tsx b/apps/dokploy/components/ui/dialog.tsx index f3b6fedbd..ae92d3797 100644 --- a/apps/dokploy/components/ui/dialog.tsx +++ b/apps/dokploy/components/ui/dialog.tsx @@ -37,7 +37,7 @@ const DialogOverlay = React.forwardRef< {/* Custom overlay for modal=false - no click handler to avoid Command conflicts */} -
+
Date: Wed, 13 Aug 2025 10:07:08 +0700 Subject: [PATCH 12/36] refactor: remove overflow hidden cause of useless --- apps/dokploy/components/ui/dialog.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/dokploy/components/ui/dialog.tsx b/apps/dokploy/components/ui/dialog.tsx index ae92d3797..9fef5b60f 100644 --- a/apps/dokploy/components/ui/dialog.tsx +++ b/apps/dokploy/components/ui/dialog.tsx @@ -61,7 +61,6 @@ const DialogContent = React.forwardRef< const originalPaddingRight = body.style.paddingRight; const originalOverflow = body.style.overflow; - body.style.overflow = "hidden"; if (scrollbarWidth > 0) { body.style.paddingRight = `${scrollbarWidth}px`; } From 6e069154ef4ecfd1ebe86f7bc2757ed8fe222604 Mon Sep 17 00:00:00 2001 From: Vyacheslav Scherbinin Date: Wed, 13 Aug 2025 12:51:44 +0700 Subject: [PATCH 13/36] fix(dialog-ux): prevent default Radix double event onInteractOutside --- apps/dokploy/components/ui/dialog.tsx | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/apps/dokploy/components/ui/dialog.tsx b/apps/dokploy/components/ui/dialog.tsx index 9fef5b60f..64e2717e9 100644 --- a/apps/dokploy/components/ui/dialog.tsx +++ b/apps/dokploy/components/ui/dialog.tsx @@ -73,8 +73,21 @@ const DialogContent = React.forwardRef< // Handle outside interactions properly with Command components const handleInteractOutside = React.useCallback( - (_e: Event) => { + (event: Event | React.MouseEvent) => { + // Don't close when clicking inside popovers, dropdowns, or command components + const target = event.target as HTMLElement; + if ( + target.closest("[data-radix-popper-content-wrapper]") || + target.closest("[cmdk-root]") || + target.closest("[data-radix-command-root]") + ) { + event.preventDefault(); + return; + } + if (onOpenChange) { + event.preventDefault(); + event.stopPropagation(); onOpenChange(false); } }, @@ -95,7 +108,10 @@ const DialogContent = React.forwardRef< return ( {/* Custom overlay for modal=false - no click handler to avoid Command conflicts */} -
+
{ - const target = e.target as HTMLElement; - // Don't close when clicking inside popovers, dropdowns, or command components - if ( - target.closest("[data-radix-popper-content-wrapper]") || - target.closest("[cmdk-root]") || - target.closest("[data-radix-command-root]") - ) { - e.preventDefault(); - return; - } - // Use our custom handler for modal=false behavior - handleInteractOutside(e); - }} + onInteractOutside={(event) => event.preventDefault()} {...props} >
Date: Wed, 13 Aug 2025 12:54:58 +0700 Subject: [PATCH 14/36] fix(dialog-ux): internal component state control --- apps/dokploy/components/ui/dialog.tsx | 32 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/apps/dokploy/components/ui/dialog.tsx b/apps/dokploy/components/ui/dialog.tsx index 64e2717e9..7be34e9b2 100644 --- a/apps/dokploy/components/ui/dialog.tsx +++ b/apps/dokploy/components/ui/dialog.tsx @@ -12,16 +12,28 @@ const Dialog = ({ onOpenChange, open, ...props -}: React.ComponentPropsWithoutRef) => ( - - - -); +}: React.ComponentPropsWithoutRef) => { + const [isOpened, setIsOpened] = React.useState(false); // for internal control + + const handleOpenChange = (open: boolean) => { + if (onOpenChange) { + onOpenChange(open); + } else { + setIsOpened(open); + } + }; + + return ( + + + + ); +}; Dialog.displayName = DialogPrimitive.Root.displayName; const DialogTrigger = DialogPrimitive.Trigger; From f3ec01ec771bc664e43ef9b68ee1d9ae03399309 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 06:46:05 +0000 Subject: [PATCH 15/36] [autofix.ci] apply automated fixes --- apps/dokploy/components/ui/dialog.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/dokploy/components/ui/dialog.tsx b/apps/dokploy/components/ui/dialog.tsx index 7be34e9b2..0d71d059c 100644 --- a/apps/dokploy/components/ui/dialog.tsx +++ b/apps/dokploy/components/ui/dialog.tsx @@ -24,7 +24,9 @@ const Dialog = ({ }; return ( - + Date: Fri, 15 Aug 2025 15:13:24 +0000 Subject: [PATCH 16/36] trim the ip address --- .../components/dashboard/settings/servers/handle-servers.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/components/dashboard/settings/servers/handle-servers.tsx b/apps/dokploy/components/dashboard/settings/servers/handle-servers.tsx index 1ff2f09dc..cdbe8a95b 100644 --- a/apps/dokploy/components/dashboard/settings/servers/handle-servers.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/handle-servers.tsx @@ -112,7 +112,7 @@ export const HandleServers = ({ serverId }: Props) => { await mutateAsync({ name: data.name, description: data.description || "", - ipAddress: data.ipAddress || "", + ipAddress: data.ipAddress?.trim() || "", port: data.port || 22, username: data.username || "root", sshKeyId: data.sshKeyId || "", From b6cbf9127d50f8305c96ac352377d2de241f20dd Mon Sep 17 00:00:00 2001 From: Haouari haitam Kouider <57036855+haouarihk@users.noreply.github.com> Date: Fri, 15 Aug 2025 15:14:26 +0000 Subject: [PATCH 17/36] trim ip address --- .../dashboard/settings/servers/welcome-stripe/create-server.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/create-server.tsx b/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/create-server.tsx index b895f385b..0141aca08 100644 --- a/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/create-server.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/welcome-stripe/create-server.tsx @@ -91,7 +91,7 @@ export const CreateServer = ({ stepper }: Props) => { await mutateAsync({ name: data.name, description: data.description || "", - ipAddress: data.ipAddress || "", + ipAddress: data.ipAddress?.trim() || "", port: data.port || 22, username: data.username || "root", sshKeyId: data.sshKeyId || "", From 4e7378371d067b9774967ce526511e80e516a9c0 Mon Sep 17 00:00:00 2001 From: Leonhard Breuer Date: Fri, 15 Aug 2025 19:52:55 +0200 Subject: [PATCH 18/36] fix(template): make every key in map unique using index FIXES #2382 --- apps/dokploy/components/dashboard/project/add-template.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/dashboard/project/add-template.tsx b/apps/dokploy/components/dashboard/project/add-template.tsx index 5eb994fc4..2bdd85a01 100644 --- a/apps/dokploy/components/dashboard/project/add-template.tsx +++ b/apps/dokploy/components/dashboard/project/add-template.tsx @@ -307,9 +307,9 @@ export const AddTemplate = ({ projectId, baseUrl }: Props) => { : "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6", )} > - {templates?.map((template) => ( + {templates?.map((template, idx) => (
Date: Sun, 17 Aug 2025 01:33:47 +0000 Subject: [PATCH 19/36] [autofix.ci] apply automated fixes --- .../pages/api/providers/gitlab/callback.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/dokploy/pages/api/providers/gitlab/callback.ts b/apps/dokploy/pages/api/providers/gitlab/callback.ts index cb51da9d2..008873511 100644 --- a/apps/dokploy/pages/api/providers/gitlab/callback.ts +++ b/apps/dokploy/pages/api/providers/gitlab/callback.ts @@ -12,11 +12,11 @@ export default async function handler( } const gitlab = await findGitlabById(gitlabId as string); - const gitlabUrl = new URL(gitlab.gitlabUrl) + const gitlabUrl = new URL(gitlab.gitlabUrl); const headers: HeadersInit = { - "Content-Type": "application/x-www-form-urlencoded" - } + "Content-Type": "application/x-www-form-urlencoded", + }; // In case of basic auth being present in the URL, we need to remove it from the URL // and add it to the Authorization header. @@ -24,13 +24,14 @@ export default async function handler( headers.Authorization = `Basic ${Buffer.from(`${gitlabUrl.username}:${gitlabUrl.password}`).toString("base64")}`; } - const url = (gitlabUrl.username && gitlabUrl.password) - ? new URL(gitlabUrl, { - ...gitlabUrl, - username: "", - password: "", - }).toString() - : gitlabUrl.toString(); + const url = + gitlabUrl.username && gitlabUrl.password + ? new URL(gitlabUrl, { + ...gitlabUrl, + username: "", + password: "", + }).toString() + : gitlabUrl.toString(); const response = await fetch(`${url}/oauth/token`, { method: "POST", From 0cdacb5501eeb2314ac05c80d86b0f8e3dc4da39 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 16 Aug 2025 19:50:15 -0600 Subject: [PATCH 20/36] update(package): bump version to v0.24.11 --- apps/dokploy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index 2758bbced..2308efce3 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.24.10", + "version": "v0.24.11", "private": true, "license": "Apache-2.0", "type": "module", From 774365c68edefdc1a3a0cb46b783378b9ccdc428 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 16 Aug 2025 20:18:08 -0600 Subject: [PATCH 21/36] Refactor and update various components in the Dokploy application, enhancing functionality and fixing minor issues across multiple pages and features, including dashboard, settings, and API integrations. --- .../advanced/general/add-command.tsx | 11 +- .../advanced/import/show-import.tsx | 12 +- .../application/advanced/ports/show-port.tsx | 5 +- .../advanced/redirects/handle-redirect.tsx | 12 +- .../advanced/redirects/show-redirects.tsx | 4 +- .../advanced/security/handle-security.tsx | 12 +- .../advanced/security/show-security.tsx | 8 +- .../application/advanced/show-resources.tsx | 12 +- .../advanced/traefik/show-traefik-config.tsx | 3 +- .../traefik/update-traefik-config.tsx | 12 +- .../advanced/volumes/add-volumes.tsx | 15 +- .../advanced/volumes/update-volume.tsx | 12 +- .../application/deployments/cancel-queues.tsx | 4 +- .../application/deployments/refresh-token.tsx | 4 +- .../deployments/show-deployment.tsx | 4 +- .../deployments/show-deployments-modal.tsx | 3 +- .../deployments/show-deployments.tsx | 8 +- .../application/domains/dns-helper-modal.tsx | 4 +- .../application/domains/show-domains.tsx | 30 ++-- .../environment/show-enviroment.tsx | 12 +- .../application/environment/show.tsx | 10 +- .../generic/save-bitbucket-provider.tsx | 14 +- .../general/generic/save-docker-provider.tsx | 10 +- .../general/generic/save-drag-n-drop.tsx | 10 +- .../general/generic/save-git-provider.tsx | 21 ++- .../general/generic/save-gitea-provider.tsx | 14 +- .../general/generic/save-github-provider.tsx | 14 +- .../general/generic/save-gitlab-provider.tsx | 14 +- .../application/general/generic/show.tsx | 10 +- .../generic/unauthorized-git-provider.tsx | 4 +- .../dashboard/application/general/show.tsx | 23 +-- .../dashboard/application/logs/show.tsx | 6 +- .../add-preview-domain.tsx | 15 +- .../show-preview-deployments.tsx | 20 +-- .../show-preview-settings.tsx | 12 +- .../rollbacks/show-rollback-settings.tsx | 10 +- .../schedules/handle-schedules.tsx | 24 +-- .../application/schedules/show-schedules.tsx | 18 +-- .../application/update-application.tsx | 12 +- .../volume-backups/handle-volume-backups.tsx | 24 +-- .../volume-backups/restore-volume-backups.tsx | 16 +- .../volume-backups/show-volume-backups.tsx | 16 +- .../compose/advanced/add-command.tsx | 11 +- .../dashboard/compose/delete-service.tsx | 18 +-- .../dashboard/compose/general/actions.tsx | 8 +- .../compose/general/compose-file-editor.tsx | 2 +- .../save-bitbucket-provider-compose.tsx | 14 +- .../generic/save-git-provider-compose.tsx | 16 +- .../generic/save-gitea-provider-compose.tsx | 14 +- .../generic/save-github-provider-compose.tsx | 14 +- .../generic/save-gitlab-provider-compose.tsx | 14 +- .../compose/general/generic/show.tsx | 10 +- .../compose/general/randomize-compose.tsx | 12 +- .../dashboard/compose/general/show.tsx | 1 + .../dashboard/compose/logs/show-stack.tsx | 6 +- .../dashboard/compose/logs/show.tsx | 6 +- .../dashboard/compose/update-compose.tsx | 12 +- .../database/backups/handle-backup.tsx | 27 ++-- .../database/backups/restore-backup.tsx | 30 ++-- .../database/backups/show-backups.tsx | 20 +-- .../docker/logs/line-count-filter.tsx | 8 +- .../docker/logs/show-docker-modal-logs.tsx | 4 +- .../logs/show-docker-modal-stack-logs.tsx | 4 +- .../docker/logs/since-logs-filter.tsx | 2 +- .../docker/logs/status-logs-filter.tsx | 4 +- .../dashboard/docker/logs/terminal-line.tsx | 6 +- .../dashboard/docker/show/colums.tsx | 4 +- .../dashboard/docker/show/show-containers.tsx | 28 ++-- .../docker/terminal/docker-terminal-modal.tsx | 4 +- .../docker/terminal/docker-terminal.tsx | 2 +- .../file-system/show-traefik-file.tsx | 15 +- .../file-system/show-traefik-system.tsx | 4 +- .../impersonation/impersonation-bar.tsx | 38 ++--- .../show-external-mariadb-credentials.tsx | 12 +- .../mariadb/general/show-general-mariadb.tsx | 8 +- .../dashboard/mariadb/update-mariadb.tsx | 12 +- .../show-external-mongo-credentials.tsx | 12 +- .../mongo/general/show-general-mongo.tsx | 9 +- .../dashboard/mongo/update-mongo.tsx | 12 +- .../free/container/docker-memory-chart.tsx | 1 + .../free/container/docker-network-chart.tsx | 1 + .../show-free-compose-monitoring.tsx | 6 +- .../show-free-container-monitoring.tsx | 2 +- .../paid/container/container-block-chart.tsx | 2 +- .../paid/container/container-cpu-chart.tsx | 2 +- .../paid/container/container-memory-chart.tsx | 2 +- .../container/container-network-chart.tsx | 2 +- .../show-paid-compose-monitoring.tsx | 6 +- .../show-paid-container-monitoring.tsx | 4 +- .../monitoring/paid/servers/cpu-chart.tsx | 2 +- .../monitoring/paid/servers/memory-chart.tsx | 2 +- .../monitoring/paid/servers/network-chart.tsx | 2 +- .../paid/servers/show-paid-monitoring.tsx | 4 +- .../show-external-mysql-credentials.tsx | 12 +- .../mysql/general/show-general-mysql.tsx | 9 +- .../dashboard/mysql/update-mysql.tsx | 12 +- .../organization/handle-organization.tsx | 12 +- .../postgres/advanced/show-custom-command.tsx | 10 +- .../show-external-postgres-credentials.tsx | 12 +- .../general/show-general-postgres.tsx | 8 +- .../dashboard/postgres/update-postgres.tsx | 12 +- .../dashboard/project/add-template.tsx | 2 +- .../dashboard/project/ai/step-three.tsx | 2 +- .../dashboard/project/ai/step-two.tsx | 8 +- .../project/ai/template-generator.tsx | 10 +- .../dashboard/project/duplicate-project.tsx | 8 +- .../dashboard/projects/handle-project.tsx | 15 +- .../projects/project-environment.tsx | 12 +- .../show-external-redis-credentials.tsx | 12 +- .../redis/general/show-general-redis.tsx | 8 +- .../dashboard/redis/update-redis.tsx | 12 +- .../components/dashboard/requests/columns.tsx | 4 +- .../requests/request-distribution-chart.tsx | 14 +- .../dashboard/requests/requests-table.tsx | 48 +++--- .../dashboard/requests/show-requests.tsx | 22 +-- .../requests/status-request-filter.tsx | 2 +- .../components/dashboard/search-command.tsx | 8 +- .../components/dashboard/settings/ai-form.tsx | 4 +- .../dashboard/settings/api/add-api-key.tsx | 12 +- .../dashboard/settings/api/show-api-keys.tsx | 8 +- .../settings/billing/show-billing.tsx | 24 +-- .../settings/billing/show-welcome-dokploy.tsx | 2 +- .../settings/certificates/add-certificate.tsx | 12 +- .../certificates/show-certificates.tsx | 4 +- .../settings/cluster/nodes/add-node.tsx | 4 +- .../cluster/nodes/manager/add-manager.tsx | 6 +- .../cluster/nodes/show-nodes-modal.tsx | 2 +- .../settings/cluster/nodes/show-nodes.tsx | 16 +- .../cluster/nodes/workers/add-worker.tsx | 6 +- .../cluster/registry/handle-registry.tsx | 12 +- .../cluster/registry/show-registry.tsx | 4 +- .../destination/handle-destinations.tsx | 12 +- .../destination/show-destinations.tsx | 4 +- .../git/bitbucket/add-bitbucket-provider.tsx | 16 +- .../git/bitbucket/edit-bitbucket-provider.tsx | 12 +- .../settings/git/gitea/add-gitea-provider.tsx | 14 +- .../git/gitea/edit-gitea-provider.tsx | 14 +- .../git/github/add-github-provider.tsx | 4 +- .../git/github/edit-github-provider.tsx | 12 +- .../git/gitlab/add-gitlab-provider.tsx | 15 +- .../git/gitlab/edit-gitlab-provider.tsx | 12 +- .../settings/git/show-git-providers.tsx | 36 ++--- .../dashboard/settings/handle-ai.tsx | 12 +- .../notifications/handle-notifications.tsx | 24 +-- .../notifications/show-notifications.tsx | 4 +- .../settings/profile/disable-2fa.tsx | 10 +- .../dashboard/settings/profile/enable-2fa.tsx | 14 +- .../settings/profile/profile-form.tsx | 16 +- .../servers/actions/show-dokploy-actions.tsx | 7 +- .../servers/actions/show-server-actions.tsx | 3 +- .../servers/actions/show-storage-actions.tsx | 5 +- .../servers/actions/toggle-docker-cleanup.tsx | 2 +- .../settings/servers/edit-script.tsx | 12 +- .../settings/servers/gpu-support-modal.tsx | 2 +- .../settings/servers/gpu-support.tsx | 6 +- .../settings/servers/security-audit.tsx | 4 +- .../settings/servers/setup-monitoring.tsx | 12 +- .../settings/servers/setup-server.tsx | 10 +- .../servers/show-docker-containers-modal.tsx | 2 +- .../servers/show-monitoring-modal.tsx | 2 +- .../settings/servers/show-schedules-modal.tsx | 2 +- .../servers/show-swarm-overview-modal.tsx | 2 +- .../show-traefik-file-system-modal.tsx | 2 +- .../settings/servers/validate-server.tsx | 4 +- .../settings/servers/welcome-stripe/setup.tsx | 2 +- .../servers/welcome-stripe/verify.tsx | 9 +- .../welcome-stripe/welcome-suscription.tsx | 23 ++- .../settings/ssh-keys/handle-ssh-keys.tsx | 12 +- .../settings/ssh-keys/show-ssh-keys.tsx | 6 +- .../settings/users/add-invitation.tsx | 12 +- .../settings/users/add-permissions.tsx | 10 +- .../settings/users/show-invitations.tsx | 9 +- .../dashboard/settings/users/show-users.tsx | 7 +- .../dashboard/settings/web-domain.tsx | 14 +- .../dashboard/settings/web-server.tsx | 4 +- .../web-server/docker-terminal-modal.tsx | 8 +- .../settings/web-server/edit-traefik-env.tsx | 10 +- .../web-server/local-server-config.tsx | 10 +- .../settings/web-server/show-modal-logs.tsx | 8 +- .../settings/web-server/terminal-modal.tsx | 6 +- .../web-server/toggle-auto-check-updates.tsx | 2 +- .../settings/web-server/update-server-ip.tsx | 12 +- .../settings/web-server/update-server.tsx | 26 +-- .../settings/web-server/update-webserver.tsx | 6 +- .../dashboard/shared/rebuild-database.tsx | 4 +- .../dashboard/swarm/applications/columns.tsx | 4 +- .../swarm/applications/data-table.tsx | 11 +- .../dashboard/swarm/details/details-card.tsx | 2 +- .../swarm/details/show-node-config.tsx | 2 +- .../dashboard/swarm/monitoring-card.tsx | 16 +- apps/dokploy/components/ui/alert.tsx | 2 +- apps/dokploy/components/ui/badge.tsx | 2 +- apps/dokploy/components/ui/button.tsx | 7 +- apps/dokploy/components/ui/dialog.tsx | 2 +- apps/dokploy/components/ui/dropzone.tsx | 4 +- apps/dokploy/components/ui/file-tree.tsx | 2 +- apps/dokploy/components/ui/input.tsx | 2 +- apps/dokploy/components/ui/label.tsx | 2 +- apps/dokploy/components/ui/modeToggle.tsx | 2 +- apps/dokploy/components/ui/secrets.tsx | 6 +- apps/dokploy/components/ui/sheet.tsx | 2 +- apps/dokploy/components/ui/sidebar.tsx | 2 +- apps/dokploy/components/ui/toggle.tsx | 2 +- apps/dokploy/esbuild.config.ts | 3 +- apps/dokploy/lib/auth-client.ts | 10 +- apps/dokploy/pages/_app.tsx | 12 +- apps/dokploy/pages/_error.tsx | 4 +- .../accept-invitation/[accept-invitation].tsx | 2 +- apps/dokploy/pages/api/[...trpc].ts | 4 +- .../pages/api/deploy/[refreshToken].ts | 6 +- .../api/deploy/compose/[refreshToken].ts | 8 +- apps/dokploy/pages/api/deploy/github.ts | 12 +- .../pages/api/providers/gitea/callback.ts | 2 +- .../pages/api/providers/github/setup.ts | 4 +- apps/dokploy/pages/api/stripe/webhook.ts | 6 +- apps/dokploy/pages/api/trpc/[trpc].ts | 4 +- apps/dokploy/pages/dashboard/docker.tsx | 6 +- apps/dokploy/pages/dashboard/monitoring.tsx | 10 +- .../pages/dashboard/project/[projectId].tsx | 59 ++++--- .../services/mariadb/[mariadbId].tsx | 24 +-- .../[projectId]/services/mongo/[mongoId].tsx | 24 +-- .../[projectId]/services/mysql/[mysqlId].tsx | 24 +-- .../services/postgres/[postgresId].tsx | 24 +-- .../[projectId]/services/redis/[redisId].tsx | 24 +-- apps/dokploy/pages/dashboard/projects.tsx | 8 +- apps/dokploy/pages/dashboard/requests.tsx | 4 +- apps/dokploy/pages/dashboard/schedules.tsx | 9 +- apps/dokploy/pages/dashboard/settings/ai.tsx | 8 +- .../pages/dashboard/settings/billing.tsx | 7 +- .../pages/dashboard/settings/certificates.tsx | 8 +- .../pages/dashboard/settings/cluster.tsx | 7 +- .../pages/dashboard/settings/destinations.tsx | 7 +- .../dashboard/settings/git-providers.tsx | 7 +- .../dashboard/settings/notifications.tsx | 7 +- .../pages/dashboard/settings/profile.tsx | 13 +- .../pages/dashboard/settings/registry.tsx | 7 +- .../pages/dashboard/settings/server.tsx | 11 +- .../pages/dashboard/settings/servers.tsx | 9 +- .../pages/dashboard/settings/ssh-keys.tsx | 7 +- .../pages/dashboard/settings/users.tsx | 9 +- apps/dokploy/pages/dashboard/swarm.tsx | 6 +- apps/dokploy/pages/dashboard/traefik.tsx | 6 +- apps/dokploy/pages/index.tsx | 22 +-- apps/dokploy/pages/invitation.tsx | 18 +-- apps/dokploy/pages/register.tsx | 20 +-- apps/dokploy/pages/reset-password.tsx | 18 +-- apps/dokploy/pages/send-reset-password.tsx | 18 +-- apps/dokploy/pages/swagger.tsx | 4 +- apps/dokploy/reset-password.ts | 3 +- apps/dokploy/server/api/routers/admin.ts | 4 +- apps/dokploy/server/api/routers/ai.ts | 16 +- apps/dokploy/server/api/routers/backup.ts | 21 ++- apps/dokploy/server/api/routers/bitbucket.ts | 18 +-- .../dokploy/server/api/routers/certificate.ts | 19 ++- apps/dokploy/server/api/routers/cluster.ts | 2 +- apps/dokploy/server/api/routers/compose.ts | 32 ++-- apps/dokploy/server/api/routers/deployment.ts | 16 +- .../dokploy/server/api/routers/destination.ts | 22 +-- apps/dokploy/server/api/routers/domain.ts | 16 +- .../server/api/routers/git-provider.ts | 6 +- apps/dokploy/server/api/routers/gitea.ts | 22 ++- apps/dokploy/server/api/routers/github.ts | 14 +- apps/dokploy/server/api/routers/gitlab.ts | 21 ++- apps/dokploy/server/api/routers/mariadb.ts | 46 +++--- apps/dokploy/server/api/routers/mongo.ts | 46 +++--- apps/dokploy/server/api/routers/mount.ts | 12 +- apps/dokploy/server/api/routers/mysql.ts | 50 +++--- .../server/api/routers/notification.ts | 48 +++--- .../server/api/routers/organization.ts | 4 +- apps/dokploy/server/api/routers/port.ts | 12 +- apps/dokploy/server/api/routers/postgres.ts | 46 +++--- .../server/api/routers/preview-deployment.ts | 2 +- apps/dokploy/server/api/routers/project.ts | 37 +++-- apps/dokploy/server/api/routers/redirects.ts | 10 +- apps/dokploy/server/api/routers/redis.ts | 49 +++--- apps/dokploy/server/api/routers/registry.ts | 22 +-- apps/dokploy/server/api/routers/rollbacks.ts | 4 +- apps/dokploy/server/api/routers/schedule.ts | 5 +- apps/dokploy/server/api/routers/security.ts | 10 +- apps/dokploy/server/api/routers/server.ts | 42 ++--- apps/dokploy/server/api/routers/ssh-key.ts | 18 +-- apps/dokploy/server/api/routers/stripe.ts | 4 +- apps/dokploy/server/api/routers/user.ts | 4 +- .../server/api/routers/volume-backups.ts | 4 +- apps/dokploy/server/api/trpc.ts | 7 +- apps/dokploy/server/db/index.ts | 2 +- apps/dokploy/server/server.ts | 6 +- apps/dokploy/server/wss/terminal.ts | 2 +- apps/dokploy/utils/api.ts | 3 +- apps/dokploy/utils/hooks/use-locale.ts | 2 +- apps/dokploy/utils/i18n.ts | 2 +- biome.json | 9 +- packages/server/esbuild.config.ts | 1 + packages/server/src/db/index.ts | 3 +- packages/server/src/db/schema/compose.ts | 3 +- packages/server/src/db/schema/index.ts | 56 +++---- packages/server/src/index.ts | 151 ++++++++---------- packages/server/src/services/deployment.ts | 9 +- packages/server/src/services/gitea.ts | 2 +- packages/server/src/services/github.ts | 2 +- packages/server/src/services/gitlab.ts | 2 +- packages/server/src/services/mariadb.ts | 5 +- packages/server/src/services/mongo.ts | 5 +- packages/server/src/services/mysql.ts | 11 +- packages/server/src/services/postgres.ts | 5 +- packages/server/src/services/redis.ts | 10 +- packages/server/src/services/schedule.ts | 2 +- packages/server/src/types/with.ts | 1 + .../server/src/utils/access-log/handler.ts | 2 +- packages/server/src/utils/backups/utils.ts | 2 +- .../server/src/utils/builders/docker-file.ts | 2 +- packages/server/src/utils/builders/heroku.ts | 2 +- .../server/src/utils/builders/nixpacks.ts | 4 +- packages/server/src/utils/builders/paketo.ts | 2 +- packages/server/src/utils/builders/static.ts | 2 +- .../server/src/utils/databases/rebuild.ts | 3 +- .../src/utils/docker/compose/service.ts | 1 + packages/server/src/utils/gpu-setup.ts | 5 +- packages/server/src/utils/providers/git.ts | 6 +- packages/server/src/utils/providers/github.ts | 9 +- packages/server/src/utils/restore/index.ts | 6 +- packages/server/src/utils/schedules/utils.ts | 4 +- .../server/src/utils/traefik/application.ts | 3 +- .../server/src/utils/volume-backups/index.ts | 1 + .../server/src/utils/volume-backups/utils.ts | 2 +- 325 files changed, 1743 insertions(+), 1768 deletions(-) diff --git a/apps/dokploy/components/dashboard/application/advanced/general/add-command.tsx b/apps/dokploy/components/dashboard/application/advanced/general/add-command.tsx index 50e36ad76..1bf69394a 100644 --- a/apps/dokploy/components/dashboard/application/advanced/general/add-command.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/general/add-command.tsx @@ -1,3 +1,8 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { Button } from "@/components/ui/button"; import { Card, @@ -16,11 +21,7 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; + interface Props { applicationId: string; } diff --git a/apps/dokploy/components/dashboard/application/advanced/import/show-import.tsx b/apps/dokploy/components/dashboard/application/advanced/import/show-import.tsx index 29033f6b6..17d033cf2 100644 --- a/apps/dokploy/components/dashboard/application/advanced/import/show-import.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/import/show-import.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { Code2, Globe2, HardDrive } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; @@ -27,12 +33,6 @@ import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import { Textarea } from "@/components/ui/textarea"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { Code2, Globe2, HardDrive } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const ImportSchema = z.object({ base64: z.string(), diff --git a/apps/dokploy/components/dashboard/application/advanced/ports/show-port.tsx b/apps/dokploy/components/dashboard/application/advanced/ports/show-port.tsx index 7d79b268a..816949f2b 100644 --- a/apps/dokploy/components/dashboard/application/advanced/ports/show-port.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/ports/show-port.tsx @@ -1,3 +1,5 @@ +import { Rss, Trash2 } from "lucide-react"; +import { toast } from "sonner"; import { AlertBlock } from "@/components/shared/alert-block"; import { DialogAction } from "@/components/shared/dialog-action"; import { Button } from "@/components/ui/button"; @@ -9,9 +11,8 @@ import { CardTitle, } from "@/components/ui/card"; import { api } from "@/utils/api"; -import { Rss, Trash2 } from "lucide-react"; -import { toast } from "sonner"; import { HandlePorts } from "./handle-ports"; + interface Props { applicationId: string; } diff --git a/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx b/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx index 253a8c24d..c4d38ef18 100644 --- a/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/redirects/handle-redirect.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { PenBoxIcon, PlusIcon } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -30,12 +36,6 @@ import { import { Separator } from "@/components/ui/separator"; import { Switch } from "@/components/ui/switch"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { PenBoxIcon, PlusIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const AddRedirectchema = z.object({ regex: z.string().min(1, "Regex required"), diff --git a/apps/dokploy/components/dashboard/application/advanced/redirects/show-redirects.tsx b/apps/dokploy/components/dashboard/application/advanced/redirects/show-redirects.tsx index 5c2c5943c..f1b14bfc0 100644 --- a/apps/dokploy/components/dashboard/application/advanced/redirects/show-redirects.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/redirects/show-redirects.tsx @@ -1,3 +1,5 @@ +import { Split, Trash2 } from "lucide-react"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; import { Button } from "@/components/ui/button"; import { @@ -8,8 +10,6 @@ import { CardTitle, } from "@/components/ui/card"; import { api } from "@/utils/api"; -import { Split, Trash2 } from "lucide-react"; -import { toast } from "sonner"; import { HandleRedirect } from "./handle-redirect"; interface Props { diff --git a/apps/dokploy/components/dashboard/application/advanced/security/handle-security.tsx b/apps/dokploy/components/dashboard/application/advanced/security/handle-security.tsx index 2fc50c7c7..c52976eb1 100644 --- a/apps/dokploy/components/dashboard/application/advanced/security/handle-security.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/security/handle-security.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { PenBoxIcon, PlusIcon } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -19,12 +25,6 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { PenBoxIcon, PlusIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const AddSecuritychema = z.object({ username: z.string().min(1, "Username is required"), diff --git a/apps/dokploy/components/dashboard/application/advanced/security/show-security.tsx b/apps/dokploy/components/dashboard/application/advanced/security/show-security.tsx index 552a186a1..5676e6f00 100644 --- a/apps/dokploy/components/dashboard/application/advanced/security/show-security.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/security/show-security.tsx @@ -1,4 +1,7 @@ +import { LockKeyhole, Trash2 } from "lucide-react"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; +import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { Button } from "@/components/ui/button"; import { Card, @@ -7,12 +10,9 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { Label } from "@/components/ui/label"; -import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input"; import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; import { api } from "@/utils/api"; -import { LockKeyhole, Trash2 } from "lucide-react"; -import { toast } from "sonner"; import { HandleSecurity } from "./handle-security"; interface Props { diff --git a/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx b/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx index 3d26716fc..25040067b 100644 --- a/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/show-resources.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { InfoIcon } from "lucide-react"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -23,12 +29,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { InfoIcon } from "lucide-react"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const addResourcesSchema = z.object({ memoryReservation: z.string().optional(), diff --git a/apps/dokploy/components/dashboard/application/advanced/traefik/show-traefik-config.tsx b/apps/dokploy/components/dashboard/application/advanced/traefik/show-traefik-config.tsx index 58601fb49..ae23f1866 100644 --- a/apps/dokploy/components/dashboard/application/advanced/traefik/show-traefik-config.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/traefik/show-traefik-config.tsx @@ -1,3 +1,4 @@ +import { File, Loader2 } from "lucide-react"; import { CodeEditor } from "@/components/shared/code-editor"; import { Card, @@ -7,8 +8,8 @@ import { CardTitle, } from "@/components/ui/card"; import { api } from "@/utils/api"; -import { File, Loader2 } from "lucide-react"; import { UpdateTraefikConfig } from "./update-traefik-config"; + interface Props { applicationId: string; } diff --git a/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx b/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx index c73ed5b3d..73512837f 100644 --- a/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/traefik/update-traefik-config.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import jsyaml from "js-yaml"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; @@ -19,12 +25,6 @@ import { FormMessage, } from "@/components/ui/form"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import jsyaml from "js-yaml"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const UpdateTraefikConfigSchema = z.object({ traefikConfig: z.string(), diff --git a/apps/dokploy/components/dashboard/application/advanced/volumes/add-volumes.tsx b/apps/dokploy/components/dashboard/application/advanced/volumes/add-volumes.tsx index 84c864e3a..00be8a1e1 100644 --- a/apps/dokploy/components/dashboard/application/advanced/volumes/add-volumes.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/volumes/add-volumes.tsx @@ -1,3 +1,10 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { PlusIcon } from "lucide-react"; +import type React from "react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; @@ -22,13 +29,7 @@ import { Label } from "@/components/ui/label"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { PlusIcon } from "lucide-react"; -import type React from "react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; + interface Props { serviceId: string; serviceType: diff --git a/apps/dokploy/components/dashboard/application/advanced/volumes/update-volume.tsx b/apps/dokploy/components/dashboard/application/advanced/volumes/update-volume.tsx index 2a692f100..38d02ec90 100644 --- a/apps/dokploy/components/dashboard/application/advanced/volumes/update-volume.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/volumes/update-volume.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { PenBoxIcon } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; @@ -20,12 +26,6 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { PenBoxIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const mountSchema = z.object({ mountPath: z.string().min(1, "Mount path required"), diff --git a/apps/dokploy/components/dashboard/application/deployments/cancel-queues.tsx b/apps/dokploy/components/dashboard/application/deployments/cancel-queues.tsx index eb85f383b..e957a496c 100644 --- a/apps/dokploy/components/dashboard/application/deployments/cancel-queues.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/cancel-queues.tsx @@ -1,3 +1,5 @@ +import { Paintbrush } from "lucide-react"; +import { toast } from "sonner"; import { AlertDialog, AlertDialogAction, @@ -11,8 +13,6 @@ import { } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { api } from "@/utils/api"; -import { Paintbrush } from "lucide-react"; -import { toast } from "sonner"; interface Props { id: string; diff --git a/apps/dokploy/components/dashboard/application/deployments/refresh-token.tsx b/apps/dokploy/components/dashboard/application/deployments/refresh-token.tsx index abfe37c3c..c49331ed7 100644 --- a/apps/dokploy/components/dashboard/application/deployments/refresh-token.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/refresh-token.tsx @@ -1,3 +1,5 @@ +import { RefreshCcw } from "lucide-react"; +import { toast } from "sonner"; import { AlertDialog, AlertDialogAction, @@ -10,8 +12,6 @@ import { AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { api } from "@/utils/api"; -import { RefreshCcw } from "lucide-react"; -import { toast } from "sonner"; interface Props { id: string; diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployment.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployment.tsx index 8733c745b..69c697721 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployment.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployment.tsx @@ -1,3 +1,5 @@ +import { Loader2 } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Checkbox } from "@/components/ui/checkbox"; import { @@ -7,8 +9,6 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { Loader2 } from "lucide-react"; -import { useEffect, useRef, useState } from "react"; import { TerminalLine } from "../../docker/logs/terminal-line"; import { type LogLine, parseLogs } from "../../docker/logs/utils"; diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployments-modal.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployments-modal.tsx index 4631a066e..7c937883e 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployments-modal.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployments-modal.tsx @@ -1,8 +1,7 @@ +import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; - import type { RouterOutputs } from "@/utils/api"; -import { useState } from "react"; import { ShowDeployment } from "../deployments/show-deployment"; import { ShowDeployments } from "./show-deployments"; diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx index 5790c129c..5efa9e5f2 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx @@ -1,3 +1,6 @@ +import { Clock, Loader2, RefreshCcw, RocketIcon, Settings } from "lucide-react"; +import React, { useEffect, useState } from "react"; +import { toast } from "sonner"; import { DateTooltip } from "@/components/shared/date-tooltip"; import { DialogAction } from "@/components/shared/dialog-action"; import { StatusTooltip } from "@/components/shared/status-tooltip"; @@ -10,10 +13,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { type RouterOutputs, api } from "@/utils/api"; -import { Clock, Loader2, RefreshCcw, RocketIcon, Settings } from "lucide-react"; -import React, { useEffect, useState } from "react"; -import { toast } from "sonner"; +import { api, type RouterOutputs } from "@/utils/api"; import { ShowRollbackSettings } from "../rollbacks/show-rollback-settings"; import { CancelQueues } from "./cancel-queues"; import { RefreshToken } from "./refresh-token"; diff --git a/apps/dokploy/components/dashboard/application/domains/dns-helper-modal.tsx b/apps/dokploy/components/dashboard/application/domains/dns-helper-modal.tsx index c67c2fbfc..768ece858 100644 --- a/apps/dokploy/components/dashboard/application/domains/dns-helper-modal.tsx +++ b/apps/dokploy/components/dashboard/application/domains/dns-helper-modal.tsx @@ -1,3 +1,5 @@ +import { Copy, HelpCircle, Server } from "lucide-react"; +import { toast } from "sonner"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -8,8 +10,6 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; -import { Copy, HelpCircle, Server } from "lucide-react"; -import { toast } from "sonner"; interface Props { domain: { diff --git a/apps/dokploy/components/dashboard/application/domains/show-domains.tsx b/apps/dokploy/components/dashboard/application/domains/show-domains.tsx index 7bb58dfbe..1fd3d82e9 100644 --- a/apps/dokploy/components/dashboard/application/domains/show-domains.tsx +++ b/apps/dokploy/components/dashboard/application/domains/show-domains.tsx @@ -1,3 +1,18 @@ +import { + CheckCircle2, + ExternalLink, + GlobeIcon, + InfoIcon, + Loader2, + PenBoxIcon, + RefreshCw, + Server, + Trash2, + XCircle, +} from "lucide-react"; +import Link from "next/link"; +import { useState } from "react"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -15,21 +30,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import { - CheckCircle2, - ExternalLink, - GlobeIcon, - InfoIcon, - Loader2, - PenBoxIcon, - RefreshCw, - Server, - Trash2, - XCircle, -} from "lucide-react"; -import Link from "next/link"; -import { useState } from "react"; -import { toast } from "sonner"; import { DnsHelperModal } from "./dns-helper-modal"; import { AddDomain } from "./handle-domain"; diff --git a/apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx b/apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx index 8a78c2745..4a5d0270b 100644 --- a/apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx +++ b/apps/dokploy/components/dashboard/application/environment/show-enviroment.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { EyeIcon, EyeOffIcon } from "lucide-react"; +import { type CSSProperties, useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; import { @@ -16,12 +22,6 @@ import { } from "@/components/ui/form"; import { Toggle } from "@/components/ui/toggle"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { EyeIcon, EyeOffIcon } from "lucide-react"; -import { type CSSProperties, useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; import type { ServiceType } from "../advanced/show-resources"; const addEnvironmentSchema = z.object({ diff --git a/apps/dokploy/components/dashboard/application/environment/show.tsx b/apps/dokploy/components/dashboard/application/environment/show.tsx index 6f504959c..78edb1aaa 100644 --- a/apps/dokploy/components/dashboard/application/environment/show.tsx +++ b/apps/dokploy/components/dashboard/application/environment/show.tsx @@ -1,13 +1,13 @@ -import { Button } from "@/components/ui/button"; -import { Card } from "@/components/ui/card"; -import { Form } from "@/components/ui/form"; -import { Secrets } from "@/components/ui/secrets"; -import { api } from "@/utils/api"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Form } from "@/components/ui/form"; +import { Secrets } from "@/components/ui/secrets"; +import { api } from "@/utils/api"; const addEnvironmentSchema = z.object({ env: z.string(), diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-bitbucket-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-bitbucket-provider.tsx index befc85957..6f6db5dd1 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-bitbucket-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-bitbucket-provider.tsx @@ -1,3 +1,10 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { CheckIcon, ChevronsUpDown, X } from "lucide-react"; +import Link from "next/link"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { BitbucketIcon } from "@/components/icons/data-tools-icons"; import { AlertBlock } from "@/components/shared/alert-block"; import { Badge } from "@/components/ui/badge"; @@ -40,13 +47,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { CheckIcon, ChevronsUpDown, X } from "lucide-react"; -import Link from "next/link"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const BitbucketProviderSchema = z.object({ buildPath: z.string().min(1, "Path is required").default("/"), diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-docker-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-docker-provider.tsx index 72b2578c5..fcdcf0a93 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-docker-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-docker-provider.tsx @@ -1,3 +1,8 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { Button } from "@/components/ui/button"; import { Form, @@ -9,11 +14,6 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const DockerProviderSchema = z.object({ dockerImage: z.string().min(1, { diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-drag-n-drop.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-drag-n-drop.tsx index 3732860d4..00e18c2ab 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-drag-n-drop.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-drag-n-drop.tsx @@ -1,3 +1,8 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { TrashIcon } from "lucide-react"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dropzone } from "@/components/ui/dropzone"; import { @@ -11,11 +16,6 @@ import { import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; import { type UploadFile, uploadFileSchema } from "@/utils/schema"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { TrashIcon } from "lucide-react"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; interface Props { applicationId: string; diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-git-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-git-provider.tsx index f3e8116e6..61690e740 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-git-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-git-provider.tsx @@ -1,3 +1,13 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { KeyRoundIcon, LockIcon, X } from "lucide-react"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { GitIcon } from "@/components/icons/data-tools-icons"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Form, @@ -25,17 +35,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { KeyRoundIcon, LockIcon, X } from "lucide-react"; -import Link from "next/link"; -import { useRouter } from "next/router"; - -import { GitIcon } from "@/components/icons/data-tools-icons"; -import { Badge } from "@/components/ui/badge"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const GitProviderSchema = z.object({ buildPath: z.string().min(1, "Path is required").default("/"), diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-gitea-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-gitea-provider.tsx index 55fbfebda..2198f4a97 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-gitea-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-gitea-provider.tsx @@ -1,3 +1,10 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; +import Link from "next/link"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { GiteaIcon } from "@/components/icons/data-tools-icons"; import { AlertBlock } from "@/components/shared/alert-block"; import { Badge } from "@/components/ui/badge"; @@ -40,13 +47,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; -import Link from "next/link"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; interface GiteaRepository { name: string; diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-github-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-github-provider.tsx index c76b9ae58..9a4b92ce1 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-github-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-github-provider.tsx @@ -1,3 +1,10 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; +import Link from "next/link"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { GithubIcon } from "@/components/icons/data-tools-icons"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -39,13 +46,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; -import Link from "next/link"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const GithubProviderSchema = z.object({ buildPath: z.string().min(1, "Path is required").default("/"), diff --git a/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx index 2995e45f3..cb7209f8a 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/save-gitlab-provider.tsx @@ -1,3 +1,10 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; +import Link from "next/link"; +import { useEffect, useMemo } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { GitlabIcon } from "@/components/icons/data-tools-icons"; import { AlertBlock } from "@/components/shared/alert-block"; import { Badge } from "@/components/ui/badge"; @@ -40,13 +47,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { CheckIcon, ChevronsUpDown, HelpCircle, Plus, X } from "lucide-react"; -import Link from "next/link"; -import { useEffect, useMemo } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const GitlabProviderSchema = z.object({ buildPath: z.string().min(1, "Path is required").default("/"), diff --git a/apps/dokploy/components/dashboard/application/general/generic/show.tsx b/apps/dokploy/components/dashboard/application/general/generic/show.tsx index 786c79e5c..a60db800c 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/show.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/show.tsx @@ -1,3 +1,7 @@ +import { GitBranch, Loader2, UploadCloud } from "lucide-react"; +import Link from "next/link"; +import { useState } from "react"; +import { toast } from "sonner"; import { SaveDockerProvider } from "@/components/dashboard/application/general/generic/save-docker-provider"; import { SaveGitProvider } from "@/components/dashboard/application/general/generic/save-git-provider"; import { SaveGiteaProvider } from "@/components/dashboard/application/general/generic/save-gitea-provider"; @@ -5,18 +9,14 @@ import { SaveGithubProvider } from "@/components/dashboard/application/general/g import { BitbucketIcon, DockerIcon, - GitIcon, GiteaIcon, GithubIcon, + GitIcon, GitlabIcon, } from "@/components/icons/data-tools-icons"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { api } from "@/utils/api"; -import { GitBranch, Loader2, UploadCloud } from "lucide-react"; -import Link from "next/link"; -import { useState } from "react"; -import { toast } from "sonner"; import { SaveBitbucketProvider } from "./save-bitbucket-provider"; import { SaveDragNDrop } from "./save-drag-n-drop"; import { SaveGitlabProvider } from "./save-gitlab-provider"; diff --git a/apps/dokploy/components/dashboard/application/general/generic/unauthorized-git-provider.tsx b/apps/dokploy/components/dashboard/application/general/generic/unauthorized-git-provider.tsx index 4dbdf7a69..de3fbff06 100644 --- a/apps/dokploy/components/dashboard/application/general/generic/unauthorized-git-provider.tsx +++ b/apps/dokploy/components/dashboard/application/general/generic/unauthorized-git-provider.tsx @@ -1,8 +1,9 @@ +import { AlertCircle, GitBranch, Unlink } from "lucide-react"; import { BitbucketIcon, - GitIcon, GiteaIcon, GithubIcon, + GitIcon, GitlabIcon, } from "@/components/icons/data-tools-icons"; import { DialogAction } from "@/components/shared/dialog-action"; @@ -10,7 +11,6 @@ import { Alert, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import type { RouterOutputs } from "@/utils/api"; -import { AlertCircle, GitBranch, Unlink } from "lucide-react"; interface Props { service: diff --git a/apps/dokploy/components/dashboard/application/general/show.tsx b/apps/dokploy/components/dashboard/application/general/show.tsx index c917d7ab7..a8fef349b 100644 --- a/apps/dokploy/components/dashboard/application/general/show.tsx +++ b/apps/dokploy/components/dashboard/application/general/show.tsx @@ -1,3 +1,14 @@ +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; +import { + Ban, + CheckCircle2, + Hammer, + RefreshCcw, + Rocket, + Terminal, +} from "lucide-react"; +import { useRouter } from "next/router"; +import { toast } from "sonner"; import { ShowBuildChooseForm } from "@/components/dashboard/application/build/show"; import { ShowProviderForm } from "@/components/dashboard/application/general/generic/show"; import { DialogAction } from "@/components/shared/dialog-action"; @@ -11,18 +22,8 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import * as TooltipPrimitive from "@radix-ui/react-tooltip"; -import { - Ban, - CheckCircle2, - Hammer, - RefreshCcw, - Rocket, - Terminal, -} from "lucide-react"; -import { useRouter } from "next/router"; -import { toast } from "sonner"; import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal"; + interface Props { applicationId: string; } diff --git a/apps/dokploy/components/dashboard/application/logs/show.tsx b/apps/dokploy/components/dashboard/application/logs/show.tsx index a73b99d25..e5dff075e 100644 --- a/apps/dokploy/components/dashboard/application/logs/show.tsx +++ b/apps/dokploy/components/dashboard/application/logs/show.tsx @@ -1,3 +1,6 @@ +import { Loader2 } from "lucide-react"; +import dynamic from "next/dynamic"; +import { useEffect, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Card, @@ -18,9 +21,6 @@ import { } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { api } from "@/utils/api"; -import { Loader2 } from "lucide-react"; -import dynamic from "next/dynamic"; -import { useEffect, useState } from "react"; export const DockerLogs = dynamic( () => import("@/components/dashboard/docker/logs/docker-logs-id").then( diff --git a/apps/dokploy/components/dashboard/application/preview-deployments/add-preview-domain.tsx b/apps/dokploy/components/dashboard/application/preview-deployments/add-preview-domain.tsx index bb6f0e0a7..eac4559f1 100644 --- a/apps/dokploy/components/dashboard/application/preview-deployments/add-preview-domain.tsx +++ b/apps/dokploy/components/dashboard/application/preview-deployments/add-preview-domain.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { Dices } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import type z from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -33,15 +39,8 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; -import { api } from "@/utils/api"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; - import { domain } from "@/server/db/validations/domain"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { Dices } from "lucide-react"; -import type z from "zod"; +import { api } from "@/utils/api"; type Domain = z.infer; diff --git a/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-deployments.tsx b/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-deployments.tsx index bf93af718..d93bbd1c8 100644 --- a/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-deployments.tsx +++ b/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-deployments.tsx @@ -1,3 +1,13 @@ +import { + ExternalLink, + FileText, + GitPullRequest, + Loader2, + PenSquare, + RocketIcon, + Trash2, +} from "lucide-react"; +import { toast } from "sonner"; import { GithubIcon } from "@/components/icons/data-tools-icons"; import { DateTooltip } from "@/components/shared/date-tooltip"; import { DialogAction } from "@/components/shared/dialog-action"; @@ -13,16 +23,6 @@ import { } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { - ExternalLink, - FileText, - GitPullRequest, - Loader2, - PenSquare, - RocketIcon, - Trash2, -} from "lucide-react"; -import { toast } from "sonner"; import { ShowModalLogs } from "../../settings/web-server/show-modal-logs"; import { ShowDeploymentsModal } from "../deployments/show-deployments-modal"; import { AddPreviewDomain } from "./add-preview-domain"; diff --git a/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-settings.tsx b/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-settings.tsx index a0f6ae0e4..3605480a0 100644 --- a/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-settings.tsx +++ b/apps/dokploy/components/dashboard/application/preview-deployments/show-preview-settings.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { Settings2 } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -28,12 +34,6 @@ import { } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { Settings2 } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const schema = z .object({ diff --git a/apps/dokploy/components/dashboard/application/rollbacks/show-rollback-settings.tsx b/apps/dokploy/components/dashboard/application/rollbacks/show-rollback-settings.tsx index 77575ea03..2fc7c0522 100644 --- a/apps/dokploy/components/dashboard/application/rollbacks/show-rollback-settings.tsx +++ b/apps/dokploy/components/dashboard/application/rollbacks/show-rollback-settings.tsx @@ -1,3 +1,8 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -18,11 +23,6 @@ import { } from "@/components/ui/form"; import { Switch } from "@/components/ui/switch"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const formSchema = z.object({ rollbackActive: z.boolean(), diff --git a/apps/dokploy/components/dashboard/application/schedules/handle-schedules.tsx b/apps/dokploy/components/dashboard/application/schedules/handle-schedules.tsx index 077c289b8..e403c8be5 100644 --- a/apps/dokploy/components/dashboard/application/schedules/handle-schedules.tsx +++ b/apps/dokploy/components/dashboard/application/schedules/handle-schedules.tsx @@ -1,3 +1,15 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { + DatabaseZap, + Info, + PenBoxIcon, + PlusCircle, + RefreshCw, +} from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { CodeEditor } from "@/components/shared/code-editor"; import { Button } from "@/components/ui/button"; @@ -35,18 +47,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { - DatabaseZap, - Info, - PenBoxIcon, - PlusCircle, - RefreshCw, -} from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; import type { CacheType } from "../domains/handle-domain"; export const commonCronExpressions = [ diff --git a/apps/dokploy/components/dashboard/application/schedules/show-schedules.tsx b/apps/dokploy/components/dashboard/application/schedules/show-schedules.tsx index 2f2ebc85a..3ebc76def 100644 --- a/apps/dokploy/components/dashboard/application/schedules/show-schedules.tsx +++ b/apps/dokploy/components/dashboard/application/schedules/show-schedules.tsx @@ -1,3 +1,12 @@ +import { + ClipboardList, + Clock, + Loader2, + Play, + Terminal, + Trash2, +} from "lucide-react"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -15,15 +24,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import { - ClipboardList, - Clock, - Loader2, - Play, - Terminal, - Trash2, -} from "lucide-react"; -import { toast } from "sonner"; import { ShowDeploymentsModal } from "../deployments/show-deployments-modal"; import { HandleSchedules } from "./handle-schedules"; diff --git a/apps/dokploy/components/dashboard/application/update-application.tsx b/apps/dokploy/components/dashboard/application/update-application.tsx index 4d4190fa2..754074d75 100644 --- a/apps/dokploy/components/dashboard/application/update-application.tsx +++ b/apps/dokploy/components/dashboard/application/update-application.tsx @@ -1,3 +1,9 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { PenBoxIcon } from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -20,12 +26,6 @@ import { import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { PenBoxIcon } from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const updateApplicationSchema = z.object({ name: z.string().min(1, { diff --git a/apps/dokploy/components/dashboard/application/volume-backups/handle-volume-backups.tsx b/apps/dokploy/components/dashboard/application/volume-backups/handle-volume-backups.tsx index c66b05850..29f8f6e15 100644 --- a/apps/dokploy/components/dashboard/application/volume-backups/handle-volume-backups.tsx +++ b/apps/dokploy/components/dashboard/application/volume-backups/handle-volume-backups.tsx @@ -1,3 +1,15 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { + DatabaseZap, + Info, + PenBoxIcon, + PlusCircle, + RefreshCw, +} from "lucide-react"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -34,18 +46,6 @@ import { } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { - DatabaseZap, - Info, - PenBoxIcon, - PlusCircle, - RefreshCw, -} from "lucide-react"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; import type { CacheType } from "../domains/handle-domain"; import { commonCronExpressions } from "../schedules/handle-schedules"; diff --git a/apps/dokploy/components/dashboard/application/volume-backups/restore-volume-backups.tsx b/apps/dokploy/components/dashboard/application/volume-backups/restore-volume-backups.tsx index b3baeb38f..6eda33648 100644 --- a/apps/dokploy/components/dashboard/application/volume-backups/restore-volume-backups.tsx +++ b/apps/dokploy/components/dashboard/application/volume-backups/restore-volume-backups.tsx @@ -1,3 +1,11 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import copy from "copy-to-clipboard"; +import { debounce } from "lodash"; +import { CheckIcon, ChevronsUpDown, Copy, RotateCcw } from "lucide-react"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { DrawerLogs } from "@/components/shared/drawer-logs"; import { Badge } from "@/components/ui/badge"; @@ -35,14 +43,6 @@ import { import { ScrollArea } from "@/components/ui/scroll-area"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import copy from "copy-to-clipboard"; -import { debounce } from "lodash"; -import { CheckIcon, ChevronsUpDown, Copy, RotateCcw } from "lucide-react"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; import { formatBytes } from "../../database/backups/restore-backup"; import { type LogLine, parseLogs } from "../../docker/logs/utils"; diff --git a/apps/dokploy/components/dashboard/application/volume-backups/show-volume-backups.tsx b/apps/dokploy/components/dashboard/application/volume-backups/show-volume-backups.tsx index 6d7895ee7..c88dd92f5 100644 --- a/apps/dokploy/components/dashboard/application/volume-backups/show-volume-backups.tsx +++ b/apps/dokploy/components/dashboard/application/volume-backups/show-volume-backups.tsx @@ -1,3 +1,11 @@ +import { + ClipboardList, + DatabaseBackup, + Loader2, + Play, + Trash2, +} from "lucide-react"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -15,14 +23,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import { - ClipboardList, - DatabaseBackup, - Loader2, - Play, - Trash2, -} from "lucide-react"; -import { toast } from "sonner"; import { ShowDeploymentsModal } from "../deployments/show-deployments-modal"; import { HandleVolumeBackups } from "./handle-volume-backups"; import { RestoreVolumeBackups } from "./restore-volume-backups"; diff --git a/apps/dokploy/components/dashboard/compose/advanced/add-command.tsx b/apps/dokploy/components/dashboard/compose/advanced/add-command.tsx index c5a34b3c1..52eb18907 100644 --- a/apps/dokploy/components/dashboard/compose/advanced/add-command.tsx +++ b/apps/dokploy/components/dashboard/compose/advanced/add-command.tsx @@ -1,3 +1,8 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { useEffect } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { AlertBlock } from "@/components/shared/alert-block"; import { Button } from "@/components/ui/button"; import { @@ -18,11 +23,7 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; + interface Props { composeId: string; } diff --git a/apps/dokploy/components/dashboard/compose/delete-service.tsx b/apps/dokploy/components/dashboard/compose/delete-service.tsx index 65689afd1..cae27c264 100644 --- a/apps/dokploy/components/dashboard/compose/delete-service.tsx +++ b/apps/dokploy/components/dashboard/compose/delete-service.tsx @@ -1,3 +1,12 @@ +import type { ServiceType } from "@dokploy/server/db/schema"; +import { zodResolver } from "@hookform/resolvers/zod"; +import copy from "copy-to-clipboard"; +import { Copy, Trash2 } from "lucide-react"; +import { useRouter } from "next/router"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; @@ -20,15 +29,6 @@ import { } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { api } from "@/utils/api"; -import type { ServiceType } from "@dokploy/server/db/schema"; -import { zodResolver } from "@hookform/resolvers/zod"; -import copy from "copy-to-clipboard"; -import { Copy, Trash2 } from "lucide-react"; -import { useRouter } from "next/router"; -import { useState } from "react"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; -import { z } from "zod"; const deleteComposeSchema = z.object({ projectName: z.string().min(1, { diff --git a/apps/dokploy/components/dashboard/compose/general/actions.tsx b/apps/dokploy/components/dashboard/compose/general/actions.tsx index 0a4433e7c..29a9f9be3 100644 --- a/apps/dokploy/components/dashboard/compose/general/actions.tsx +++ b/apps/dokploy/components/dashboard/compose/general/actions.tsx @@ -1,3 +1,7 @@ +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; +import { Ban, CheckCircle2, RefreshCcw, Rocket, Terminal } from "lucide-react"; +import { useRouter } from "next/router"; +import { toast } from "sonner"; import { DialogAction } from "@/components/shared/dialog-action"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; @@ -8,10 +12,6 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { api } from "@/utils/api"; -import * as TooltipPrimitive from "@radix-ui/react-tooltip"; -import { Ban, CheckCircle2, RefreshCcw, Rocket, Terminal } from "lucide-react"; -import { useRouter } from "next/router"; -import { toast } from "sonner"; import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal"; interface Props { diff --git a/apps/dokploy/components/dashboard/compose/general/compose-file-editor.tsx b/apps/dokploy/components/dashboard/compose/general/compose-file-editor.tsx index c2db472d2..afb66bd54 100644 --- a/apps/dokploy/components/dashboard/compose/general/compose-file-editor.tsx +++ b/apps/dokploy/components/dashboard/compose/general/compose-file-editor.tsx @@ -141,7 +141,7 @@ services:
-
+
+ + + + +
From ba1f4dbd3a76c0079de2ea28417a5dc243e2f577 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 23 Aug 2025 16:04:13 -0600 Subject: [PATCH 35/36] feat(ui): add bulk deploy functionality for services in project dashboard --- .../pages/dashboard/project/[projectId].tsx | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/apps/dokploy/pages/dashboard/project/[projectId].tsx b/apps/dokploy/pages/dashboard/project/[projectId].tsx index a32bae06f..65f7d064d 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId].tsx @@ -10,6 +10,7 @@ import { FolderInput, GlobeIcon, Loader2, + Play, PlusIcon, Search, ServerIcon, @@ -312,6 +313,7 @@ const Project = ( stop: api.compose.stop.useMutation(), move: api.compose.move.useMutation(), delete: api.compose.delete.useMutation(), + deploy: api.compose.deploy.useMutation(), }; const applicationActions = { @@ -319,6 +321,7 @@ const Project = ( stop: api.application.stop.useMutation(), move: api.application.move.useMutation(), delete: api.application.delete.useMutation(), + deploy: api.application.deploy.useMutation(), }; const postgresActions = { @@ -326,6 +329,7 @@ const Project = ( stop: api.postgres.stop.useMutation(), move: api.postgres.move.useMutation(), delete: api.postgres.remove.useMutation(), + deploy: api.postgres.deploy.useMutation(), }; const mysqlActions = { @@ -333,6 +337,7 @@ const Project = ( stop: api.mysql.stop.useMutation(), move: api.mysql.move.useMutation(), delete: api.mysql.remove.useMutation(), + deploy: api.mysql.deploy.useMutation(), }; const mariadbActions = { @@ -340,6 +345,7 @@ const Project = ( stop: api.mariadb.stop.useMutation(), move: api.mariadb.move.useMutation(), delete: api.mariadb.remove.useMutation(), + deploy: api.mariadb.deploy.useMutation(), }; const redisActions = { @@ -347,6 +353,7 @@ const Project = ( stop: api.redis.stop.useMutation(), move: api.redis.move.useMutation(), delete: api.redis.remove.useMutation(), + deploy: api.redis.deploy.useMutation(), }; const mongoActions = { @@ -354,6 +361,7 @@ const Project = ( stop: api.mongo.stop.useMutation(), move: api.mongo.move.useMutation(), delete: api.mongo.remove.useMutation(), + deploy: api.mongo.deploy.useMutation(), }; const handleBulkStart = async () => { @@ -586,6 +594,83 @@ const Project = ( setIsBulkActionLoading(false); }; + const handleBulkDeploy = async () => { + let success = 0; + let failed = 0; + setIsBulkActionLoading(true); + + for (const serviceId of selectedServices) { + try { + const service = filteredServices.find((s) => s.id === serviceId); + if (!service) continue; + + switch (service.type) { + case "application": + await applicationActions.deploy.mutateAsync({ + applicationId: serviceId, + }); + break; + case "compose": + await composeActions.deploy.mutateAsync({ + composeId: serviceId, + }); + + break; + case "postgres": + await postgresActions.deploy.mutateAsync({ + postgresId: serviceId, + }); + + break; + case "mysql": + await mysqlActions.deploy.mutateAsync({ + mysqlId: serviceId, + }); + + break; + case "mariadb": + await mariadbActions.deploy.mutateAsync({ + mariadbId: serviceId, + }); + + break; + case "redis": + await redisActions.deploy.mutateAsync({ + redisId: serviceId, + }); + + break; + case "mongo": + await mongoActions.deploy.mutateAsync({ + mongoId: serviceId, + }); + + break; + } + success++; + } catch (error) { + failed++; + toast.error( + `Error deploying service ${serviceId}: ${error instanceof Error ? error.message : "Unknown error"}`, + ); + } + } + if (success > 0) { + toast.success( + `${success} service${success !== 1 ? "s" : ""} deployed successfully`, + ); + } + if (failed > 0) { + toast.error( + `${failed} service${failed !== 1 ? "s" : ""} failed to deploy`, + ); + } + + setSelectedServices([]); + setIsDropdownOpen(false); + setIsBulkActionLoading(false); + }; + const filteredServices = useMemo(() => { if (!applications) return []; const filtered = applications.filter( @@ -729,6 +814,24 @@ const Project = ( Start + + + Date: Sat, 23 Aug 2025 16:06:25 -0600 Subject: [PATCH 36/36] feat(ui): implement bulk delete dialog for services in project dashboard --- .../pages/dashboard/project/[projectId].tsx | 115 +++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/pages/dashboard/project/[projectId].tsx b/apps/dokploy/pages/dashboard/project/[projectId].tsx index 65f7d064d..3182f316a 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId].tsx @@ -290,6 +290,8 @@ const Project = ( const [openCombobox, setOpenCombobox] = useState(false); const [selectedServices, setSelectedServices] = useState([]); const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [isBulkDeleteDialogOpen, setIsBulkDeleteDialogOpen] = useState(false); + const [deleteVolumes, setDeleteVolumes] = useState(false); const handleSelectAll = () => { if (selectedServices.length === filteredServices.length) { @@ -532,7 +534,7 @@ const Project = ( setIsBulkActionLoading(false); }; - const handleBulkDelete = async () => { + const handleBulkDelete = async (deleteVolumes = false) => { let success = 0; setIsBulkActionLoading(true); for (const serviceId of selectedServices) { @@ -549,7 +551,7 @@ const Project = ( case "compose": await composeActions.delete.mutateAsync({ composeId: serviceId, - deleteVolumes: false, + deleteVolumes, }); break; case "postgres": @@ -879,7 +881,7 @@ const Project = ( disabled={ selectedServicesWithRunningStatus.length > 0 } - onClick={handleBulkDelete} + onClick={() => setIsBulkDeleteDialogOpen(true)} > + + + +