mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-27 00:35:22 +02:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff20bb2731 | ||
|
|
8a802b0739 | ||
|
|
e511173283 | ||
|
|
763b1a344a | ||
|
|
a4041185f1 | ||
|
|
522dcd6c08 | ||
|
|
b4d5935875 | ||
|
|
6d9a1db8af | ||
|
|
e3979d2c48 |
@@ -7,6 +7,7 @@ import { useState } from "react";
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
@@ -114,6 +115,12 @@ export const DeleteService = ({ id, type }: Props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isDisabled =
|
||||||
|
(data &&
|
||||||
|
"applicationStatus" in data &&
|
||||||
|
data?.applicationStatus === "running") ||
|
||||||
|
(data && "composeStatus" in data && data?.composeStatus === "running");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
@@ -202,6 +209,12 @@ export const DeleteService = ({ id, type }: Props) => {
|
|||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
{isDisabled && (
|
||||||
|
<AlertBlock type="warning" className="w-full mt-5">
|
||||||
|
Cannot delete the service while it is running. Please wait for the
|
||||||
|
build to finish and then try again.
|
||||||
|
</AlertBlock>
|
||||||
|
)}
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -211,8 +224,10 @@ export const DeleteService = ({ id, type }: Props) => {
|
|||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
disabled={isDisabled}
|
||||||
form="hook-form-delete-compose"
|
form="hook-form-delete-compose"
|
||||||
type="submit"
|
type="submit"
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
|
|||||||
@@ -129,10 +129,11 @@ const DialogContent = React.forwardRef<
|
|||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed left-[50%] top-[50%] z-50 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
"fixed left-[50%] top-[50%] z-50 pointer-events-auto w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
"flex flex-col max-h-[90vh]",
|
"flex flex-col max-h-[90vh]",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
style={{ pointerEvents: "auto" }}
|
||||||
onInteractOutside={(event) => event.preventDefault()}
|
onInteractOutside={(event) => event.preventDefault()}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ const SidebarProvider = React.forwardRef<
|
|||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}
|
}
|
||||||
className={cn(
|
className={cn(
|
||||||
"group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",
|
"group/sidebar-wrapper flex h-svh w-full has-[[data-variant=inset]]:bg-sidebar",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
@@ -329,10 +329,11 @@ const SidebarInset = React.forwardRef<
|
|||||||
<main
|
<main
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex min-h-svh overflow-auto w-full flex-col bg-background",
|
"relative flex min-h-svh overflow-auto w-full flex-col bg-background",
|
||||||
"peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
|
"peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
style={{ scrollbarGutter: "stable" }}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dokploy",
|
"name": "dokploy",
|
||||||
"version": "v0.24.11",
|
"version": "v0.24.12",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {
|
|||||||
RedisIcon,
|
RedisIcon,
|
||||||
} from "@/components/icons/data-tools-icons";
|
} from "@/components/icons/data-tools-icons";
|
||||||
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
import { DashboardLayout } from "@/components/layouts/dashboard-layout";
|
||||||
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
||||||
import { DateTooltip } from "@/components/shared/date-tooltip";
|
import { DateTooltip } from "@/components/shared/date-tooltip";
|
||||||
import { DialogAction } from "@/components/shared/dialog-action";
|
import { DialogAction } from "@/components/shared/dialog-action";
|
||||||
@@ -598,6 +599,13 @@ const Project = (
|
|||||||
return sortServices(filtered);
|
return sortServices(filtered);
|
||||||
}, [applications, searchQuery, selectedTypes, sortBy]);
|
}, [applications, searchQuery, selectedTypes, sortBy]);
|
||||||
|
|
||||||
|
const selectedServicesWithRunningStatus = useMemo(() => {
|
||||||
|
return filteredServices.filter(
|
||||||
|
(service) =>
|
||||||
|
selectedServices.includes(service.id) && service.status === "running",
|
||||||
|
);
|
||||||
|
}, [filteredServices, selectedServices]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<BreadcrumbSidebar
|
<BreadcrumbSidebar
|
||||||
@@ -740,8 +748,34 @@ const Project = (
|
|||||||
<>
|
<>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Delete Services"
|
title="Delete Services"
|
||||||
description={`Are you sure you want to delete ${selectedServices.length} services? This action cannot be undone.`}
|
description={
|
||||||
|
<div className="space-y-3">
|
||||||
|
<p>
|
||||||
|
Are you sure you want to delete{" "}
|
||||||
|
{selectedServices.length} services? This
|
||||||
|
action cannot be undone.
|
||||||
|
</p>
|
||||||
|
{selectedServicesWithRunningStatus.length >
|
||||||
|
0 && (
|
||||||
|
<AlertBlock type="warning">
|
||||||
|
Warning:{" "}
|
||||||
|
{
|
||||||
|
selectedServicesWithRunningStatus.length
|
||||||
|
}{" "}
|
||||||
|
of the selected services are currently
|
||||||
|
running. Please stop these services
|
||||||
|
first before deleting:{" "}
|
||||||
|
{selectedServicesWithRunningStatus
|
||||||
|
.map((s) => s.name)
|
||||||
|
.join(", ")}
|
||||||
|
</AlertBlock>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
type="destructive"
|
type="destructive"
|
||||||
|
disabled={
|
||||||
|
selectedServicesWithRunningStatus.length > 0
|
||||||
|
}
|
||||||
onClick={handleBulkDelete}
|
onClick={handleBulkDelete}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
Reference in New Issue
Block a user