mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: improve button structure and tooltip integration across dashboard components
- Refactored button components in the dashboard to enhance structure and readability. - Integrated tooltips directly within button elements for better user experience. - Updated tooltip descriptions for clarity across various database actions (Deploy, Reload, Start, Stop) for Redis, MySQL, PostgreSQL, and MariaDB. - Ensured consistent formatting and improved code maintainability.
This commit is contained in:
@@ -76,25 +76,27 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
Downloads the source code and performs a complete build
|
<p>
|
||||||
</p>
|
Downloads the source code and performs a complete build
|
||||||
</TooltipContent>
|
</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Reload Application"
|
title="Reload Application"
|
||||||
@@ -114,23 +116,25 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={isReloading}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isReloading}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Reload
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
</Button>
|
Reload
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Reload the application without rebuilding it</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Reload the application without rebuilding it</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Rebuild Application"
|
title="Rebuild Application"
|
||||||
@@ -149,25 +153,28 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Hammer className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Rebuild
|
<Hammer className="size-4 mr-1" />
|
||||||
</Button>
|
Rebuild
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
Only rebuilds the application without downloading new code
|
<p>
|
||||||
</p>
|
Only rebuilds the application without downloading new
|
||||||
</TooltipContent>
|
code
|
||||||
</TooltipPrimitive.Portal>
|
</p>
|
||||||
</Tooltip>
|
</TooltipContent>
|
||||||
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
|
|
||||||
{data?.applicationStatus === "idle" ? (
|
{data?.applicationStatus === "idle" ? (
|
||||||
@@ -188,26 +195,28 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={isStarting}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStarting}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Start
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
</Button>
|
Start
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
Start the application (requires a previous successful
|
<p>
|
||||||
build)
|
Start the application (requires a previous successful
|
||||||
</p>
|
build)
|
||||||
</TooltipContent>
|
</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
) : (
|
) : (
|
||||||
<DialogAction
|
<DialogAction
|
||||||
@@ -226,23 +235,25 @@ export const ShowGeneralApplication = ({ applicationId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="destructive"
|
||||||
<Button
|
isLoading={isStopping}
|
||||||
variant="destructive"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStopping}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Ban className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Stop
|
<Ban className="size-4 mr-1" />
|
||||||
</Button>
|
Stop
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Stop the currently running application</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Stop the currently running application</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|||||||
@@ -55,23 +55,25 @@ export const ComposeActions = ({ composeId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.composeStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.composeStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Downloads the source code and performs a complete build</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Downloads the source code and performs a complete build</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Reload Compose"
|
title="Reload Compose"
|
||||||
@@ -90,23 +92,25 @@ export const ComposeActions = ({ composeId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={data?.composeStatus === "running"}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.composeStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Reload
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
</Button>
|
Reload
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Reload the compose without rebuilding it</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Reload the compose without rebuilding it</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
{data?.composeType === "docker-compose" &&
|
{data?.composeType === "docker-compose" &&
|
||||||
data?.composeStatus === "idle" ? (
|
data?.composeStatus === "idle" ? (
|
||||||
@@ -127,25 +131,27 @@ export const ComposeActions = ({ composeId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={isStarting}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStarting}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Start
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
</Button>
|
Start
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
Start the compose (requires a previous successful build)
|
<p>
|
||||||
</p>
|
Start the compose (requires a previous successful build)
|
||||||
</TooltipContent>
|
</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
) : (
|
) : (
|
||||||
<DialogAction
|
<DialogAction
|
||||||
@@ -164,23 +170,25 @@ export const ComposeActions = ({ composeId }: Props) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="destructive"
|
||||||
<Button
|
isLoading={isStopping}
|
||||||
variant="destructive"
|
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStopping}
|
>
|
||||||
className="flex items-center gap-1.5 group focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Ban className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Stop
|
<Ban className="size-4 mr-1" />
|
||||||
</Button>
|
Stop
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Stop the currently running compose</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Stop the currently running compose</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|||||||
@@ -17,236 +17,252 @@ import { type LogLine, parseLogs } from "../../docker/logs/utils";
|
|||||||
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
mariadbId: string;
|
mariadbId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowGeneralMariadb = ({ mariadbId }: Props) => {
|
export const ShowGeneralMariadb = ({ mariadbId }: Props) => {
|
||||||
const { data, refetch } = api.mariadb.one.useQuery(
|
const { data, refetch } = api.mariadb.one.useQuery(
|
||||||
{
|
{
|
||||||
mariadbId,
|
mariadbId,
|
||||||
},
|
},
|
||||||
{ enabled: !!mariadbId }
|
{ enabled: !!mariadbId },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { mutateAsync: reload, isLoading: isReloading } =
|
const { mutateAsync: reload, isLoading: isReloading } =
|
||||||
api.mariadb.reload.useMutation();
|
api.mariadb.reload.useMutation();
|
||||||
|
|
||||||
const { mutateAsync: start, isLoading: isStarting } =
|
const { mutateAsync: start, isLoading: isStarting } =
|
||||||
api.mariadb.start.useMutation();
|
api.mariadb.start.useMutation();
|
||||||
|
|
||||||
const { mutateAsync: stop, isLoading: isStopping } =
|
const { mutateAsync: stop, isLoading: isStopping } =
|
||||||
api.mariadb.stop.useMutation();
|
api.mariadb.stop.useMutation();
|
||||||
|
|
||||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
||||||
const [isDeploying, setIsDeploying] = useState(false);
|
const [isDeploying, setIsDeploying] = useState(false);
|
||||||
api.mariadb.deployWithLogs.useSubscription(
|
api.mariadb.deployWithLogs.useSubscription(
|
||||||
{
|
{
|
||||||
mariadbId: mariadbId,
|
mariadbId: mariadbId,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: isDeploying,
|
enabled: isDeploying,
|
||||||
onData(log) {
|
onData(log) {
|
||||||
if (!isDrawerOpen) {
|
if (!isDrawerOpen) {
|
||||||
setIsDrawerOpen(true);
|
setIsDrawerOpen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log === "Deployment completed successfully!") {
|
if (log === "Deployment completed successfully!") {
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
}
|
}
|
||||||
const parsedLogs = parseLogs(log);
|
const parsedLogs = parseLogs(log);
|
||||||
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
console.error("Deployment logs error:", error);
|
console.error("Deployment logs error:", error);
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex w-full flex-col gap-5 ">
|
<div className="flex w-full flex-col gap-5 ">
|
||||||
<Card className="bg-background">
|
<Card className="bg-background">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-row gap-4 flex-wrap">
|
<CardContent className="flex flex-row gap-4 flex-wrap">
|
||||||
<TooltipProvider delayDuration={0}>
|
<TooltipProvider delayDuration={0}>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Deploy Mariadb"
|
title="Deploy Mariadb"
|
||||||
description="Are you sure you want to deploy this mariadb?"
|
description="Are you sure you want to deploy this mariadb?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setIsDeploying(true);
|
setIsDeploying(true);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
refetch();
|
refetch();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Downloads and sets up the MariaDB database</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Downloads and sets up the MariaDB database</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
</DialogAction>
|
</Tooltip>
|
||||||
<DialogAction
|
</Button>
|
||||||
title="Reload Mariadb"
|
</DialogAction>
|
||||||
description="Are you sure you want to reload this mariadb?"
|
</TooltipProvider>
|
||||||
type="default"
|
<TooltipProvider delayDuration={0}>
|
||||||
onClick={async () => {
|
<DialogAction
|
||||||
await reload({
|
title="Reload Mariadb"
|
||||||
mariadbId: mariadbId,
|
description="Are you sure you want to reload this mariadb?"
|
||||||
appName: data?.appName || "",
|
type="default"
|
||||||
})
|
onClick={async () => {
|
||||||
.then(() => {
|
await reload({
|
||||||
toast.success("Mariadb reloaded successfully");
|
mariadbId: mariadbId,
|
||||||
refetch();
|
appName: data?.appName || "",
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.then(() => {
|
||||||
toast.error("Error reloading Mariadb");
|
toast.success("Mariadb reloaded successfully");
|
||||||
});
|
refetch();
|
||||||
}}
|
})
|
||||||
>
|
.catch(() => {
|
||||||
<Tooltip>
|
toast.error("Error reloading Mariadb");
|
||||||
<TooltipTrigger asChild>
|
});
|
||||||
<Button
|
}}
|
||||||
variant="secondary"
|
>
|
||||||
isLoading={isReloading}
|
<Button
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
variant="secondary"
|
||||||
>
|
isLoading={isReloading}
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
Reload
|
>
|
||||||
</Button>
|
<Tooltip>
|
||||||
</TooltipTrigger>
|
<TooltipTrigger asChild>
|
||||||
<TooltipPrimitive.Portal>
|
<div className="flex items-center">
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
<p>Restart the MariaDB service without rebuilding</p>
|
Reload
|
||||||
</TooltipContent>
|
</div>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
</Tooltip>
|
<TooltipPrimitive.Portal>
|
||||||
</DialogAction>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
{data?.applicationStatus === "idle" ? (
|
<p>Restart the MariaDB service without rebuilding</p>
|
||||||
<DialogAction
|
</TooltipContent>
|
||||||
title="Start Mariadb"
|
</TooltipPrimitive.Portal>
|
||||||
description="Are you sure you want to start this mariadb?"
|
</Tooltip>
|
||||||
type="default"
|
</Button>
|
||||||
onClick={async () => {
|
</DialogAction>
|
||||||
await start({
|
</TooltipProvider>
|
||||||
mariadbId: mariadbId,
|
{data?.applicationStatus === "idle" ? (
|
||||||
})
|
<TooltipProvider delayDuration={0}>
|
||||||
.then(() => {
|
<DialogAction
|
||||||
toast.success("Mariadb started successfully");
|
title="Start Mariadb"
|
||||||
refetch();
|
description="Are you sure you want to start this mariadb?"
|
||||||
})
|
type="default"
|
||||||
.catch(() => {
|
onClick={async () => {
|
||||||
toast.error("Error starting Mariadb");
|
await start({
|
||||||
});
|
mariadbId: mariadbId,
|
||||||
}}
|
})
|
||||||
>
|
.then(() => {
|
||||||
<Tooltip>
|
toast.success("Mariadb started successfully");
|
||||||
<TooltipTrigger asChild>
|
refetch();
|
||||||
<Button
|
})
|
||||||
variant="secondary"
|
.catch(() => {
|
||||||
isLoading={isStarting}
|
toast.error("Error starting Mariadb");
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
});
|
||||||
>
|
}}
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
>
|
||||||
Start
|
<Button
|
||||||
</Button>
|
variant="secondary"
|
||||||
</TooltipTrigger>
|
isLoading={isStarting}
|
||||||
<TooltipPrimitive.Portal>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
>
|
||||||
<p>
|
<Tooltip>
|
||||||
Start the MariaDB database (requires a previous
|
<TooltipTrigger asChild>
|
||||||
successful setup)
|
<div className="flex items-center">
|
||||||
</p>
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
</TooltipContent>
|
Start
|
||||||
</TooltipPrimitive.Portal>
|
</div>
|
||||||
</Tooltip>
|
</TooltipTrigger>
|
||||||
</DialogAction>
|
<TooltipPrimitive.Portal>
|
||||||
) : (
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
<DialogAction
|
<p>
|
||||||
title="Stop Mariadb"
|
Start the MariaDB database (requires a previous
|
||||||
description="Are you sure you want to stop this mariadb?"
|
successful setup)
|
||||||
onClick={async () => {
|
</p>
|
||||||
await stop({
|
</TooltipContent>
|
||||||
mariadbId: mariadbId,
|
</TooltipPrimitive.Portal>
|
||||||
})
|
</Tooltip>
|
||||||
.then(() => {
|
</Button>
|
||||||
toast.success("Mariadb stopped successfully");
|
</DialogAction>
|
||||||
refetch();
|
</TooltipProvider>
|
||||||
})
|
) : (
|
||||||
.catch(() => {
|
<TooltipProvider delayDuration={0}>
|
||||||
toast.error("Error stopping Mariadb");
|
<DialogAction
|
||||||
});
|
title="Stop Mariadb"
|
||||||
}}
|
description="Are you sure you want to stop this mariadb?"
|
||||||
>
|
onClick={async () => {
|
||||||
<Tooltip>
|
await stop({
|
||||||
<TooltipTrigger asChild>
|
mariadbId: mariadbId,
|
||||||
<Button
|
})
|
||||||
variant="destructive"
|
.then(() => {
|
||||||
isLoading={isStopping}
|
toast.success("Mariadb stopped successfully");
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
refetch();
|
||||||
>
|
})
|
||||||
<Ban className="size-4 mr-1" />
|
.catch(() => {
|
||||||
Stop
|
toast.error("Error stopping Mariadb");
|
||||||
</Button>
|
});
|
||||||
</TooltipTrigger>
|
}}
|
||||||
<TooltipPrimitive.Portal>
|
>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<Button
|
||||||
<p>Stop the currently running MariaDB database</p>
|
variant="destructive"
|
||||||
</TooltipContent>
|
isLoading={isStopping}
|
||||||
</TooltipPrimitive.Portal>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
</Tooltip>
|
>
|
||||||
</DialogAction>
|
<Tooltip>
|
||||||
)}
|
<TooltipTrigger asChild>
|
||||||
</TooltipProvider>
|
<div className="flex items-center">
|
||||||
<DockerTerminalModal
|
<Ban className="size-4 mr-1" />
|
||||||
appName={data?.appName || ""}
|
Stop
|
||||||
serverId={data?.serverId || ""}
|
</div>
|
||||||
>
|
</TooltipTrigger>
|
||||||
<Tooltip>
|
<TooltipPrimitive.Portal>
|
||||||
<TooltipTrigger asChild>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
<Button
|
<p>Stop the currently running MariaDB database</p>
|
||||||
variant="outline"
|
</TooltipContent>
|
||||||
className="flex items-center gap-2 focus-visible:ring-2 focus-visible:ring-offset-2"
|
</TooltipPrimitive.Portal>
|
||||||
>
|
</Tooltip>
|
||||||
<Terminal className="size-4" />
|
</Button>
|
||||||
Open Terminal
|
</DialogAction>
|
||||||
</Button>
|
</TooltipProvider>
|
||||||
</TooltipTrigger>
|
)}
|
||||||
<TooltipPrimitive.Portal>
|
<DockerTerminalModal
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
appName={data?.appName || ""}
|
||||||
<p>Open a terminal to the MariaDB container</p>
|
serverId={data?.serverId || ""}
|
||||||
</TooltipContent>
|
>
|
||||||
</TooltipPrimitive.Portal>
|
<Button
|
||||||
</Tooltip>
|
variant="outline"
|
||||||
</DockerTerminalModal>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
</CardContent>
|
>
|
||||||
</Card>
|
<Tooltip>
|
||||||
<DrawerLogs
|
<TooltipTrigger asChild>
|
||||||
isOpen={isDrawerOpen}
|
<div className="flex items-center">
|
||||||
onClose={() => {
|
<Terminal className="size-4 mr-1" />
|
||||||
setIsDrawerOpen(false);
|
Open Terminal
|
||||||
setFilteredLogs([]);
|
</div>
|
||||||
setIsDeploying(false);
|
</TooltipTrigger>
|
||||||
refetch();
|
<TooltipPrimitive.Portal>
|
||||||
}}
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
filteredLogs={filteredLogs}
|
<p>Open a terminal to the MariaDB container</p>
|
||||||
/>
|
</TooltipContent>
|
||||||
</div>
|
</TooltipPrimitive.Portal>
|
||||||
</>
|
</Tooltip>
|
||||||
);
|
</Button>
|
||||||
|
</DockerTerminalModal>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<DrawerLogs
|
||||||
|
isOpen={isDrawerOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsDrawerOpen(false);
|
||||||
|
setFilteredLogs([]);
|
||||||
|
setIsDeploying(false);
|
||||||
|
refetch();
|
||||||
|
}}
|
||||||
|
filteredLogs={filteredLogs}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,234 +16,244 @@ import { toast } from "sonner";
|
|||||||
import { type LogLine, parseLogs } from "../../docker/logs/utils";
|
import { type LogLine, parseLogs } from "../../docker/logs/utils";
|
||||||
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
||||||
interface Props {
|
interface Props {
|
||||||
mysqlId: string;
|
mysqlId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowGeneralMysql = ({ mysqlId }: Props) => {
|
export const ShowGeneralMysql = ({ mysqlId }: Props) => {
|
||||||
const { data, refetch } = api.mysql.one.useQuery(
|
const { data, refetch } = api.mysql.one.useQuery(
|
||||||
{
|
{
|
||||||
mysqlId,
|
mysqlId,
|
||||||
},
|
},
|
||||||
{ enabled: !!mysqlId }
|
{ enabled: !!mysqlId },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { mutateAsync: reload, isLoading: isReloading } =
|
const { mutateAsync: reload, isLoading: isReloading } =
|
||||||
api.mysql.reload.useMutation();
|
api.mysql.reload.useMutation();
|
||||||
const { mutateAsync: start, isLoading: isStarting } =
|
const { mutateAsync: start, isLoading: isStarting } =
|
||||||
api.mysql.start.useMutation();
|
api.mysql.start.useMutation();
|
||||||
|
|
||||||
const { mutateAsync: stop, isLoading: isStopping } =
|
const { mutateAsync: stop, isLoading: isStopping } =
|
||||||
api.mysql.stop.useMutation();
|
api.mysql.stop.useMutation();
|
||||||
|
|
||||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
||||||
const [isDeploying, setIsDeploying] = useState(false);
|
const [isDeploying, setIsDeploying] = useState(false);
|
||||||
api.mysql.deployWithLogs.useSubscription(
|
api.mysql.deployWithLogs.useSubscription(
|
||||||
{
|
{
|
||||||
mysqlId: mysqlId,
|
mysqlId: mysqlId,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: isDeploying,
|
enabled: isDeploying,
|
||||||
onData(log) {
|
onData(log) {
|
||||||
if (!isDrawerOpen) {
|
if (!isDrawerOpen) {
|
||||||
setIsDrawerOpen(true);
|
setIsDrawerOpen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log === "Deployment completed successfully!") {
|
if (log === "Deployment completed successfully!") {
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
}
|
}
|
||||||
const parsedLogs = parseLogs(log);
|
const parsedLogs = parseLogs(log);
|
||||||
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
console.error("Deployment logs error:", error);
|
console.error("Deployment logs error:", error);
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex w-full flex-col gap-5 ">
|
<div className="flex w-full flex-col gap-5 ">
|
||||||
<Card className="bg-background">
|
<Card className="bg-background">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-row gap-4 flex-wrap">
|
<CardContent className="flex flex-row gap-4 flex-wrap">
|
||||||
<TooltipProvider delayDuration={0}>
|
<TooltipProvider delayDuration={0}>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Deploy Mysql"
|
title="Deploy MySQL"
|
||||||
description="Are you sure you want to deploy this mysql?"
|
description="Are you sure you want to deploy this mysql?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setIsDeploying(true);
|
setIsDeploying(true);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
refetch();
|
refetch();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Downloads and sets up the MySQL database</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Downloads and sets up the MySQL database</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
</DialogAction>
|
</Tooltip>
|
||||||
<DialogAction
|
</Button>
|
||||||
title="Reload Mysql"
|
</DialogAction>
|
||||||
description="Are you sure you want to reload this mysql?"
|
<DialogAction
|
||||||
type="default"
|
title="Reload MySQL"
|
||||||
onClick={async () => {
|
description="Are you sure you want to reload this mysql?"
|
||||||
await reload({
|
type="default"
|
||||||
mysqlId: mysqlId,
|
onClick={async () => {
|
||||||
appName: data?.appName || "",
|
await reload({
|
||||||
})
|
mysqlId: mysqlId,
|
||||||
.then(() => {
|
appName: data?.appName || "",
|
||||||
toast.success("Mysql reloaded successfully");
|
})
|
||||||
refetch();
|
.then(() => {
|
||||||
})
|
toast.success("MySQL reloaded successfully");
|
||||||
.catch(() => {
|
refetch();
|
||||||
toast.error("Error reloading Mysql");
|
})
|
||||||
});
|
.catch(() => {
|
||||||
}}
|
toast.error("Error reloading MySQL");
|
||||||
>
|
});
|
||||||
<Tooltip>
|
}}
|
||||||
<TooltipTrigger asChild>
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
isLoading={isReloading}
|
isLoading={isReloading}
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
>
|
>
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
<Tooltip>
|
||||||
Reload
|
<TooltipTrigger asChild>
|
||||||
</Button>
|
<div className="flex items-center">
|
||||||
</TooltipTrigger>
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
<TooltipPrimitive.Portal>
|
Reload
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
</div>
|
||||||
<p>Restart the MySQL service without rebuilding</p>
|
</TooltipTrigger>
|
||||||
</TooltipContent>
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipPrimitive.Portal>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</Tooltip>
|
<p>Restart the MySQL service without rebuilding</p>
|
||||||
</DialogAction>
|
</TooltipContent>
|
||||||
{data?.applicationStatus === "idle" ? (
|
</TooltipPrimitive.Portal>
|
||||||
<DialogAction
|
</Tooltip>
|
||||||
title="Start Mysql"
|
</Button>
|
||||||
description="Are you sure you want to start this mysql?"
|
</DialogAction>
|
||||||
type="default"
|
{data?.applicationStatus === "idle" ? (
|
||||||
onClick={async () => {
|
<DialogAction
|
||||||
await start({
|
title="Start MySQL"
|
||||||
mysqlId: mysqlId,
|
description="Are you sure you want to start this mysql?"
|
||||||
})
|
type="default"
|
||||||
.then(() => {
|
onClick={async () => {
|
||||||
toast.success("Mysql started successfully");
|
await start({
|
||||||
refetch();
|
mysqlId: mysqlId,
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.then(() => {
|
||||||
toast.error("Error starting Mysql");
|
toast.success("MySQL started successfully");
|
||||||
});
|
refetch();
|
||||||
}}
|
})
|
||||||
>
|
.catch(() => {
|
||||||
<Tooltip>
|
toast.error("Error starting MySQL");
|
||||||
<TooltipTrigger asChild>
|
});
|
||||||
<Button
|
}}
|
||||||
variant="secondary"
|
>
|
||||||
isLoading={isStarting}
|
<Button
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
variant="secondary"
|
||||||
>
|
isLoading={isStarting}
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
Start
|
>
|
||||||
</Button>
|
<Tooltip>
|
||||||
</TooltipTrigger>
|
<TooltipTrigger asChild>
|
||||||
<TooltipPrimitive.Portal>
|
<div className="flex items-center">
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
<p>
|
Start
|
||||||
Start the MySQL database (requires a previous
|
</div>
|
||||||
successful setup)
|
</TooltipTrigger>
|
||||||
</p>
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipContent>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipPrimitive.Portal>
|
<p>
|
||||||
</Tooltip>
|
Start the MySQL database (requires a previous
|
||||||
</DialogAction>
|
successful setup)
|
||||||
) : (
|
</p>
|
||||||
<DialogAction
|
</TooltipContent>
|
||||||
title="Stop Mysql"
|
</TooltipPrimitive.Portal>
|
||||||
description="Are you sure you want to stop this mysql?"
|
</Tooltip>
|
||||||
onClick={async () => {
|
</Button>
|
||||||
await stop({
|
</DialogAction>
|
||||||
mysqlId: mysqlId,
|
) : (
|
||||||
})
|
<DialogAction
|
||||||
.then(() => {
|
title="Stop MySQL"
|
||||||
toast.success("Mysql stopped successfully");
|
description="Are you sure you want to stop this mysql?"
|
||||||
refetch();
|
onClick={async () => {
|
||||||
})
|
await stop({
|
||||||
.catch(() => {
|
mysqlId: mysqlId,
|
||||||
toast.error("Error stopping Mysql");
|
})
|
||||||
});
|
.then(() => {
|
||||||
}}
|
toast.success("MySQL stopped successfully");
|
||||||
>
|
refetch();
|
||||||
<Tooltip>
|
})
|
||||||
<TooltipTrigger asChild>
|
.catch(() => {
|
||||||
<Button
|
toast.error("Error stopping MySQL");
|
||||||
variant="destructive"
|
});
|
||||||
isLoading={isStopping}
|
}}
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
>
|
||||||
>
|
<Button
|
||||||
<Ban className="size-4 mr-1" />
|
variant="destructive"
|
||||||
Stop
|
isLoading={isStopping}
|
||||||
</Button>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
</TooltipTrigger>
|
>
|
||||||
<TooltipPrimitive.Portal>
|
<Tooltip>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipTrigger asChild>
|
||||||
<p>Stop the currently running MySQL database</p>
|
<div className="flex items-center">
|
||||||
</TooltipContent>
|
<Ban className="size-4 mr-1" />
|
||||||
</TooltipPrimitive.Portal>
|
Stop
|
||||||
</Tooltip>
|
</div>
|
||||||
</DialogAction>
|
</TooltipTrigger>
|
||||||
)}
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipProvider>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
<DockerTerminalModal
|
<p>Stop the currently running MySQL database</p>
|
||||||
appName={data?.appName || ""}
|
</TooltipContent>
|
||||||
serverId={data?.serverId || ""}
|
</TooltipPrimitive.Portal>
|
||||||
>
|
</Tooltip>
|
||||||
<Tooltip>
|
</Button>
|
||||||
<TooltipTrigger asChild>
|
</DialogAction>
|
||||||
<Button
|
)}
|
||||||
variant="outline"
|
</TooltipProvider>
|
||||||
className="flex items-center gap-2 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<DockerTerminalModal
|
||||||
>
|
appName={data?.appName || ""}
|
||||||
<Terminal className="size-4" />
|
serverId={data?.serverId || ""}
|
||||||
Open Terminal
|
>
|
||||||
</Button>
|
<Button
|
||||||
</TooltipTrigger>
|
variant="outline"
|
||||||
<TooltipPrimitive.Portal>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
>
|
||||||
<p>Open a terminal to the MySQL container</p>
|
<Tooltip>
|
||||||
</TooltipContent>
|
<TooltipTrigger asChild>
|
||||||
</TooltipPrimitive.Portal>
|
<div className="flex items-center">
|
||||||
</Tooltip>
|
<Terminal className="size-4 mr-1" />
|
||||||
</DockerTerminalModal>
|
Open Terminal
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</TooltipTrigger>
|
||||||
<DrawerLogs
|
<TooltipPrimitive.Portal>
|
||||||
isOpen={isDrawerOpen}
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
onClose={() => {
|
<p>Open a terminal to the MySQL container</p>
|
||||||
setIsDrawerOpen(false);
|
</TooltipContent>
|
||||||
setFilteredLogs([]);
|
</TooltipPrimitive.Portal>
|
||||||
setIsDeploying(false);
|
</Tooltip>
|
||||||
refetch();
|
</Button>
|
||||||
}}
|
</DockerTerminalModal>
|
||||||
filteredLogs={filteredLogs}
|
</CardContent>
|
||||||
/>
|
</Card>
|
||||||
</div>
|
<DrawerLogs
|
||||||
</>
|
isOpen={isDrawerOpen}
|
||||||
);
|
onClose={() => {
|
||||||
|
setIsDrawerOpen(false);
|
||||||
|
setFilteredLogs([]);
|
||||||
|
setIsDeploying(false);
|
||||||
|
refetch();
|
||||||
|
}}
|
||||||
|
filteredLogs={filteredLogs}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const ShowGeneralPostgres = ({ postgresId }: Props) => {
|
|||||||
<CardContent className="flex flex-row gap-4 flex-wrap">
|
<CardContent className="flex flex-row gap-4 flex-wrap">
|
||||||
<TooltipProvider disableHoverableContent={false}>
|
<TooltipProvider disableHoverableContent={false}>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Deploy Postgres"
|
title="Deploy PostgreSQL"
|
||||||
description="Are you sure you want to deploy this postgres?"
|
description="Are you sure you want to deploy this postgres?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@@ -83,26 +83,28 @@ export const ShowGeneralPostgres = ({ postgresId }: Props) => {
|
|||||||
refetch();
|
refetch();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Downloads and sets up the PostgreSQL database</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Downloads and sets up the PostgreSQL database</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Reload Postgres"
|
title="Reload PostgreSQL"
|
||||||
description="Are you sure you want to reload this postgres?"
|
description="Are you sure you want to reload this postgres?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@@ -111,35 +113,37 @@ export const ShowGeneralPostgres = ({ postgresId }: Props) => {
|
|||||||
appName: data?.appName || "",
|
appName: data?.appName || "",
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("Postgres reloaded successfully");
|
toast.success("PostgreSQL reloaded successfully");
|
||||||
refetch();
|
refetch();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error reloading Postgres");
|
toast.error("Error reloading PostgreSQL");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={isReloading}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isReloading}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Reload
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
</Button>
|
Reload
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Reload the PostgreSQL without rebuilding it</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Restart the PostgreSQL service without rebuilding</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
{data?.applicationStatus === "idle" ? (
|
{data?.applicationStatus === "idle" ? (
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Start Postgres"
|
title="Start PostgreSQL"
|
||||||
description="Are you sure you want to start this postgres?"
|
description="Are you sure you want to start this postgres?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@@ -147,69 +151,73 @@ export const ShowGeneralPostgres = ({ postgresId }: Props) => {
|
|||||||
postgresId: postgresId,
|
postgresId: postgresId,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("Postgres started successfully");
|
toast.success("PostgreSQL started successfully");
|
||||||
refetch();
|
refetch();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error starting Postgres");
|
toast.error("Error starting PostgreSQL");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="secondary"
|
||||||
<Button
|
isLoading={isStarting}
|
||||||
variant="secondary"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStarting}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Start
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
</Button>
|
Start
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
Start the PostgreSQL database (requires a previous
|
<p>
|
||||||
successful setup)
|
Start the PostgreSQL database (requires a previous
|
||||||
</p>
|
successful setup)
|
||||||
</TooltipContent>
|
</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
) : (
|
) : (
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Stop Postgres"
|
title="Stop PostgreSQL"
|
||||||
description="Are you sure you want to stop this postgres?"
|
description="Are you sure you want to stop this postgres?"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await stop({
|
await stop({
|
||||||
postgresId: postgresId,
|
postgresId: postgresId,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("Postgres stopped successfully");
|
toast.success("PostgreSQL stopped successfully");
|
||||||
refetch();
|
refetch();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error stopping Postgres");
|
toast.error("Error stopping PostgreSQL");
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="destructive"
|
||||||
<Button
|
isLoading={isStopping}
|
||||||
variant="destructive"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={isStopping}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Ban className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Stop
|
<Ban className="size-4 mr-1" />
|
||||||
</Button>
|
Stop
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Stop the currently running PostgreSQL database</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Stop the currently running PostgreSQL database</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
</DialogAction>
|
</DialogAction>
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
@@ -221,8 +229,19 @@ export const ShowGeneralPostgres = ({ postgresId }: Props) => {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
>
|
>
|
||||||
<Terminal className="size-4 mr-1" />
|
<Tooltip>
|
||||||
Open Terminal
|
<TooltipTrigger asChild>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Terminal className="size-4 mr-1" />
|
||||||
|
Open Terminal
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipPrimitive.Portal>
|
||||||
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
|
<p>Open a terminal to the PostgreSQL container</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</TooltipPrimitive.Portal>
|
||||||
|
</Tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
</DockerTerminalModal>
|
</DockerTerminalModal>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -17,235 +17,245 @@ import { type LogLine, parseLogs } from "../../docker/logs/utils";
|
|||||||
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
redisId: string;
|
redisId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShowGeneralRedis = ({ redisId }: Props) => {
|
export const ShowGeneralRedis = ({ redisId }: Props) => {
|
||||||
const { data, refetch } = api.redis.one.useQuery(
|
const { data, refetch } = api.redis.one.useQuery(
|
||||||
{
|
{
|
||||||
redisId,
|
redisId,
|
||||||
},
|
},
|
||||||
{ enabled: !!redisId }
|
{ enabled: !!redisId },
|
||||||
);
|
);
|
||||||
|
|
||||||
const { mutateAsync: reload, isLoading: isReloading } =
|
const { mutateAsync: reload, isLoading: isReloading } =
|
||||||
api.redis.reload.useMutation();
|
api.redis.reload.useMutation();
|
||||||
const { mutateAsync: start, isLoading: isStarting } =
|
const { mutateAsync: start, isLoading: isStarting } =
|
||||||
api.redis.start.useMutation();
|
api.redis.start.useMutation();
|
||||||
|
|
||||||
const { mutateAsync: stop, isLoading: isStopping } =
|
const { mutateAsync: stop, isLoading: isStopping } =
|
||||||
api.redis.stop.useMutation();
|
api.redis.stop.useMutation();
|
||||||
|
|
||||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
const [filteredLogs, setFilteredLogs] = useState<LogLine[]>([]);
|
||||||
const [isDeploying, setIsDeploying] = useState(false);
|
const [isDeploying, setIsDeploying] = useState(false);
|
||||||
api.redis.deployWithLogs.useSubscription(
|
api.redis.deployWithLogs.useSubscription(
|
||||||
{
|
{
|
||||||
redisId: redisId,
|
redisId: redisId,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: isDeploying,
|
enabled: isDeploying,
|
||||||
onData(log) {
|
onData(log) {
|
||||||
if (!isDrawerOpen) {
|
if (!isDrawerOpen) {
|
||||||
setIsDrawerOpen(true);
|
setIsDrawerOpen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log === "Deployment completed successfully!") {
|
if (log === "Deployment completed successfully!") {
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
}
|
}
|
||||||
const parsedLogs = parseLogs(log);
|
const parsedLogs = parseLogs(log);
|
||||||
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
setFilteredLogs((prev) => [...prev, ...parsedLogs]);
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
console.error("Deployment logs error:", error);
|
console.error("Deployment logs error:", error);
|
||||||
setIsDeploying(false);
|
setIsDeploying(false);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex w-full flex-col gap-5 ">
|
<div className="flex w-full flex-col gap-5 ">
|
||||||
<Card className="bg-background">
|
<Card className="bg-background">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
<CardTitle className="text-xl">Deploy Settings</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-row gap-4 flex-wrap">
|
<CardContent className="flex flex-row gap-4 flex-wrap">
|
||||||
<TooltipProvider delayDuration={0}>
|
<TooltipProvider delayDuration={0}>
|
||||||
<DialogAction
|
<DialogAction
|
||||||
title="Deploy Redis"
|
title="Deploy Redis"
|
||||||
description="Are you sure you want to deploy this redis?"
|
description="Are you sure you want to deploy this redis?"
|
||||||
type="default"
|
type="default"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setIsDeploying(true);
|
setIsDeploying(true);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
refetch();
|
refetch();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip>
|
<Button
|
||||||
<TooltipTrigger asChild>
|
variant="default"
|
||||||
<Button
|
isLoading={data?.applicationStatus === "running"}
|
||||||
variant="default"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
isLoading={data?.applicationStatus === "running"}
|
>
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<Tooltip>
|
||||||
>
|
<TooltipTrigger asChild>
|
||||||
<Rocket className="size-4 mr-1" />
|
<div className="flex items-center">
|
||||||
Deploy
|
<Rocket className="size-4 mr-1" />
|
||||||
</Button>
|
Deploy
|
||||||
</TooltipTrigger>
|
</div>
|
||||||
<TooltipPrimitive.Portal>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipPrimitive.Portal>
|
||||||
<p>Downloads and sets up the Redis database</p>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipContent>
|
<p>Downloads and sets up the Redis database</p>
|
||||||
</TooltipPrimitive.Portal>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</TooltipPrimitive.Portal>
|
||||||
</DialogAction>
|
</Tooltip>
|
||||||
<DialogAction
|
</Button>
|
||||||
title="Reload Redis"
|
</DialogAction>
|
||||||
description="Are you sure you want to reload this redis?"
|
<DialogAction
|
||||||
type="default"
|
title="Reload Redis"
|
||||||
onClick={async () => {
|
description="Are you sure you want to reload this redis?"
|
||||||
await reload({
|
type="default"
|
||||||
redisId: redisId,
|
onClick={async () => {
|
||||||
appName: data?.appName || "",
|
await reload({
|
||||||
})
|
redisId: redisId,
|
||||||
.then(() => {
|
appName: data?.appName || "",
|
||||||
toast.success("Redis reloaded successfully");
|
})
|
||||||
refetch();
|
.then(() => {
|
||||||
})
|
toast.success("Redis reloaded successfully");
|
||||||
.catch(() => {
|
refetch();
|
||||||
toast.error("Error reloading Redis");
|
})
|
||||||
});
|
.catch(() => {
|
||||||
}}
|
toast.error("Error reloading Redis");
|
||||||
>
|
});
|
||||||
<Tooltip>
|
}}
|
||||||
<TooltipTrigger asChild>
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
isLoading={isReloading}
|
isLoading={isReloading}
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
>
|
>
|
||||||
<RefreshCcw className="size-4 mr-1" />
|
<Tooltip>
|
||||||
Reload
|
<TooltipTrigger asChild>
|
||||||
</Button>
|
<div className="flex items-center">
|
||||||
</TooltipTrigger>
|
<RefreshCcw className="size-4 mr-1" />
|
||||||
<TooltipPrimitive.Portal>
|
Reload
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
</div>
|
||||||
<p>Restart the Redis service without rebuilding</p>
|
</TooltipTrigger>
|
||||||
</TooltipContent>
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipPrimitive.Portal>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</Tooltip>
|
<p>Restart the Redis service without rebuilding</p>
|
||||||
</DialogAction>
|
</TooltipContent>
|
||||||
{data?.applicationStatus === "idle" ? (
|
</TooltipPrimitive.Portal>
|
||||||
<DialogAction
|
</Tooltip>
|
||||||
title="Start Redis"
|
</Button>
|
||||||
description="Are you sure you want to start this redis?"
|
</DialogAction>
|
||||||
type="default"
|
{data?.applicationStatus === "idle" ? (
|
||||||
onClick={async () => {
|
<DialogAction
|
||||||
await start({
|
title="Start Redis"
|
||||||
redisId: redisId,
|
description="Are you sure you want to start this redis?"
|
||||||
})
|
type="default"
|
||||||
.then(() => {
|
onClick={async () => {
|
||||||
toast.success("Redis started successfully");
|
await start({
|
||||||
refetch();
|
redisId: redisId,
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.then(() => {
|
||||||
toast.error("Error starting Redis");
|
toast.success("Redis started successfully");
|
||||||
});
|
refetch();
|
||||||
}}
|
})
|
||||||
>
|
.catch(() => {
|
||||||
<Tooltip>
|
toast.error("Error starting Redis");
|
||||||
<TooltipTrigger asChild>
|
});
|
||||||
<Button
|
}}
|
||||||
variant="secondary"
|
>
|
||||||
isLoading={isStarting}
|
<Button
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
variant="secondary"
|
||||||
>
|
isLoading={isStarting}
|
||||||
<CheckCircle2 className="size-4 mr-1" />
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
Start
|
>
|
||||||
</Button>
|
<Tooltip>
|
||||||
</TooltipTrigger>
|
<TooltipTrigger asChild>
|
||||||
<TooltipPrimitive.Portal>
|
<div className="flex items-center">
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<CheckCircle2 className="size-4 mr-1" />
|
||||||
<p>
|
Start
|
||||||
Start the Redis database (requires a previous
|
</div>
|
||||||
successful setup)
|
</TooltipTrigger>
|
||||||
</p>
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipContent>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
</TooltipPrimitive.Portal>
|
<p>
|
||||||
</Tooltip>
|
Start the Redis database (requires a previous
|
||||||
</DialogAction>
|
successful setup)
|
||||||
) : (
|
</p>
|
||||||
<DialogAction
|
</TooltipContent>
|
||||||
title="Stop Redis"
|
</TooltipPrimitive.Portal>
|
||||||
description="Are you sure you want to stop this redis?"
|
</Tooltip>
|
||||||
onClick={async () => {
|
</Button>
|
||||||
await stop({
|
</DialogAction>
|
||||||
redisId: redisId,
|
) : (
|
||||||
})
|
<DialogAction
|
||||||
.then(() => {
|
title="Stop Redis"
|
||||||
toast.success("Redis stopped successfully");
|
description="Are you sure you want to stop this redis?"
|
||||||
refetch();
|
onClick={async () => {
|
||||||
})
|
await stop({
|
||||||
.catch(() => {
|
redisId: redisId,
|
||||||
toast.error("Error stopping Redis");
|
})
|
||||||
});
|
.then(() => {
|
||||||
}}
|
toast.success("Redis stopped successfully");
|
||||||
>
|
refetch();
|
||||||
<Tooltip>
|
})
|
||||||
<TooltipTrigger asChild>
|
.catch(() => {
|
||||||
<Button
|
toast.error("Error stopping Redis");
|
||||||
variant="destructive"
|
});
|
||||||
isLoading={isStopping}
|
}}
|
||||||
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
>
|
||||||
>
|
<Button
|
||||||
<Ban className="size-4 mr-1" />
|
variant="destructive"
|
||||||
Stop
|
isLoading={isStopping}
|
||||||
</Button>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
</TooltipTrigger>
|
>
|
||||||
<TooltipPrimitive.Portal>
|
<Tooltip>
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
<TooltipTrigger asChild>
|
||||||
<p>Stop the currently running Redis database</p>
|
<div className="flex items-center">
|
||||||
</TooltipContent>
|
<Ban className="size-4 mr-1" />
|
||||||
</TooltipPrimitive.Portal>
|
Stop
|
||||||
</Tooltip>
|
</div>
|
||||||
</DialogAction>
|
</TooltipTrigger>
|
||||||
)}
|
<TooltipPrimitive.Portal>
|
||||||
</TooltipProvider>
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
<DockerTerminalModal
|
<p>Stop the currently running Redis database</p>
|
||||||
appName={data?.appName || ""}
|
</TooltipContent>
|
||||||
serverId={data?.serverId || ""}
|
</TooltipPrimitive.Portal>
|
||||||
>
|
</Tooltip>
|
||||||
<Tooltip>
|
</Button>
|
||||||
<TooltipTrigger asChild>
|
</DialogAction>
|
||||||
<Button
|
)}
|
||||||
variant="outline"
|
</TooltipProvider>
|
||||||
className="flex items-center gap-2 focus-visible:ring-2 focus-visible:ring-offset-2"
|
<DockerTerminalModal
|
||||||
>
|
appName={data?.appName || ""}
|
||||||
<Terminal className="size-4" />
|
serverId={data?.serverId || ""}
|
||||||
Open Terminal
|
>
|
||||||
</Button>
|
<Button
|
||||||
</TooltipTrigger>
|
variant="outline"
|
||||||
<TooltipPrimitive.Portal>
|
className="flex items-center gap-1.5 focus-visible:ring-2 focus-visible:ring-offset-2"
|
||||||
<TooltipContent sideOffset={5} className="z-[60]">
|
>
|
||||||
<p>Open a terminal to the Redis container</p>
|
<Tooltip>
|
||||||
</TooltipContent>
|
<TooltipTrigger asChild>
|
||||||
</TooltipPrimitive.Portal>
|
<div className="flex items-center">
|
||||||
</Tooltip>
|
<Terminal className="size-4 mr-1" />
|
||||||
</DockerTerminalModal>
|
Open Terminal
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</TooltipTrigger>
|
||||||
<DrawerLogs
|
<TooltipPrimitive.Portal>
|
||||||
isOpen={isDrawerOpen}
|
<TooltipContent sideOffset={5} className="z-[60]">
|
||||||
onClose={() => {
|
<p>Open a terminal to the Redis container</p>
|
||||||
setIsDrawerOpen(false);
|
</TooltipContent>
|
||||||
setFilteredLogs([]);
|
</TooltipPrimitive.Portal>
|
||||||
setIsDeploying(false);
|
</Tooltip>
|
||||||
refetch();
|
</Button>
|
||||||
}}
|
</DockerTerminalModal>
|
||||||
filteredLogs={filteredLogs}
|
</CardContent>
|
||||||
/>
|
</Card>
|
||||||
</div>
|
<DrawerLogs
|
||||||
</>
|
isOpen={isDrawerOpen}
|
||||||
);
|
onClose={() => {
|
||||||
|
setIsDrawerOpen(false);
|
||||||
|
setFilteredLogs([]);
|
||||||
|
setIsDeploying(false);
|
||||||
|
refetch();
|
||||||
|
}}
|
||||||
|
filteredLogs={filteredLogs}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user