refactor: add toggle for normal containers & stack

This commit is contained in:
Mauricio Siu
2024-12-25 02:51:44 -06:00
parent f672c429c4
commit da858e215d
3 changed files with 164 additions and 52 deletions

View File

@@ -15,6 +15,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api"; import { api } from "@/utils/api";
import { Loader2 } from "lucide-react"; import { Loader2 } from "lucide-react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
@@ -35,34 +36,72 @@ interface Props {
} }
export const ShowDockerLogs = ({ appName, serverId }: Props) => { export const ShowDockerLogs = ({ appName, serverId }: Props) => {
const { data, isLoading } = api.docker.getServiceContainersByAppName.useQuery(
{
appName,
serverId,
},
{
enabled: !!appName,
},
);
const [containerId, setContainerId] = useState<string | undefined>(); const [containerId, setContainerId] = useState<string | undefined>();
const [option, setOption] = useState<"swarm" | "native">("native");
const { data: services, isLoading: servicesLoading } =
api.docker.getServiceContainersByAppName.useQuery(
{
appName,
serverId,
},
{
enabled: !!appName && option === "swarm",
},
);
const { data: containers, isLoading: containersLoading } =
api.docker.getContainersByAppNameMatch.useQuery(
{
appName,
serverId,
},
{
enabled: !!appName && option === "native",
},
);
useEffect(() => { useEffect(() => {
if (data && data?.length > 0) { if (option === "native") {
setContainerId(data[0]?.containerId); if (containers && containers?.length > 0) {
setContainerId(containers[0]?.containerId);
}
} else {
if (services && services?.length > 0) {
setContainerId(services[0]?.containerId);
}
} }
}, [data]); }, [option, services, containers]);
const isLoading = option === "native" ? containersLoading : servicesLoading;
const containersLenght =
option === "native" ? containers?.length : services?.length;
return ( return (
<Card className="bg-background"> <Card className="bg-background">
<CardHeader> <CardHeader>
<CardTitle className="text-xl">Logs</CardTitle> <CardTitle className="text-xl">Logssss</CardTitle>
<CardDescription> <CardDescription>
Watch the logs of the application in real time Watch the logs of the application in real time
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent className="flex flex-col gap-4"> <CardContent className="flex flex-col gap-4">
<Label>Select a container to view logs</Label> <div className="flex flex-row justify-between items-center gap-2">
<Label>Select a container to view logs</Label>
<div className="flex flex-row gap-2 items-center">
<span className="text-sm text-muted-foreground">
{option === "native" ? "Native" : "Swarm"}
</span>
<Switch
checked={option === "native"}
onCheckedChange={(checked) => {
setOption(checked ? "native" : "swarm");
}}
/>
</div>
</div>
<Select onValueChange={setContainerId} value={containerId}> <Select onValueChange={setContainerId} value={containerId}>
<SelectTrigger> <SelectTrigger>
{isLoading ? ( {isLoading ? (
@@ -76,23 +115,40 @@ export const ShowDockerLogs = ({ appName, serverId }: Props) => {
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
{data?.map((container) => ( {option === "native" ? (
<SelectItem <div>
key={container.containerId} {containers?.map((container) => (
value={container.containerId} <SelectItem
> key={container.containerId}
{container.name} ({container.containerId}@{container.node}){" "} value={container.containerId}
{container.state} >
</SelectItem> {container.name} ({container.containerId}){" "}
))} {container.state}
<SelectLabel>Containers ({data?.length})</SelectLabel> </SelectItem>
))}
</div>
) : (
<>
{services?.map((container) => (
<SelectItem
key={container.containerId}
value={container.containerId}
>
{container.name} ({container.containerId}@{container.node}
) {container.state}
</SelectItem>
))}
</>
)}
<SelectLabel>Containers ({containersLenght})</SelectLabel>
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
<DockerLogs <DockerLogs
serverId={serverId || ""} serverId={serverId || ""}
containerId={containerId || "select-a-container"} containerId={containerId || "select-a-container"}
runType="swarm" runType={option}
/> />
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -15,8 +15,9 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api"; import { api } from "@/utils/api";
import { Loader, Loader2 } from "lucide-react"; import { Loader2 } from "lucide-react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
export const DockerLogs = dynamic( export const DockerLogs = dynamic(
@@ -35,22 +36,47 @@ interface Props {
} }
export const ShowDockerLogsStack = ({ appName, serverId }: Props) => { export const ShowDockerLogsStack = ({ appName, serverId }: Props) => {
const { data, isLoading } = api.docker.getStackContainersByAppName.useQuery( const [option, setOption] = useState<"swarm" | "native">("native");
{
appName,
serverId,
},
{
enabled: !!appName,
},
);
const [containerId, setContainerId] = useState<string | undefined>(); const [containerId, setContainerId] = useState<string | undefined>();
const { data: services, isLoading: servicesLoading } =
api.docker.getStackContainersByAppName.useQuery(
{
appName,
serverId,
},
{
enabled: !!appName && option === "swarm",
},
);
const { data: containers, isLoading: containersLoading } =
api.docker.getContainersByAppNameMatch.useQuery(
{
appName,
appType: "stack",
serverId,
},
{
enabled: !!appName && option === "native",
},
);
useEffect(() => { useEffect(() => {
if (data && data?.length > 0) { if (option === "native") {
setContainerId(data[0]?.containerId); if (containers && containers?.length > 0) {
setContainerId(containers[0]?.containerId);
}
} else {
if (services && services?.length > 0) {
setContainerId(services[0]?.containerId);
}
} }
}, [data]); }, [option, services, containers]);
const isLoading = option === "native" ? containersLoading : servicesLoading;
const containersLenght =
option === "native" ? containers?.length : services?.length;
return ( return (
<Card className="bg-background"> <Card className="bg-background">
@@ -62,7 +88,20 @@ export const ShowDockerLogsStack = ({ appName, serverId }: Props) => {
</CardHeader> </CardHeader>
<CardContent className="flex flex-col gap-4"> <CardContent className="flex flex-col gap-4">
<Label>Select a container to view logs</Label> <div className="flex flex-row justify-between items-center gap-2">
<Label>Select a container to view logs</Label>
<div className="flex flex-row gap-2 items-center">
<span className="text-sm text-muted-foreground">
{option === "native" ? "Native" : "Swarm"}
</span>
<Switch
checked={option === "native"}
onCheckedChange={(checked) => {
setOption(checked ? "native" : "swarm");
}}
/>
</div>
</div>
<Select onValueChange={setContainerId} value={containerId}> <Select onValueChange={setContainerId} value={containerId}>
<SelectTrigger> <SelectTrigger>
{isLoading ? ( {isLoading ? (
@@ -76,23 +115,40 @@ export const ShowDockerLogsStack = ({ appName, serverId }: Props) => {
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
{data?.map((container) => ( {option === "native" ? (
<SelectItem <div>
key={container.containerId} {containers?.map((container) => (
value={container.containerId} <SelectItem
> key={container.containerId}
{container.name} ({container.containerId}@{container.node}){" "} value={container.containerId}
{container.state} >
</SelectItem> {container.name} ({container.containerId}){" "}
))} {container.state}
<SelectLabel>Containers ({data?.length})</SelectLabel> </SelectItem>
))}
</div>
) : (
<>
{services?.map((container) => (
<SelectItem
key={container.containerId}
value={container.containerId}
>
{container.name} ({container.containerId}@{container.node}
) {container.state}
</SelectItem>
))}
</>
)}
<SelectLabel>Containers ({containersLenght})</SelectLabel>
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
<DockerLogs <DockerLogs
serverId={serverId || ""} serverId={serverId || ""}
containerId={containerId || "select-a-container"} containerId={containerId || "select-a-container"}
runType="swarm" runType={option}
/> />
</CardContent> </CardContent>
</Card> </Card>

View File

@@ -54,7 +54,7 @@ export const setupDockerContainerLogsWebSocketServer = (
const client = new Client(); const client = new Client();
client client
.once("ready", () => { .once("ready", () => {
const baseCommand = `docker ${runType==="swarm"?"service":"container"} logs --timestamps --tail ${tail} ${ const baseCommand = `docker ${runType === "swarm" ? "service" : "container"} logs --timestamps --tail ${tail} ${
since === "all" ? "" : `--since ${since}` since === "all" ? "" : `--since ${since}`
} --follow ${containerId}`; } --follow ${containerId}`;
const escapedSearch = search ? search.replace(/'/g, "'\\''") : ""; const escapedSearch = search ? search.replace(/'/g, "'\\''") : "";
@@ -98,7 +98,7 @@ export const setupDockerContainerLogsWebSocketServer = (
}); });
} else { } else {
const shell = getShell(); const shell = getShell();
const baseCommand = `docker ${runType==="swarm"?"service":"container"} logs --timestamps --tail ${tail} ${ const baseCommand = `docker ${runType === "swarm" ? "service" : "container"} logs --timestamps --tail ${tail} ${
since === "all" ? "" : `--since ${since}` since === "all" ? "" : `--since ${since}`
} --follow ${containerId}`; } --follow ${containerId}`;
const command = search const command = search