wip: service

This commit is contained in:
Derock 2024-01-04 22:31:19 -05:00
parent 1d14969091
commit 1966fce572
No known key found for this signature in database
4 changed files with 73 additions and 33 deletions

View file

@ -88,7 +88,7 @@ export function ProjectList({ defaultValue }: { defaultValue: Projects }) {
</div>
</div>
<div className="mt-4 grid grid-cols-2 gap-8">
<div className="mt-4 grid gap-8 md:grid-cols-2">
{sortedProjects.map((project, key) => (
<Project key={key} project={project} />
))}

View file

@ -8,13 +8,7 @@ import { api } from "~/trpc/react";
import { type RouterOutputs } from "~/trpc/shared";
import { ProjectContextProvider } from "../_context/ProjectContext";
import { CreateService } from "./CreateService";
const STATUS_ICON_COLORS = {
Healthy: "bg-green-500 border-green-400",
Partial: "bg-yellow-500 border-yellow-400",
Unhealthy: "bg-red-500 border-red-400",
Unknown: "bg-gray-500 border-gray-400",
} as const;
import { ServiceCard } from "./ServiceCard";
export function ProjectLayout(props: {
project: RouterOutputs["projects"]["get"];
@ -38,10 +32,21 @@ export function ProjectLayout(props: {
).length ?? 0;
return (
<ProjectContextProvider data={project.data}>
<ProjectContextProvider
data={{
...project.data,
path: projectPath,
selectedService:
typeof params.serviceId === "string"
? project.data.services.find((service) =>
[service.id, service.name].includes(params.serviceId as string),
)
: undefined,
}}
>
<h1 className="text-3xl font-bold">
{project.data.friendlyName}{" "}
<span className="text-sm font-normal text-muted-foreground">
<span className="text-nowrap text-sm font-normal text-muted-foreground">
({project.data.internalName})
</span>
</h1>
@ -81,30 +86,11 @@ export function ProjectLayout(props: {
</Button>
</div>
<div className="flex flex-row gap-4 border-b-2 border-b-border py-8">
<div className="flex flex-row gap-4 border-b-2 border-b-border py-4">
{/* services */}
<div className="flex flex-grow flex-row gap-2 overflow-x-auto">
<div className="flex flex-grow flex-row flex-wrap gap-2">
{project.data.services.map((service) => (
<Link
key={service.id}
href={`${projectPath}/service/${service.id}`}
>
<div className="flex flex-row items-center gap-1">
<div
className={`mr-1 inline-block h-3 w-3 rounded-full border-2 ${
service.stats?.ServiceStatus?.RunningTasks == undefined
? STATUS_ICON_COLORS.Unknown
: service.stats?.ServiceStatus?.RunningTasks ==
service.stats?.ServiceStatus?.DesiredTasks
? STATUS_ICON_COLORS.Healthy
: service.stats?.ServiceStatus?.RunningTasks ?? 0 > 0
? STATUS_ICON_COLORS.Partial
: STATUS_ICON_COLORS.Unhealthy
}`}
/>
<span>{service.name}</span>
</div>
</Link>
<ServiceCard service={service} key={service.id} />
))}
{project.data.services.length == 0 && (

View file

@ -0,0 +1,49 @@
"use client";
import Link from "next/link";
import { buttonVariants } from "~/components/ui/button";
import { cn } from "~/utils/utils";
import {
useProject,
type BasicServiceDetails,
} from "../_context/ProjectContext";
const STATUS_ICON_COLORS = {
Healthy: "bg-green-500 border-green-400",
Partial: "bg-yellow-500 border-yellow-400",
Unhealthy: "bg-red-500 border-red-400",
Unknown: "bg-gray-500 border-gray-400",
} as const;
export function ServiceCard({ service }: { service: BasicServiceDetails }) {
const project = useProject();
return (
<Link href={`${project.path}/service/${service.name}`}>
<div
className={cn(
buttonVariants({ variant: "outline", size: "lg" }),
"px-6 py-4",
project.selectedService?.id === service.id &&
"cursor-default bg-card hover:bg-card",
)}
>
<div className="flex flex-row items-center gap-1">
<div
className={`mr-1 inline-block h-3 w-3 rounded-full border-2 ${
service.stats?.ServiceStatus?.RunningTasks == undefined
? STATUS_ICON_COLORS.Unknown
: service.stats?.ServiceStatus?.RunningTasks ==
service.stats?.ServiceStatus?.DesiredTasks
? STATUS_ICON_COLORS.Healthy
: service.stats?.ServiceStatus?.RunningTasks ?? 0 > 0
? STATUS_ICON_COLORS.Partial
: STATUS_ICON_COLORS.Unhealthy
}`}
/>
<span>{service.name}</span>
</div>
</div>
</Link>
);
}

View file

@ -3,7 +3,12 @@
import { createContext, useContext } from "react";
import { type RouterOutputs } from "~/trpc/shared";
type ProjectContextType = RouterOutputs["projects"]["get"];
export type BasicServiceDetails =
RouterOutputs["projects"]["get"]["services"][number];
export type ProjectContextType = RouterOutputs["projects"]["get"] & {
path: string;
selectedService?: BasicServiceDetails;
};
const ProjectContext = createContext<ProjectContextType>(
{} as unknown as ProjectContextType,