mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-08 07:25:22 +02:00
feat(multi-server): add actions to the server
This commit is contained in:
@@ -49,13 +49,7 @@ export const SetupServer = ({ serverId }: Props) => {
|
||||
},
|
||||
);
|
||||
|
||||
const { mutateAsync, isLoading } = api.server.setup.useMutation({
|
||||
onMutate: async (variables) => {
|
||||
console.log("Running....");
|
||||
refetch();
|
||||
// refetch();
|
||||
},
|
||||
});
|
||||
const { mutateAsync, isLoading } = api.server.setup.useMutation();
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
@@ -99,7 +93,7 @@ export const SetupServer = ({ serverId }: Props) => {
|
||||
serverId: server?.serverId || "",
|
||||
})
|
||||
.then(async () => {
|
||||
// refetch();
|
||||
refetch();
|
||||
toast.success("Server setup successfully");
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
@@ -26,11 +27,45 @@ import { TerminalModal } from "../web-server/terminal-modal";
|
||||
import { AddServer } from "./add-server";
|
||||
import { SetupServer } from "./setup-server";
|
||||
import { UpdateServer } from "./update-server";
|
||||
import { ShowTraefikFileSystemModal } from "./show-traefik-file-system-modal";
|
||||
import { ShowModalLogs } from "../web-server/show-modal-logs";
|
||||
export const ShowServers = () => {
|
||||
const { data, refetch } = api.server.all.useQuery();
|
||||
const { mutateAsync } = api.server.remove.useMutation();
|
||||
const { data: sshKeys } = api.sshKey.all.useQuery();
|
||||
|
||||
const { mutateAsync: toggleDashboard, isLoading: toggleDashboardIsLoading } =
|
||||
api.settings.toggleDashboard.useMutation();
|
||||
|
||||
const {
|
||||
mutateAsync: cleanDockerBuilder,
|
||||
isLoading: cleanDockerBuilderIsLoading,
|
||||
} = api.settings.cleanDockerBuilder.useMutation();
|
||||
|
||||
const {
|
||||
mutateAsync: cleanUnusedImages,
|
||||
isLoading: cleanUnusedImagesIsLoading,
|
||||
} = api.settings.cleanUnusedImages.useMutation();
|
||||
|
||||
const { mutateAsync: reloadTraefik, isLoading: reloadTraefikIsLoading } =
|
||||
api.settings.reloadTraefik.useMutation();
|
||||
|
||||
const {
|
||||
mutateAsync: cleanUnusedVolumes,
|
||||
isLoading: cleanUnusedVolumesIsLoading,
|
||||
} = api.settings.cleanUnusedVolumes.useMutation();
|
||||
|
||||
const {
|
||||
mutateAsync: cleanStoppedContainers,
|
||||
isLoading: cleanStoppedContainersIsLoading,
|
||||
} = api.settings.cleanStoppedContainers.useMutation();
|
||||
|
||||
const { mutateAsync: cleanAll, isLoading: cleanAllIsLoading } =
|
||||
api.settings.cleanAll.useMutation();
|
||||
|
||||
const { data: haveTraefikDashboardPortEnabled, refetch: refetchDashboard } =
|
||||
api.settings.haveTraefikDashboardPortEnabled.useQuery();
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="space-y-2 flex flex-row justify-between items-end">
|
||||
@@ -116,7 +151,17 @@ export const ShowServers = () => {
|
||||
|
||||
<TableCell className="text-right flex justify-end">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<DropdownMenuTrigger
|
||||
asChild
|
||||
disabled={
|
||||
cleanAllIsLoading ||
|
||||
cleanDockerBuilderIsLoading ||
|
||||
cleanUnusedImagesIsLoading ||
|
||||
cleanUnusedVolumesIsLoading ||
|
||||
cleanStoppedContainersIsLoading ||
|
||||
reloadTraefikIsLoading
|
||||
}
|
||||
>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
@@ -128,6 +173,7 @@ export const ShowServers = () => {
|
||||
<span>Enter the terminal</span>
|
||||
</TerminalModal>
|
||||
<SetupServer serverId={server.serverId} />
|
||||
|
||||
<UpdateServer serverId={server.serverId} />
|
||||
<DialogAction
|
||||
title={"Delete Server"}
|
||||
@@ -154,6 +200,150 @@ export const ShowServers = () => {
|
||||
Delete Server
|
||||
</DropdownMenuItem>
|
||||
</DialogAction>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuLabel>Traefik</DropdownMenuLabel>
|
||||
<DropdownMenuItem
|
||||
onClick={async () => {
|
||||
await reloadTraefik({
|
||||
serverId: server.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Traefik Reloaded");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to reload the traefik");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Reload</span>
|
||||
</DropdownMenuItem>
|
||||
<ShowTraefikFileSystemModal
|
||||
serverId={server.serverId}
|
||||
/>
|
||||
<ShowModalLogs
|
||||
appName="dokploy-traefik"
|
||||
serverId={server.serverId}
|
||||
>
|
||||
<span>Watch logs</span>
|
||||
</ShowModalLogs>
|
||||
|
||||
{/* <DropdownMenuItem
|
||||
onClick={async () => {
|
||||
await toggleDashboard({
|
||||
enableDashboard:
|
||||
!haveTraefikDashboardPortEnabled,
|
||||
serverId: server.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success(
|
||||
`${haveTraefikDashboardPortEnabled ? "Disabled" : "Enabled"} Dashboard`,
|
||||
);
|
||||
refetchDashboard();
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error(
|
||||
`${haveTraefikDashboardPortEnabled ? "Disabled" : "Enabled"} Dashboard`,
|
||||
);
|
||||
});
|
||||
}}
|
||||
className="w-full cursor-pointer space-x-3"
|
||||
>
|
||||
<span>
|
||||
{haveTraefikDashboardPortEnabled
|
||||
? "Disable"
|
||||
: "Enable"}{" "}
|
||||
Dashboard
|
||||
</span>
|
||||
</DropdownMenuItem> */}
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuLabel>Storage</DropdownMenuLabel>
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onClick={async () => {
|
||||
await cleanUnusedImages({
|
||||
serverId: server?.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Cleaned images");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to clean images");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Clean unused images</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onClick={async () => {
|
||||
await cleanUnusedVolumes({
|
||||
serverId: server?.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Cleaned volumes");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to clean volumes");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Clean unused volumes</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onClick={async () => {
|
||||
await cleanStoppedContainers({
|
||||
serverId: server?.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Stopped containers cleaned");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error(
|
||||
"Error to clean stopped containers",
|
||||
);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Clean stopped containers</span>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onClick={async () => {
|
||||
await cleanDockerBuilder({
|
||||
serverId: server?.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Cleaned Docker Builder");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error(
|
||||
"Error to clean Docker Builder",
|
||||
);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Clean Docker Builder & System</span>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer"
|
||||
onClick={async () => {
|
||||
await cleanAll({
|
||||
serverId: server?.serverId,
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Cleaned all");
|
||||
})
|
||||
.catch(() => {
|
||||
toast.error("Error to clean all");
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span>Clean all</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
|
||||
import { FileTextIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { ShowTraefikSystem } from "../../file-system/show-traefik-system";
|
||||
|
||||
interface Props {
|
||||
serverId: string;
|
||||
}
|
||||
|
||||
export const ShowTraefikFileSystemModal = ({ serverId }: Props) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<DropdownMenuItem
|
||||
className="w-full cursor-pointer "
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
>
|
||||
Show Traefik File System
|
||||
</DropdownMenuItem>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-7xl overflow-y-auto max-h-screen ">
|
||||
<DialogHeader>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<FileTextIcon className="size-5" /> Traefik File System
|
||||
</DialogTitle>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
See all the files and directories of your traefik configuration
|
||||
</p>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
<div id="hook-form-add-gitlab" className="grid w-full gap-1">
|
||||
<ShowTraefikSystem serverId={serverId} />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -33,12 +33,15 @@ type Schema = z.infer<typeof schema>;
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
export const EditTraefikEnv = ({ children }: Props) => {
|
||||
export const EditTraefikEnv = ({ children, serverId }: Props) => {
|
||||
const [canEdit, setCanEdit] = useState(true);
|
||||
|
||||
const { data } = api.settings.readTraefikEnv.useQuery();
|
||||
const { data } = api.settings.readTraefikEnv.useQuery({
|
||||
serverId,
|
||||
});
|
||||
|
||||
const { mutateAsync, isLoading, error, isError } =
|
||||
api.settings.writeTraefikEnv.useMutation();
|
||||
|
||||
@@ -36,12 +36,14 @@ export const DockerLogsId = dynamic(
|
||||
interface Props {
|
||||
appName: string;
|
||||
children?: React.ReactNode;
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
export const ShowModalLogs = ({ appName, children }: Props) => {
|
||||
export const ShowModalLogs = ({ appName, children, serverId }: Props) => {
|
||||
const { data, isLoading } = api.docker.getContainersByAppLabel.useQuery(
|
||||
{
|
||||
appName,
|
||||
serverId,
|
||||
},
|
||||
{
|
||||
enabled: !!appName,
|
||||
@@ -96,7 +98,11 @@ export const ShowModalLogs = ({ appName, children }: Props) => {
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<DockerLogsId id="terminal" containerId={containerId || ""} />
|
||||
<DockerLogsId
|
||||
id="terminal"
|
||||
containerId={containerId || ""}
|
||||
serverId={serverId}
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user