Skip to content

Commit 46ddaa6

Browse files
authored
Merge pull request #1221 from Dokploy/1170-0176-copy-to-clipboard-stopped-working-on-the-project-delete-confirm-dialog
refactor: add back delete with confirmation
2 parents 13551f6 + 64e68cf commit 46ddaa6

File tree

11 files changed

+102
-216
lines changed

11 files changed

+102
-216
lines changed

apps/dokploy/components/dashboard/application/domains/show-domains.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@ export const ShowDomains = ({ applicationId }: Props) => {
9898
applicationId={applicationId}
9999
domainId={item.domainId}
100100
>
101-
<Button variant="ghost">
102-
<PenBoxIcon className="size-4 text-muted-foreground" />
101+
<Button
102+
variant="ghost"
103+
size="icon"
104+
className="group hover:bg-blue-500/10 "
105+
>
106+
<PenBoxIcon className="size-3.5 text-primary group-hover:text-blue-500" />
103107
</Button>
104108
</AddDomain>
105109
<DialogAction

apps/dokploy/components/dashboard/compose/delete-compose.tsx renamed to apps/dokploy/components/dashboard/compose/delete-service.tsx

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ import {
2020
} from "@/components/ui/form";
2121
import { Input } from "@/components/ui/input";
2222
import { api } from "@/utils/api";
23+
import type { ServiceType } from "@dokploy/server/db/schema";
2324
import { zodResolver } from "@hookform/resolvers/zod";
25+
import copy from "copy-to-clipboard";
2426
import { Copy, Trash2 } from "lucide-react";
25-
import { TrashIcon } from "lucide-react";
2627
import { useRouter } from "next/router";
2728
import { useState } from "react";
2829
import { useForm } from "react-hook-form";
@@ -39,16 +40,42 @@ const deleteComposeSchema = z.object({
3940
type DeleteCompose = z.infer<typeof deleteComposeSchema>;
4041

4142
interface Props {
42-
composeId: string;
43+
id: string;
44+
type: ServiceType | "application";
4345
}
4446

45-
export const DeleteCompose = ({ composeId }: Props) => {
47+
export const DeleteService = ({ id, type }: Props) => {
4648
const [isOpen, setIsOpen] = useState(false);
47-
const { mutateAsync, isLoading } = api.compose.delete.useMutation();
48-
const { data } = api.compose.one.useQuery(
49-
{ composeId },
50-
{ enabled: !!composeId },
51-
);
49+
50+
const queryMap = {
51+
postgres: () =>
52+
api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }),
53+
redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }),
54+
mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }),
55+
mariadb: () =>
56+
api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }),
57+
application: () =>
58+
api.application.one.useQuery({ applicationId: id }, { enabled: !!id }),
59+
mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }),
60+
compose: () =>
61+
api.compose.one.useQuery({ composeId: id }, { enabled: !!id }),
62+
};
63+
const { data, refetch } = queryMap[type]
64+
? queryMap[type]()
65+
: api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id });
66+
67+
const mutationMap = {
68+
postgres: () => api.postgres.remove.useMutation(),
69+
redis: () => api.redis.remove.useMutation(),
70+
mysql: () => api.mysql.remove.useMutation(),
71+
mariadb: () => api.mariadb.remove.useMutation(),
72+
application: () => api.application.delete.useMutation(),
73+
mongo: () => api.mongo.remove.useMutation(),
74+
compose: () => api.compose.delete.useMutation(),
75+
};
76+
const { mutateAsync, isLoading } = mutationMap[type]
77+
? mutationMap[type]()
78+
: api.mongo.remove.useMutation();
5279
const { push } = useRouter();
5380
const form = useForm<DeleteCompose>({
5481
defaultValues: {
@@ -62,14 +89,23 @@ export const DeleteCompose = ({ composeId }: Props) => {
6289
const expectedName = `${data?.name}/${data?.appName}`;
6390
if (formData.projectName === expectedName) {
6491
const { deleteVolumes } = formData;
65-
await mutateAsync({ composeId, deleteVolumes })
92+
await mutateAsync({
93+
mongoId: id || "",
94+
postgresId: id || "",
95+
redisId: id || "",
96+
mysqlId: id || "",
97+
mariadbId: id || "",
98+
applicationId: id || "",
99+
composeId: id || "",
100+
deleteVolumes,
101+
})
66102
.then((result) => {
67103
push(`/dashboard/project/${result?.projectId}`);
68-
toast.success("Compose deleted successfully");
104+
toast.success("deleted successfully");
69105
setIsOpen(false);
70106
})
71107
.catch(() => {
72-
toast.error("Error deleting the compose");
108+
toast.error("Error deleting the service");
73109
});
74110
} else {
75111
form.setError("projectName", {
@@ -95,8 +131,8 @@ export const DeleteCompose = ({ composeId }: Props) => {
95131
<DialogTitle>Are you absolutely sure?</DialogTitle>
96132
<DialogDescription>
97133
This action cannot be undone. This will permanently delete the
98-
compose. If you are sure please enter the compose name to delete
99-
this compose.
134+
service. If you are sure please enter the service name to delete
135+
this service.
100136
</DialogDescription>
101137
</DialogHeader>
102138
<div className="grid gap-4">
@@ -119,9 +155,7 @@ export const DeleteCompose = ({ composeId }: Props) => {
119155
variant="outline"
120156
onClick={() => {
121157
if (data?.name && data?.appName) {
122-
navigator.clipboard.writeText(
123-
`${data.name}/${data.appName}`,
124-
);
158+
copy(`${data.name}/${data.appName}`);
125159
toast.success("Copied to clipboard. Be careful!");
126160
}
127161
}}
@@ -142,27 +176,29 @@ export const DeleteCompose = ({ composeId }: Props) => {
142176
</FormItem>
143177
)}
144178
/>
145-
<FormField
146-
control={form.control}
147-
name="deleteVolumes"
148-
render={({ field }) => (
149-
<FormItem>
150-
<div className="flex items-center">
151-
<FormControl>
152-
<Checkbox
153-
checked={field.value}
154-
onCheckedChange={field.onChange}
155-
/>
156-
</FormControl>
179+
{type === "compose" && (
180+
<FormField
181+
control={form.control}
182+
name="deleteVolumes"
183+
render={({ field }) => (
184+
<FormItem>
185+
<div className="flex items-center">
186+
<FormControl>
187+
<Checkbox
188+
checked={field.value}
189+
onCheckedChange={field.onChange}
190+
/>
191+
</FormControl>
157192

158-
<FormLabel className="ml-2">
159-
Delete volumes associated with this compose
160-
</FormLabel>
161-
</div>
162-
<FormMessage />
163-
</FormItem>
164-
)}
165-
/>
193+
<FormLabel className="ml-2">
194+
Delete volumes associated with this compose
195+
</FormLabel>
196+
</div>
197+
<FormMessage />
198+
</FormItem>
199+
)}
200+
/>
201+
)}
166202
</form>
167203
</Form>
168204
</div>

apps/dokploy/components/dashboard/compose/domains/show-domains.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,12 @@ export const ShowDomainsCompose = ({ composeId }: Props) => {
9797
composeId={composeId}
9898
domainId={item.domainId}
9999
>
100-
<Button variant="ghost">
101-
<PenBoxIcon className="size-4 text-muted-foreground" />
100+
<Button
101+
variant="ghost"
102+
size="icon"
103+
className="group hover:bg-blue-500/10 "
104+
>
105+
<PenBoxIcon className="size-3.5 text-primary group-hover:text-blue-500" />
102106
</Button>
103107
</AddDomainCompose>
104108
<DialogAction

apps/dokploy/components/layouts/side.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ const MENU: Menu = {
247247
settings: [
248248
{
249249
isSingle: true,
250-
title: "Server",
250+
title: "Web Server",
251251
url: "/dashboard/settings/server",
252252
icon: Activity,
253253
// Only enabled for admins in non-cloud environments
@@ -262,7 +262,7 @@ const MENU: Menu = {
262262
},
263263
{
264264
isSingle: true,
265-
title: "Servers",
265+
title: "Remote Servers",
266266
url: "/dashboard/settings/servers",
267267
icon: Server,
268268
// Only enabled for admins

apps/dokploy/pages/dashboard/project/[projectId]/services/application/[applicationId].tsx

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ShowGeneralApplication } from "@/components/dashboard/application/gener
1313
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
1414
import { ShowPreviewDeployments } from "@/components/dashboard/application/preview-deployments/show-preview-deployments";
1515
import { UpdateApplication } from "@/components/dashboard/application/update-application";
16+
import { DeleteService } from "@/components/dashboard/compose/delete-service";
1617
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
1718
import { ProjectLayout } from "@/components/layouts/project-layout";
1819
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
@@ -82,8 +83,6 @@ const Service = (
8283
},
8384
);
8485

85-
const { mutateAsync, isLoading: isRemoving } =
86-
api.application.delete.useMutation();
8786
const { data: auth } = api.auth.get.useQuery();
8887
const { data: user } = api.user.byAuthId.useQuery(
8988
{
@@ -177,34 +176,7 @@ const Service = (
177176
<div className="flex flex-row gap-2 justify-end">
178177
<UpdateApplication applicationId={applicationId} />
179178
{(auth?.rol === "admin" || user?.canDeleteServices) && (
180-
<DialogAction
181-
title="Delete Application"
182-
description="Are you sure you want to delete this application?"
183-
type="destructive"
184-
onClick={async () => {
185-
await mutateAsync({
186-
applicationId: applicationId,
187-
})
188-
.then(() => {
189-
router.push(
190-
`/dashboard/project/${data?.projectId}`,
191-
);
192-
toast.success("Application deleted successfully");
193-
})
194-
.catch(() => {
195-
toast.error("Error deleting application");
196-
});
197-
}}
198-
>
199-
<Button
200-
variant="ghost"
201-
size="icon"
202-
className="group hover:bg-red-500/10 "
203-
isLoading={isRemoving}
204-
>
205-
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
206-
</Button>
207-
</DialogAction>
179+
<DeleteService id={applicationId} type="application" />
208180
)}
209181
</div>
210182
</div>

apps/dokploy/pages/dashboard/project/[projectId]/services/compose/[composeId].tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
22
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
33
import { AddCommandCompose } from "@/components/dashboard/compose/advanced/add-command";
4-
import { DeleteCompose } from "@/components/dashboard/compose/delete-compose";
4+
import { DeleteService } from "@/components/dashboard/compose/delete-service";
55
import { ShowDeploymentsCompose } from "@/components/dashboard/compose/deployments/show-deployments-compose";
66
import { ShowDomainsCompose } from "@/components/dashboard/compose/domains/show-domains";
77
import { ShowGeneralCompose } from "@/components/dashboard/compose/general/show";
@@ -168,7 +168,7 @@ const Service = (
168168
<UpdateCompose composeId={composeId} />
169169

170170
{(auth?.rol === "admin" || user?.canDeleteServices) && (
171-
<DeleteCompose composeId={composeId} />
171+
<DeleteService id={composeId} type="compose" />
172172
)}
173173
</div>
174174
</div>

apps/dokploy/pages/dashboard/project/[projectId]/services/mariadb/[mariadbId].tsx

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
22
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
33
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
44
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
5+
import { DeleteService } from "@/components/dashboard/compose/delete-service";
56
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
67
import { ShowExternalMariadbCredentials } from "@/components/dashboard/mariadb/general/show-external-mariadb-credentials";
78
import { ShowGeneralMariadb } from "@/components/dashboard/mariadb/general/show-general-mariadb";
@@ -67,8 +68,7 @@ const Mariadb = (
6768
enabled: !!auth?.id && auth?.rol === "user",
6869
},
6970
);
70-
const { mutateAsync: remove, isLoading: isRemoving } =
71-
api.mariadb.remove.useMutation();
71+
7272
return (
7373
<div className="pb-10">
7474
<BreadcrumbSidebar
@@ -148,35 +148,10 @@ const Mariadb = (
148148
</TooltipProvider>
149149
)}
150150
</div>
151-
<div className="flex flex-row gap-2">
151+
<div className="flex flex-row gap-2 justify-end">
152152
<UpdateMariadb mariadbId={mariadbId} />
153153
{(auth?.rol === "admin" || user?.canDeleteServices) && (
154-
<DialogAction
155-
title="Remove Mariadb"
156-
description="Are you sure you want to delete this mariadb?"
157-
type="destructive"
158-
onClick={async () => {
159-
await remove({ mariadbId })
160-
.then(() => {
161-
router.push(
162-
`/dashboard/project/${data?.projectId}`,
163-
);
164-
toast.success("Mariadb deleted successfully");
165-
})
166-
.catch(() => {
167-
toast.error("Error deleting the mariadb");
168-
});
169-
}}
170-
>
171-
<Button
172-
variant="ghost"
173-
size="icon"
174-
className="group hover:bg-red-500/10 "
175-
isLoading={isRemoving}
176-
>
177-
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
178-
</Button>
179-
</DialogAction>
154+
<DeleteService id={mariadbId} type="mariadb" />
180155
)}
181156
</div>
182157
</div>

apps/dokploy/pages/dashboard/project/[projectId]/services/mongo/[mongoId].tsx

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
22
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
33
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
44
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
5+
import { DeleteService } from "@/components/dashboard/compose/delete-service";
56
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
67
import { ShowExternalMongoCredentials } from "@/components/dashboard/mongo/general/show-external-mongo-credentials";
78
import { ShowGeneralMongo } from "@/components/dashboard/mongo/general/show-general-mongo";
@@ -69,8 +70,6 @@ const Mongo = (
6970
enabled: !!auth?.id && auth?.rol === "user",
7071
},
7172
);
72-
const { mutateAsync: remove, isLoading: isRemoving } =
73-
api.mongo.remove.useMutation();
7473

7574
return (
7675
<div className="pb-10">
@@ -155,32 +154,7 @@ const Mongo = (
155154
<div className="flex flex-row gap-2 justify-end">
156155
<UpdateMongo mongoId={mongoId} />
157156
{(auth?.rol === "admin" || user?.canDeleteServices) && (
158-
<DialogAction
159-
title="Remove mongo"
160-
description="Are you sure you want to delete this mongo?"
161-
type="destructive"
162-
onClick={async () => {
163-
await remove({ mongoId })
164-
.then(() => {
165-
router.push(
166-
`/dashboard/project/${data?.projectId}`,
167-
);
168-
toast.success("Mongo deleted successfully");
169-
})
170-
.catch(() => {
171-
toast.error("Error deleting the mongo");
172-
});
173-
}}
174-
>
175-
<Button
176-
variant="ghost"
177-
size="icon"
178-
className="group hover:bg-red-500/10 "
179-
isLoading={isRemoving}
180-
>
181-
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
182-
</Button>
183-
</DialogAction>
157+
<DeleteService id={mongoId} type="mongo" />
184158
)}
185159
</div>
186160
</div>

0 commit comments

Comments
 (0)