mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
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
This commit is contained in:
commit
46ddaa68fa
@ -98,8 +98,12 @@ export const ShowDomains = ({ applicationId }: Props) => {
|
||||
applicationId={applicationId}
|
||||
domainId={item.domainId}
|
||||
>
|
||||
<Button variant="ghost">
|
||||
<PenBoxIcon className="size-4 text-muted-foreground" />
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-blue-500/10 "
|
||||
>
|
||||
<PenBoxIcon className="size-3.5 text-primary group-hover:text-blue-500" />
|
||||
</Button>
|
||||
</AddDomain>
|
||||
<DialogAction
|
||||
|
@ -20,9 +20,10 @@ 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 { TrashIcon } from "lucide-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
@ -39,16 +40,42 @@ const deleteComposeSchema = z.object({
|
||||
type DeleteCompose = z.infer<typeof deleteComposeSchema>;
|
||||
|
||||
interface Props {
|
||||
composeId: string;
|
||||
id: string;
|
||||
type: ServiceType | "application";
|
||||
}
|
||||
|
||||
export const DeleteCompose = ({ composeId }: Props) => {
|
||||
export const DeleteService = ({ id, type }: Props) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const { mutateAsync, isLoading } = api.compose.delete.useMutation();
|
||||
const { data } = api.compose.one.useQuery(
|
||||
{ composeId },
|
||||
{ enabled: !!composeId },
|
||||
);
|
||||
|
||||
const queryMap = {
|
||||
postgres: () =>
|
||||
api.postgres.one.useQuery({ postgresId: id }, { enabled: !!id }),
|
||||
redis: () => api.redis.one.useQuery({ redisId: id }, { enabled: !!id }),
|
||||
mysql: () => api.mysql.one.useQuery({ mysqlId: id }, { enabled: !!id }),
|
||||
mariadb: () =>
|
||||
api.mariadb.one.useQuery({ mariadbId: id }, { enabled: !!id }),
|
||||
application: () =>
|
||||
api.application.one.useQuery({ applicationId: id }, { enabled: !!id }),
|
||||
mongo: () => api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id }),
|
||||
compose: () =>
|
||||
api.compose.one.useQuery({ composeId: id }, { enabled: !!id }),
|
||||
};
|
||||
const { data, refetch } = queryMap[type]
|
||||
? queryMap[type]()
|
||||
: api.mongo.one.useQuery({ mongoId: id }, { enabled: !!id });
|
||||
|
||||
const mutationMap = {
|
||||
postgres: () => api.postgres.remove.useMutation(),
|
||||
redis: () => api.redis.remove.useMutation(),
|
||||
mysql: () => api.mysql.remove.useMutation(),
|
||||
mariadb: () => api.mariadb.remove.useMutation(),
|
||||
application: () => api.application.delete.useMutation(),
|
||||
mongo: () => api.mongo.remove.useMutation(),
|
||||
compose: () => api.compose.delete.useMutation(),
|
||||
};
|
||||
const { mutateAsync, isLoading } = mutationMap[type]
|
||||
? mutationMap[type]()
|
||||
: api.mongo.remove.useMutation();
|
||||
const { push } = useRouter();
|
||||
const form = useForm<DeleteCompose>({
|
||||
defaultValues: {
|
||||
@ -62,14 +89,23 @@ export const DeleteCompose = ({ composeId }: Props) => {
|
||||
const expectedName = `${data?.name}/${data?.appName}`;
|
||||
if (formData.projectName === expectedName) {
|
||||
const { deleteVolumes } = formData;
|
||||
await mutateAsync({ composeId, deleteVolumes })
|
||||
await mutateAsync({
|
||||
mongoId: id || "",
|
||||
postgresId: id || "",
|
||||
redisId: id || "",
|
||||
mysqlId: id || "",
|
||||
mariadbId: id || "",
|
||||
applicationId: id || "",
|
||||
composeId: id || "",
|
||||
deleteVolumes,
|
||||
})
|
||||
.then((result) => {
|
||||
push(`/dashboard/project/${result?.projectId}`);
|
||||
toast.success("Compose deleted successfully");
|
||||
toast.success("deleted successfully");
|
||||
setIsOpen(false);
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the compose");
|
||||
toast.error("Error deleting the service");
|
||||
});
|
||||
} else {
|
||||
form.setError("projectName", {
|
||||
@ -95,8 +131,8 @@ export const DeleteCompose = ({ composeId }: Props) => {
|
||||
<DialogTitle>Are you absolutely sure?</DialogTitle>
|
||||
<DialogDescription>
|
||||
This action cannot be undone. This will permanently delete the
|
||||
compose. If you are sure please enter the compose name to delete
|
||||
this compose.
|
||||
service. If you are sure please enter the service name to delete
|
||||
this service.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="grid gap-4">
|
||||
@ -119,9 +155,7 @@ export const DeleteCompose = ({ composeId }: Props) => {
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
if (data?.name && data?.appName) {
|
||||
navigator.clipboard.writeText(
|
||||
`${data.name}/${data.appName}`,
|
||||
);
|
||||
copy(`${data.name}/${data.appName}`);
|
||||
toast.success("Copied to clipboard. Be careful!");
|
||||
}
|
||||
}}
|
||||
@ -142,27 +176,29 @@ export const DeleteCompose = ({ composeId }: Props) => {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="deleteVolumes"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<div className="flex items-center">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
{type === "compose" && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="deleteVolumes"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<div className="flex items-center">
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormLabel className="ml-2">
|
||||
Delete volumes associated with this compose
|
||||
</FormLabel>
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormLabel className="ml-2">
|
||||
Delete volumes associated with this compose
|
||||
</FormLabel>
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
@ -97,8 +97,12 @@ export const ShowDomainsCompose = ({ composeId }: Props) => {
|
||||
composeId={composeId}
|
||||
domainId={item.domainId}
|
||||
>
|
||||
<Button variant="ghost">
|
||||
<PenBoxIcon className="size-4 text-muted-foreground" />
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-blue-500/10 "
|
||||
>
|
||||
<PenBoxIcon className="size-3.5 text-primary group-hover:text-blue-500" />
|
||||
</Button>
|
||||
</AddDomainCompose>
|
||||
<DialogAction
|
||||
|
@ -247,7 +247,7 @@ const MENU: Menu = {
|
||||
settings: [
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Server",
|
||||
title: "Web Server",
|
||||
url: "/dashboard/settings/server",
|
||||
icon: Activity,
|
||||
// Only enabled for admins in non-cloud environments
|
||||
@ -262,7 +262,7 @@ const MENU: Menu = {
|
||||
},
|
||||
{
|
||||
isSingle: true,
|
||||
title: "Servers",
|
||||
title: "Remote Servers",
|
||||
url: "/dashboard/settings/servers",
|
||||
icon: Server,
|
||||
// Only enabled for admins
|
||||
|
@ -13,6 +13,7 @@ import { ShowGeneralApplication } from "@/components/dashboard/application/gener
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { ShowPreviewDeployments } from "@/components/dashboard/application/preview-deployments/show-preview-deployments";
|
||||
import { UpdateApplication } from "@/components/dashboard/application/update-application";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
|
||||
import { ProjectLayout } from "@/components/layouts/project-layout";
|
||||
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
||||
@ -82,8 +83,6 @@ const Service = (
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync, isLoading: isRemoving } =
|
||||
api.application.delete.useMutation();
|
||||
const { data: auth } = api.auth.get.useQuery();
|
||||
const { data: user } = api.user.byAuthId.useQuery(
|
||||
{
|
||||
@ -177,34 +176,7 @@ const Service = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateApplication applicationId={applicationId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Delete Application"
|
||||
description="Are you sure you want to delete this application?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await mutateAsync({
|
||||
applicationId: applicationId,
|
||||
})
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Application deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting application");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={applicationId} type="application" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { AddCommandCompose } from "@/components/dashboard/compose/advanced/add-command";
|
||||
import { DeleteCompose } from "@/components/dashboard/compose/delete-compose";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { ShowDeploymentsCompose } from "@/components/dashboard/compose/deployments/show-deployments-compose";
|
||||
import { ShowDomainsCompose } from "@/components/dashboard/compose/domains/show-domains";
|
||||
import { ShowGeneralCompose } from "@/components/dashboard/compose/general/show";
|
||||
@ -168,7 +168,7 @@ const Service = (
|
||||
<UpdateCompose composeId={composeId} />
|
||||
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DeleteCompose composeId={composeId} />
|
||||
<DeleteService id={composeId} type="compose" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
|
||||
import { ShowExternalMariadbCredentials } from "@/components/dashboard/mariadb/general/show-external-mariadb-credentials";
|
||||
import { ShowGeneralMariadb } from "@/components/dashboard/mariadb/general/show-general-mariadb";
|
||||
@ -67,8 +68,7 @@ const Mariadb = (
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
},
|
||||
);
|
||||
const { mutateAsync: remove, isLoading: isRemoving } =
|
||||
api.mariadb.remove.useMutation();
|
||||
|
||||
return (
|
||||
<div className="pb-10">
|
||||
<BreadcrumbSidebar
|
||||
@ -148,35 +148,10 @@ const Mariadb = (
|
||||
</TooltipProvider>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-row gap-2">
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMariadb mariadbId={mariadbId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Remove Mariadb"
|
||||
description="Are you sure you want to delete this mariadb?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await remove({ mariadbId })
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Mariadb deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the mariadb");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={mariadbId} type="mariadb" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
|
||||
import { ShowExternalMongoCredentials } from "@/components/dashboard/mongo/general/show-external-mongo-credentials";
|
||||
import { ShowGeneralMongo } from "@/components/dashboard/mongo/general/show-general-mongo";
|
||||
@ -69,8 +70,6 @@ const Mongo = (
|
||||
enabled: !!auth?.id && auth?.rol === "user",
|
||||
},
|
||||
);
|
||||
const { mutateAsync: remove, isLoading: isRemoving } =
|
||||
api.mongo.remove.useMutation();
|
||||
|
||||
return (
|
||||
<div className="pb-10">
|
||||
@ -155,32 +154,7 @@ const Mongo = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMongo mongoId={mongoId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Remove mongo"
|
||||
description="Are you sure you want to delete this mongo?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await remove({ mongoId })
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Mongo deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the mongo");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={mongoId} type="mongo" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
|
||||
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
|
||||
import { ShowExternalMysqlCredentials } from "@/components/dashboard/mysql/general/show-external-mysql-credentials";
|
||||
@ -68,8 +69,6 @@ const MySql = (
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync: remove, isLoading: isRemoving } =
|
||||
api.mysql.remove.useMutation();
|
||||
return (
|
||||
<div className="pb-10">
|
||||
<BreadcrumbSidebar
|
||||
@ -154,32 +153,7 @@ const MySql = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateMysql mysqlId={mysqlId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Remove Mysql"
|
||||
description="Are you sure you want to delete this mysql?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await remove({ mysqlId })
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Mysql deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the mysql");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={mysqlId} type="mysql" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { ShowBackups } from "@/components/dashboard/database/backups/show-backups";
|
||||
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
|
||||
import { ShowCustomCommand } from "@/components/dashboard/postgres/advanced/show-custom-command";
|
||||
@ -70,9 +71,6 @@ const Postgresql = (
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync: remove, isLoading: isRemoving } =
|
||||
api.postgres.remove.useMutation();
|
||||
|
||||
return (
|
||||
<div className="pb-10">
|
||||
<BreadcrumbSidebar
|
||||
@ -156,32 +154,7 @@ const Postgresql = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdatePostgres postgresId={postgresId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Remove Postgres"
|
||||
description="Are you sure you want to delete this postgres?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await remove({ postgresId })
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Postgres deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the postgres");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={postgresId} type="postgres" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@ import { ShowResources } from "@/components/dashboard/application/advanced/show-
|
||||
import { ShowVolumes } from "@/components/dashboard/application/advanced/volumes/show-volumes";
|
||||
import { ShowEnvironment } from "@/components/dashboard/application/environment/show-enviroment";
|
||||
import { ShowDockerLogs } from "@/components/dashboard/application/logs/show";
|
||||
import { DeleteService } from "@/components/dashboard/compose/delete-service";
|
||||
import { DockerMonitoring } from "@/components/dashboard/monitoring/docker/show";
|
||||
import { ShowCustomCommand } from "@/components/dashboard/postgres/advanced/show-custom-command";
|
||||
import { ShowExternalRedisCredentials } from "@/components/dashboard/redis/general/show-external-redis-credentials";
|
||||
@ -68,8 +69,6 @@ const Redis = (
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync: remove, isLoading: isRemoving } =
|
||||
api.redis.remove.useMutation();
|
||||
return (
|
||||
<div className="pb-10">
|
||||
<BreadcrumbSidebar
|
||||
@ -153,32 +152,7 @@ const Redis = (
|
||||
<div className="flex flex-row gap-2 justify-end">
|
||||
<UpdateRedis redisId={redisId} />
|
||||
{(auth?.rol === "admin" || user?.canDeleteServices) && (
|
||||
<DialogAction
|
||||
title="Remove Redis"
|
||||
description="Are you sure you want to delete this redis?"
|
||||
type="destructive"
|
||||
onClick={async () => {
|
||||
await remove({ redisId })
|
||||
.then(() => {
|
||||
router.push(
|
||||
`/dashboard/project/${data?.projectId}`,
|
||||
);
|
||||
toast.success("Redis deleted successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error deleting the redis");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group hover:bg-red-500/10 "
|
||||
isLoading={isRemoving}
|
||||
>
|
||||
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
||||
</Button>
|
||||
</DialogAction>
|
||||
<DeleteService id={redisId} type="redis" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user