wip: service
This commit is contained in:
parent
1d14969091
commit
1966fce572
|
@ -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} />
|
||||
))}
|
||||
|
|
|
@ -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 && (
|
||||
|
|
49
src/app/(dashboard)/project/[id]/_components/ServiceCard.tsx
Normal file
49
src/app/(dashboard)/project/[id]/_components/ServiceCard.tsx
Normal 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>
|
||||
);
|
||||
}
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue