forked from github-starred/komodo
refactor useRead, improve dx alot
This commit is contained in:
@@ -7,6 +7,7 @@ import { Link, useLocation, useParams } from "react-router-dom";
|
||||
import { useUser } from "@hooks";
|
||||
import { ServerName } from "@resources/server/util";
|
||||
import { DeploymentName } from "@resources/deployment/util";
|
||||
import { DesktopUpdates } from "@components/updates/desktop";
|
||||
|
||||
export const Paths = () => {
|
||||
const path = useLocation().pathname.split("/")[1];
|
||||
@@ -61,12 +62,13 @@ export const Header = () => {
|
||||
</Link>
|
||||
<Paths />
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="flex ">
|
||||
{user && (
|
||||
<Button disabled variant="ghost">
|
||||
<Circle className="w-4 h-4 fill-green-500 stroke-none" />
|
||||
</Button>
|
||||
)}
|
||||
{user && <DesktopUpdates />}
|
||||
<ThemeToggle />
|
||||
{user && (
|
||||
<Button variant="ghost" onClick={logout}>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useRead } from "@hooks";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@ui/dropdown";
|
||||
import { Bell } from "lucide-react";
|
||||
import { SingleUpdate } from "./updates";
|
||||
import { Button } from "@ui/button";
|
||||
|
||||
export const DesktopUpdates = () => {
|
||||
const updates = useRead("ListUpdates", {}).data;
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button variant="ghost">
|
||||
<Bell className="w-4 h-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{updates?.map((update) => (
|
||||
<DropdownMenuItem key={update._id?.$oid}>
|
||||
<SingleUpdate update={update} />
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
@@ -22,12 +22,13 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@ui/card";
|
||||
// import { useRead } from "@hooks";
|
||||
|
||||
export const UpdateUser = ({ userId }: { userId: string }) => {
|
||||
// const { data } = useUpdateUser(userId);
|
||||
// const { data } = useRead({ type: "GetUser", params: {} });
|
||||
if (userId === "github") return <>GitHub</>;
|
||||
if (userId === "auto redeploy") return <>Auto Redeploy</>;
|
||||
return <>{userId}</>;
|
||||
return <>{userId.slice(0, 5)}...</>;
|
||||
};
|
||||
|
||||
export const UpdateDetails = ({ update }: { update: Update }) => {
|
||||
|
||||
@@ -1,62 +1,31 @@
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@ui/card";
|
||||
import { Types } from "@monitor/client";
|
||||
import { cn, version_to_string } from "@util/helpers";
|
||||
import { version_to_string } from "@util/helpers";
|
||||
import { Calendar, User } from "lucide-react";
|
||||
import { UpdateDetails, UpdateUser } from "./update";
|
||||
import { Update } from "@monitor/client/dist/types";
|
||||
|
||||
export const Updates = ({
|
||||
updates,
|
||||
className,
|
||||
}: {
|
||||
updates?: Types.Update[];
|
||||
className?: string;
|
||||
}) => (
|
||||
<Card className={cn("w-full h-fit", className)}>
|
||||
<CardHeader className="flex-row justify-between">
|
||||
<CardTitle className="text-xl">Updates</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-2 max-h-[50vh] overflow-y-auto">
|
||||
{updates?.map((update) => (
|
||||
<Card key={update._id?.$oid}>
|
||||
<CardHeader className="flex flex-row items-end md:items-center justify-between gap-4">
|
||||
<div
|
||||
className="flex flex-col md:flex-row justify-between items-center w-full"
|
||||
style={{ placeItems: "center start" }}
|
||||
>
|
||||
<CardTitle className="whitespace-nowrap w-full">
|
||||
{update.operation
|
||||
.split("_")
|
||||
.map((s) => s[0].toUpperCase() + s.slice(1))
|
||||
.join(" ")}{" "}
|
||||
{version_to_string(update.version)}
|
||||
</CardTitle>
|
||||
<div className="flex flex-col-reverse md:flex-row md:gap-4 w-full">
|
||||
<div className="flex gap-2 items-center md:w-[200px]">
|
||||
<Calendar className="w-4 h-4" />
|
||||
<CardDescription className="text-xs md:text-sm">
|
||||
{update.end_ts
|
||||
? new Date(update.end_ts).toLocaleString()
|
||||
: "ongoing"}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<User className="w-4 h-4" />
|
||||
<CardDescription>
|
||||
<UpdateUser userId={update.operator} />
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UpdateDetails update={update} />
|
||||
</CardHeader>
|
||||
</Card>
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
export const SingleUpdate = ({ update }: { update: Update }) => (
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
{update.operation
|
||||
.split("_")
|
||||
.map((s) => s[0].toUpperCase() + s.slice(1))
|
||||
.join(" ")}{" "}
|
||||
{version_to_string(update.version)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex gap-2 items-center md:w-[200px]">
|
||||
<Calendar className="w-4 h-4" />
|
||||
<div className="text-xs md:text-sm">
|
||||
{update.end_ts ? new Date(update.end_ts).toLocaleString() : "ongoing"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<User className="w-4 h-4" />
|
||||
<div>
|
||||
<UpdateUser userId={update.operator} />
|
||||
</div>
|
||||
</div>
|
||||
<UpdateDetails update={update} />
|
||||
</div>
|
||||
);
|
||||
|
||||
+25
-3
@@ -3,6 +3,7 @@ import { client } from "./main";
|
||||
import {
|
||||
useQuery,
|
||||
useMutation,
|
||||
UseQueryOptions,
|
||||
UseMutationOptions,
|
||||
} from "@tanstack/react-query";
|
||||
import { useAtomValue, useSetAtom } from "jotai";
|
||||
@@ -10,11 +11,32 @@ import { atomWithStorage } from "jotai/utils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
ExecuteResponses,
|
||||
ReadResponses,
|
||||
WriteResponses,
|
||||
} from "@monitor/client/dist/responses";
|
||||
|
||||
export const useRead = <T extends Types.ReadRequest>(req: T) =>
|
||||
useQuery([req], () => client.read(req));
|
||||
export const useRead = <
|
||||
T extends Types.ReadRequest["type"],
|
||||
P = Extract<Types.WriteRequest, { type: T }>["params"]
|
||||
>(
|
||||
type: T,
|
||||
params: P,
|
||||
config?: Omit<
|
||||
UseQueryOptions<ReadResponses[T], unknown, ReadResponses[T], (T | P)[]>,
|
||||
"initialData" | "queryFn" | "queryKey"
|
||||
>
|
||||
) =>
|
||||
useQuery(
|
||||
[type, params],
|
||||
async () =>
|
||||
(await client.read({ type, params } as any)) as ReadResponses[T],
|
||||
config
|
||||
);
|
||||
|
||||
// export const useRead = <T extends Types.ReadRequest>(
|
||||
// req: T,
|
||||
// options?: UseQueryOptions
|
||||
// ) => useQuery([req], () => client.read(req), options);
|
||||
|
||||
export const useWrite = <
|
||||
T extends Types.WriteRequest["type"],
|
||||
@@ -50,7 +72,7 @@ export const useExecute = <
|
||||
config
|
||||
);
|
||||
|
||||
export const useUser = () => useRead({ type: "GetUser", params: {} });
|
||||
export const useUser = () => useRead("GetUser", {});
|
||||
|
||||
export const useLogin = () => {
|
||||
const { refetch } = useUser();
|
||||
|
||||
@@ -12,10 +12,7 @@ import { useRead } from "@hooks";
|
||||
import { DockerContainerState } from "@monitor/client/dist/types";
|
||||
|
||||
export const DeploymentsChart = () => {
|
||||
const { data, isLoading, isError } = useRead({
|
||||
type: "ListDeployments",
|
||||
params: {},
|
||||
});
|
||||
const { data, isLoading, isError } = useRead("ListDeployments", {});
|
||||
|
||||
const running = data?.filter(
|
||||
(d) => d.state === DockerContainerState.Running
|
||||
|
||||
@@ -12,10 +12,7 @@ import { useRead } from "@hooks";
|
||||
import { ServerStatus } from "@monitor/client/dist/types";
|
||||
|
||||
export const ServersChart = () => {
|
||||
const { data, isLoading, isError } = useRead({
|
||||
type: "ListServers",
|
||||
params: {},
|
||||
});
|
||||
const { data, isLoading, isError } = useRead("ListServers", {});
|
||||
|
||||
const running = data?.filter((d) => d.status === ServerStatus.Ok).length;
|
||||
const stopped = data?.filter((d) => d.status === ServerStatus.NotOk).length;
|
||||
|
||||
@@ -10,26 +10,33 @@ export const Dashboard = () => {
|
||||
<div className="flex flex-col gap-24">
|
||||
<RecentlyViewed />
|
||||
<div className="flex flex-col gap-6 w-full">
|
||||
{/* <h1 className="text-4xl"> All Resources </h1> */}
|
||||
<div>
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<Box className="w-4 h-4" />
|
||||
<h2 className="text-xl">My Resources</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<div className="flex gap-4 w-full h-fit">
|
||||
<DeploymentsChart />
|
||||
<ServersChart />
|
||||
</div>
|
||||
<Link to="/builds" className="w-full max-w-[50%] h-full">
|
||||
<Card hoverable>
|
||||
<CardHeader>
|
||||
<CardTitle>Builds</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Link>
|
||||
<div className="flex gap-4 w-full h-fit">
|
||||
<Link to="/builds" className="w-full max-w-[50%] h-full">
|
||||
<Card hoverable>
|
||||
<CardHeader>
|
||||
<CardTitle>Builds</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Link>
|
||||
<Link to="/builders" className="w-full max-w-[50%] h-full">
|
||||
<Card hoverable>
|
||||
<CardHeader>
|
||||
<CardTitle>Builders</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ import { BuildInfo } from "./util";
|
||||
import { Hammer } from "lucide-react";
|
||||
|
||||
export const BuildCard = ({ id }: { id: string }) => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const build = builds?.find((server) => server.id === id);
|
||||
if (!build) return null;
|
||||
|
||||
|
||||
@@ -4,25 +4,25 @@ import { version_to_string } from "@util/helpers";
|
||||
import { Factory, History } from "lucide-react";
|
||||
|
||||
export const BuildName = ({ id }: { id: string }) => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const build = builds?.find((b) => b.id === id);
|
||||
return <>{build?.name ?? "..."}</>;
|
||||
};
|
||||
|
||||
export const BuildVersion = ({ id }: { id: string }) => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const build = builds?.find((b) => b.id === id);
|
||||
return <>{version_to_string(build?.version) ?? "..."}</>;
|
||||
};
|
||||
|
||||
export const BuildBuilder = ({ id }: { id: string }) => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const build = builds?.find((b) => b.id === id);
|
||||
return <>{"build.builder " + build?.id ?? "..."}</>;
|
||||
};
|
||||
|
||||
export const BuildLastBuilt = ({ id }: { id: string }) => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const build = builds?.find((b) => b.id === id);
|
||||
const last = build?.last_built_at;
|
||||
return <>{last ? new Date(last).toLocaleString() : "not yet built"}</>;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useRead } from "@hooks";
|
||||
import { ServerStatusIcon } from "@resources/server/util";
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
CardContent,
|
||||
} from "@ui/card";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Factory } from "lucide-react";
|
||||
|
||||
export const BuilderCard = ({ id }: { id: string }) => {
|
||||
const builders = useRead("ListBuilders", {}).data;
|
||||
const builder = builders?.find((builder) => builder._id?.$oid === id);
|
||||
if (!builder) return null;
|
||||
|
||||
return (
|
||||
<Link to={`/builds/${builder._id?.$oid}`} key={builder._id?.$oid}>
|
||||
<Card hoverable>
|
||||
<CardHeader className="flex flex-row justify-between">
|
||||
<div>
|
||||
<CardTitle>{builder.name}</CardTitle>
|
||||
<CardDescription> </CardDescription>
|
||||
</div>
|
||||
<ServerStatusIcon serverId={builder._id?.$oid} />
|
||||
</CardHeader>
|
||||
<CardContent className="flex items-center gap-4">
|
||||
<Factory className="w-4 h-4" />
|
||||
<div className="border h-6" />
|
||||
<div>{builder.description}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -11,7 +11,7 @@ import { DeploymentInfo, DeploymentStatusIcon } from "./util";
|
||||
import { Rocket } from "lucide-react";
|
||||
|
||||
export const DeploymentCard = ({ id }: { id: string }) => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === id);
|
||||
if (!deployment) return null;
|
||||
return (
|
||||
|
||||
@@ -20,7 +20,7 @@ interface DeploymentId {
|
||||
|
||||
export const RedeployContainer = ({ deployment_id }: DeploymentId) => {
|
||||
const { mutate, isLoading } = useExecute("Deploy");
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deployment_id);
|
||||
return (
|
||||
<ActionButton
|
||||
@@ -61,8 +61,8 @@ const StopContainer = ({ deployment_id }: DeploymentId) => {
|
||||
};
|
||||
|
||||
export const StartOrStopContainer = ({ deployment_id }: DeploymentId) => {
|
||||
const { data } = useRead({ type: "ListDeployments", params: {} });
|
||||
const deployment = data?.find((d) => d.id == deployment_id);
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deployment_id);
|
||||
if (deployment?.state === DockerContainerState.Running)
|
||||
return <StopContainer deployment_id={deployment_id} />;
|
||||
return <StartContainer deployment_id={deployment_id} />;
|
||||
@@ -83,7 +83,8 @@ export const RemoveContainer = ({ deployment_id }: DeploymentId) => {
|
||||
|
||||
export const DeleteDeployment = ({ id }: { id: string }) => {
|
||||
const nav = useNavigate();
|
||||
const { data } = useRead({ type: "GetDeployment", params: { id } });
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === id);
|
||||
const { mutate, isLoading } = useWrite("DeleteDeployment", {
|
||||
onSuccess: () => nav("/deployments"),
|
||||
});
|
||||
@@ -107,7 +108,7 @@ export const DeleteDeployment = ({ id }: { id: string }) => {
|
||||
<div className="flex flex-col gap-2">
|
||||
<p>
|
||||
Are you sure you wish to delete this deployment? If so, please
|
||||
type in <b>{data?.name}</b> below
|
||||
type in <b>{deployment?.name}</b> below
|
||||
</p>
|
||||
<Input value={name} onChange={(e) => setName(e.target.value)} />
|
||||
</div>
|
||||
@@ -115,7 +116,7 @@ export const DeleteDeployment = ({ id }: { id: string }) => {
|
||||
<Button
|
||||
variant="outline"
|
||||
intent="danger"
|
||||
disabled={name !== data?.name || isLoading}
|
||||
disabled={name !== deployment?.name || isLoading}
|
||||
onClick={() => mutate({ id })}
|
||||
>
|
||||
Delete
|
||||
|
||||
@@ -12,11 +12,12 @@ const scroll_to_bottom = (id: string) => () =>
|
||||
.getElementById(id)
|
||||
?.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
|
||||
|
||||
export const DeploymentLogs = ({ deploymentId }: { deploymentId: string }) => {
|
||||
const { data, refetch } = useRead({
|
||||
type: "GetLog",
|
||||
params: { deployment_id: deploymentId, tail: 200 },
|
||||
});
|
||||
export const DeploymentLogs = ({
|
||||
deployment_id,
|
||||
}: {
|
||||
deployment_id: string;
|
||||
}) => {
|
||||
const { data, refetch } = useRead("GetLog", { deployment_id, tail: 200 });
|
||||
|
||||
useEffect(() => {
|
||||
const handle = setInterval(() => refetch(), 30000);
|
||||
|
||||
@@ -7,7 +7,7 @@ export const DeploymentName = ({
|
||||
}: {
|
||||
deploymentId: string | undefined;
|
||||
}) => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deploymentId);
|
||||
return <>{deployment?.name ?? "..."}</>;
|
||||
};
|
||||
@@ -17,7 +17,7 @@ export const DeploymentStatus = ({
|
||||
}: {
|
||||
deploymentId: string | undefined;
|
||||
}) => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deploymentId);
|
||||
return <>{deployments ? deployment?.status ?? "not deployed" : "..."}</>;
|
||||
};
|
||||
@@ -27,7 +27,7 @@ export const DeploymentStatusIcon = ({
|
||||
}: {
|
||||
deploymentId: string | undefined;
|
||||
}) => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deploymentId);
|
||||
return (
|
||||
<Circle
|
||||
@@ -42,7 +42,7 @@ export const DeploymentStatusIcon = ({
|
||||
};
|
||||
|
||||
export const DeploymentInfo = ({ deploymentId }: { deploymentId: string }) => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === deploymentId);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Factory, Hammer, Rocket, Server } from "lucide-react";
|
||||
import { useRead } from "@hooks";
|
||||
import { Resources } from "@layouts/resources";
|
||||
import { DeploymentCard } from "./deployment/card";
|
||||
import { BuildCard } from "./build/card";
|
||||
import { ServerCard } from "./server/card";
|
||||
import { Hammer, Rocket, Server } from "lucide-react";
|
||||
import { BuilderCard } from "./builder/card";
|
||||
|
||||
export const Deployments = () => {
|
||||
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
|
||||
const summary = useRead({ type: "GetDeploymentsSummary", params: {} }).data;
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const summary = useRead("GetDeploymentsSummary", {}).data;
|
||||
|
||||
return (
|
||||
<Resources
|
||||
@@ -27,9 +28,30 @@ export const Deployments = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const Servers = () => {
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const summary = useRead("GetServersSummary", {}).data;
|
||||
return (
|
||||
<Resources
|
||||
type="Server"
|
||||
info={`${summary?.total} Total, ${summary?.healthy} Healthy, ${summary?.unhealthy} Unhealthy`}
|
||||
icon={<Server className="w-6 h-6" />}
|
||||
components={(search) => (
|
||||
<>
|
||||
{servers
|
||||
?.filter((d) => d.name.includes(search) || search.includes(d.name))
|
||||
.map(({ id }) => (
|
||||
<ServerCard key={id} id={id} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const Builds = () => {
|
||||
const builds = useRead({ type: "ListBuilds", params: {} }).data;
|
||||
const summary = useRead({ type: "GetBuildsSummary", params: {} }).data;
|
||||
const builds = useRead("ListBuilds", {}).data;
|
||||
const summary = useRead("GetBuildsSummary", {}).data;
|
||||
|
||||
return (
|
||||
<Resources
|
||||
@@ -49,20 +71,21 @@ export const Builds = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const Servers = () => {
|
||||
const servers = useRead({ type: "ListServers", params: {} }).data;
|
||||
const summary = useRead({ type: "GetServersSummary", params: {} }).data;
|
||||
export const Builders = () => {
|
||||
const builders = useRead("ListBuilders", {}).data;
|
||||
const summary = useRead("GetBuildersSummary", {}).data;
|
||||
|
||||
return (
|
||||
<Resources
|
||||
type="Server"
|
||||
info={`${summary?.total} Total, ${summary?.healthy} Healthy, ${summary?.unhealthy} Unhealthy`}
|
||||
icon={<Server className="w-6 h-6" />}
|
||||
type="Builder"
|
||||
info={`${summary?.total} Total`}
|
||||
icon={<Factory className="w-6 h-6" />}
|
||||
components={(search) => (
|
||||
<>
|
||||
{servers
|
||||
{builders
|
||||
?.filter((d) => d.name.includes(search) || search.includes(d.name))
|
||||
.map(({ id }) => (
|
||||
<ServerCard key={id} id={id} />
|
||||
.map(({ _id }) => (
|
||||
<BuilderCard key={_id?.$oid} id={_id?.$oid!} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ServerStatusIcon, ServerStats } from "./util";
|
||||
import { Server } from "lucide-react";
|
||||
|
||||
export const ServerCard = ({ id }: { id: string }) => {
|
||||
const servers = useRead({ type: "ListServers", params: {} }).data;
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const server = servers?.find((server) => server.id === id);
|
||||
if (!server) return null;
|
||||
|
||||
@@ -28,7 +28,7 @@ export const ServerCard = ({ id }: { id: string }) => {
|
||||
<CardContent className="flex items-center gap-4">
|
||||
<Server className="w-4 h-4" />
|
||||
<div className="border h-6" />
|
||||
<ServerStats serverId={server.id} />
|
||||
<ServerStats server_id={server.id} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
|
||||
@@ -5,17 +5,17 @@ import { Circle, Cpu, Database, MemoryStick } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export const ServerName = ({ serverId }: { serverId: string | undefined }) => {
|
||||
const servers = useRead({ type: "ListServers", params: {} }).data;
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const server = servers?.find((s) => s.id === serverId);
|
||||
return <>{server?.name ?? "..."}</>;
|
||||
};
|
||||
|
||||
export const ServerInfo = ({ serverId }: { serverId: string | undefined }) => {
|
||||
const servers = useRead({ type: "ListServers", params: {} }).data;
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const server = servers?.find((s) => s.id === serverId);
|
||||
return (
|
||||
<div className="flex items-center gap-4 text-muted-foreground">
|
||||
{serverId && <ServerStats serverId={serverId} />}
|
||||
{serverId && <ServerStats server_id={serverId} />}
|
||||
<div>|</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div> Status: {server?.status}</div>
|
||||
@@ -25,11 +25,8 @@ export const ServerInfo = ({ serverId }: { serverId: string | undefined }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ServerStats = ({ serverId }: { serverId: string }) => {
|
||||
const { data, refetch } = useRead({
|
||||
type: "GetBasicSystemStats",
|
||||
params: { server_id: serverId },
|
||||
});
|
||||
export const ServerStats = ({ server_id }: { server_id: string }) => {
|
||||
const { data, refetch } = useRead("GetBasicSystemStats", { server_id });
|
||||
|
||||
useEffect(() => {
|
||||
const handle = setInterval(() => refetch(), 30000);
|
||||
@@ -63,7 +60,7 @@ export const ServerStatusIcon = ({
|
||||
serverId: string | undefined;
|
||||
sm?: boolean;
|
||||
}) => {
|
||||
const servers = useRead({ type: "ListServers", params: {} }).data;
|
||||
const servers = useRead("ListServers", {}).data;
|
||||
const server = servers?.find((s) => s.id === serverId);
|
||||
return (
|
||||
<Circle
|
||||
|
||||
+12
-4
@@ -6,7 +6,7 @@ import { Dashboard } from "@pages/dashboard";
|
||||
import { Deployment } from "@resources/deployment/page";
|
||||
import { Server } from "@resources/server/page";
|
||||
import { Build } from "@resources/build/page";
|
||||
import { Deployments, Builds, Servers } from "@resources/pages";
|
||||
import { Deployments, Builds, Servers, Builders } from "@resources/pages";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@@ -24,6 +24,14 @@ const router = createBrowserRouter([
|
||||
{ path: ":deploymentId", element: <Deployment /> },
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: "servers",
|
||||
children: [
|
||||
{ path: "", element: <Servers /> },
|
||||
{ path: ":serverId", element: <Server /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "builds",
|
||||
children: [
|
||||
@@ -32,10 +40,10 @@ const router = createBrowserRouter([
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "servers",
|
||||
path: "builders",
|
||||
children: [
|
||||
{ path: "", element: <Servers /> },
|
||||
{ path: ":serverId", element: <Server /> },
|
||||
{ path: "", element: <Builders /> },
|
||||
// { path: ":builderId", element: <Build /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user