add builds page, build page, etc

This commit is contained in:
karamvir
2023-07-24 00:21:20 -07:00
parent 145804c05d
commit 6407a3a06d
6 changed files with 203 additions and 36 deletions

View File

@@ -0,0 +1,63 @@
import { Resource } from "@layouts/resource";
import { useParams } from "react-router-dom";
import { useExecute, useRead, useSetRecentlyViewed } from "@hooks";
import { ActionButton } from "@components/util";
import { Hammer } from "lucide-react";
import { version_to_string } from "@util/helpers";
export const BuildName = ({ id }: { id: string }) => {
const builds = useRead({ type: "ListBuilds", params: {} }).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 build = builds?.find((b) => b.id === id);
return <>{version_to_string(build?.version) ?? "..."}</>;
};
export const RebuildBuild = ({ buildId }: { buildId: string }) => {
const { mutate, isLoading } = useExecute();
return (
<ActionButton
title="Build"
intent="success"
icon={<Hammer className="h-4 w-4" />}
onClick={() =>
mutate({ type: "RunBuild", params: { build_id: buildId } })
}
disabled={isLoading}
/>
);
};
export const Build = () => {
const { buildId } = useParams();
const push = useSetRecentlyViewed();
if (!buildId) return null;
push("Build", buildId);
return (
<Resource
title={<BuildName id={buildId} />}
info={<BuildVersion id={buildId} />}
actions={<RebuildBuild buildId={buildId} />}
tabs={[
{
title: "Config",
component: "config",
},
{
title: "Builder",
component: "builder",
},
{
title: "Updates",
component: "updates",
},
]}
/>
);
};

View File

@@ -0,0 +1,17 @@
import { useRead } from "@hooks";
import { BuildCard } from "@pages/dashboard";
export const Builds = () => {
const builds = useRead({ type: "ListBuilds", params: {} }).data;
return (
<div className="flex flex-col gap-12">
<h1 className="text-3xl">Builds</h1>
<div className="grid grid-cols-4 gap-8">
{builds?.map(({ id }) => (
<BuildCard key={id} id={id} />
))}
</div>
</div>
);
};

View File

@@ -1,21 +1,19 @@
import { useGetRecentlyViewed } from "@hooks";
import { Card, CardContent, CardHeader, CardTitle } from "@ui/card";
import { DeploymentCard, ServerCard } from "..";
import { BuildCard, DeploymentCard, ServerCard } from "..";
export const RecentlyViewed = () => {
const recents = useGetRecentlyViewed();
return (
<Card className="w-full">
<CardHeader>
<CardTitle>Recently Viewed</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="w-full flex flex-col gap-6">
<h2 className="text-xl">Recently Viewed</h2>
<div className="flex flex-col gap-4">
{recents.map(({ type, id }) => {
if (type === "Deployment") return <DeploymentCard key={id} id={id} />;
if (type === "Build") return <div></div>;
if (type === "Build") return <BuildCard key={id} id={id} />;
if (type === "Server") return <ServerCard key={id} id={id} />;
})}
</CardContent>
</Card>
</div>
</div>
);
};

View File

@@ -6,7 +6,7 @@ import {
CardHeader,
CardTitle,
} from "@ui/card";
import { version_to_string } from "@util/helpers";
import { readableVersion, version_to_string } from "@util/helpers";
import { ServersChart } from "./components/servers-chart";
import { DeploymentsChart } from "./components/deployments-chart";
import { Input } from "@ui/input";
@@ -30,7 +30,7 @@ import {
DialogTitle,
} from "@ui/dialog";
import { useState } from "react";
import { RecentlyViewed } from "./components/recents";
import { RecentlyViewed } from "./components/recently-viewed";
import { ServerStats, ServerStatusIcon } from "@pages/server";
const NewDeployment = ({
@@ -78,8 +78,55 @@ const NewDeployment = ({
);
};
const NewBuild = ({
open,
set,
}: {
open: boolean;
set: (b: boolean) => void;
}) => {
const { mutate } = useWrite();
const [name, setName] = useState("");
return (
<Dialog open={open} onOpenChange={set}>
<DialogContent>
<DialogHeader>
<DialogTitle>New Build</DialogTitle>
</DialogHeader>
<div className="flex items-center justify-between">
<div>Build Name</div>
<Input
className="max-w-[50%]"
placeholder="Build Name"
name={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<DialogFooter>
<Button
variant="outline"
intent="success"
onClick={() => {
mutate({
type: "CreateBuild",
params: { name, config: {} },
});
set(false);
}}
>
Create
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
const NewButton = () => {
const [open, set] = useState<"deployment" | "server" | boolean>(false);
const [open, set] = useState<"deployment" | "build" | "server" | boolean>(
false
);
return (
<>
<DropdownMenu>
@@ -104,12 +151,15 @@ const NewButton = () => {
<DropdownMenuItem onClick={() => set("deployment")}>
Deployment
</DropdownMenuItem>
<DropdownMenuItem> Build </DropdownMenuItem>
<DropdownMenuItem onClick={() => set("build")}>
Build
</DropdownMenuItem>
<DropdownMenuItem> Server </DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<NewDeployment open={open === "deployment"} set={set} />
<NewBuild open={open === "build"} set={set} />
</>
);
};
@@ -181,6 +231,28 @@ const ServersList = () => {
);
};
export const BuildCard = ({ id }: { id: string }) => {
const builds = useRead({ type: "ListBuilds", params: {} }).data;
const build = builds?.find((server) => server.id === id);
if (!build) return null;
return (
<Link to={`/builds/${build.id}`} key={build.id}>
<Card className="hover:bg-accent">
<CardHeader className="flex flex-row justify-between">
<div>
<CardTitle>{build.name}</CardTitle>
<CardDescription>
{version_to_string(build.version)}
</CardDescription>
</div>
<ServerStatusIcon serverId={build.id} />
</CardHeader>
</Card>
</Link>
);
};
const BuildsList = () => {
const builds = useRead({ type: "ListBuilds", params: {} }).data;
@@ -188,14 +260,7 @@ const BuildsList = () => {
<div className="flex flex-col gap-2 w-full">
<h2 className="text-lg">Builds</h2>
{builds?.map((build) => (
<Card>
<CardHeader key={build.id}>
<CardTitle>{build.name}</CardTitle>
<CardDescription>
{version_to_string(build.version)}
</CardDescription>
</CardHeader>
</Card>
<BuildCard id={build.id} key={build.id} />
))}
</div>
);

View File

@@ -1,16 +1,42 @@
import { useRead } from "@hooks";
import { DeploymentCard } from "@pages/dashboard";
import { Button } from "@ui/button";
import { Input } from "@ui/input";
import { PlusCircle } from "lucide-react";
import { useState } from "react";
export const Deployments = () => {
const deployments = useRead({ type: "ListDeployments", params: {} }).data;
const [search, set] = useState("");
return (
<div className="flex flex-col gap-12">
<h1 className="text-3xl">Deployments</h1>
<div className="flex justify-between">
<h1 className="text-3xl">Deployments</h1>
<div className="flex gap-4">
<Input
className="w-[300px]"
placeholder="Search"
value={search}
onChange={(e) => set(e.target.value)}
/>
<Button
className="w-[200px] flex items-center gap-2"
variant="outline"
intent="success"
>
<PlusCircle className="w-4 h-4 text-green-500" />
New Deployment
</Button>
</div>
</div>
<div className="grid grid-cols-4 gap-8">
{deployments?.map(({ id }) => (
<DeploymentCard key={id} id={id} />
))}
{deployments?.map(
({ id, name }) =>
(search.includes(name) || name.includes(search)) && (
<DeploymentCard key={id} id={id} />
)
)}
</div>
</div>
);

View File

@@ -1,8 +1,4 @@
// import { Build } from "@pages/resource/build";
// import { Server } from "@pages/resource/server";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
// import { Deployment } from "@pages/resource/deployment";
// import { Builds, Dashboard, Deployments, Servers } from "@pages/resources";
import { Layout } from "@layouts/layout";
import { Login } from "@pages/auth/login";
import { Signup } from "@pages/auth/signup";
@@ -11,6 +7,8 @@ import { Server } from "@pages/server";
import { Deployment } from "@pages/deployment";
import { Servers } from "@pages/servers";
import { Deployments } from "@pages/deployments";
import { Builds } from "@pages/builds";
import { Build } from "@pages/build";
const router = createBrowserRouter([
{
@@ -28,13 +26,13 @@ const router = createBrowserRouter([
{ path: ":deploymentId", element: <Deployment /> },
],
},
// {
// path: "builds",
// children: [
// { path: "", element: <Builds /> },
// { path: ":buildId", element: <Build /> },
// ],
// },
{
path: "builds",
children: [
{ path: "", element: <Builds /> },
{ path: ":buildId", element: <Build /> },
],
},
{
path: "servers",
children: [