wip: service
This commit is contained in:
parent
1d14969091
commit
1966fce572
|
@ -88,7 +88,7 @@ export function ProjectList({ defaultValue }: { defaultValue: Projects }) {
|
||||||
</div>
|
</div>
|
||||||
</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) => (
|
{sortedProjects.map((project, key) => (
|
||||||
<Project key={key} project={project} />
|
<Project key={key} project={project} />
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -8,13 +8,7 @@ import { api } from "~/trpc/react";
|
||||||
import { type RouterOutputs } from "~/trpc/shared";
|
import { type RouterOutputs } from "~/trpc/shared";
|
||||||
import { ProjectContextProvider } from "../_context/ProjectContext";
|
import { ProjectContextProvider } from "../_context/ProjectContext";
|
||||||
import { CreateService } from "./CreateService";
|
import { CreateService } from "./CreateService";
|
||||||
|
import { ServiceCard } from "./ServiceCard";
|
||||||
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 ProjectLayout(props: {
|
export function ProjectLayout(props: {
|
||||||
project: RouterOutputs["projects"]["get"];
|
project: RouterOutputs["projects"]["get"];
|
||||||
|
@ -38,10 +32,21 @@ export function ProjectLayout(props: {
|
||||||
).length ?? 0;
|
).length ?? 0;
|
||||||
|
|
||||||
return (
|
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">
|
<h1 className="text-3xl font-bold">
|
||||||
{project.data.friendlyName}{" "}
|
{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})
|
({project.data.internalName})
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -81,30 +86,11 @@ export function ProjectLayout(props: {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</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 */}
|
{/* 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) => (
|
{project.data.services.map((service) => (
|
||||||
<Link
|
<ServiceCard service={service} key={service.id} />
|
||||||
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>
|
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{project.data.services.length == 0 && (
|
{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 { createContext, useContext } from "react";
|
||||||
import { type RouterOutputs } from "~/trpc/shared";
|
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>(
|
const ProjectContext = createContext<ProjectContextType>(
|
||||||
{} as unknown as ProjectContextType,
|
{} as unknown as ProjectContextType,
|
||||||
|
|
Loading…
Reference in a new issue