From e243292eb5b5526ee7b10a6723dad6e7ada16cbb Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Wed, 30 Apr 2025 21:24:33 -0700 Subject: [PATCH] refactor: system table cell uses new jobs --- .../deployments/TableDeployments.tsx | 3 +- .../TableDeployments.tsx | 13 +- .../DeploymentEnvironmentCell.tsx | 216 ++++-------------- packages/api/src/router/system-table.ts | 68 ++++++ packages/api/src/router/system.ts | 2 + 5 files changed, 124 insertions(+), 178 deletions(-) create mode 100644 packages/api/src/router/system-table.ts diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx index 5ebe30f21..60722de8c 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx @@ -228,9 +228,8 @@ const DeploymentTable: React.FC<{ })} > diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx index 59ecaf4d8..71fef70da 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx @@ -208,14 +208,11 @@ const DeploymentTable: React.FC<{ /> {environments.map((env) => ( -
- -
+
))} {directories.map((dir) => ( diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx index 762c599af..856ced664 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx @@ -1,196 +1,81 @@ "use client"; -import type * as SCHEMA from "@ctrlplane/db/schema"; import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { - IconAlertCircle, - IconCube, - IconProgressCheck, -} from "@tabler/icons-react"; +import { useParams } from "next/navigation"; +import { format } from "date-fns"; import { useInView } from "react-intersection-observer"; import { Skeleton } from "@ctrlplane/ui/skeleton"; -import { ApprovalDialog } from "~/app/[workspaceSlug]/(app)/(deploy)/_components/deployment-version/ApprovalDialog"; -import { DeploymentVersionDropdownMenu } from "~/app/[workspaceSlug]/(app)/(deploy)/_components/deployment-version/DeploymentVersionDropdownMenu"; import { urls } from "~/app/urls"; import { api } from "~/trpc/react"; -import { Release } from "./ReleaseInfo"; +import { StatusIcon } from "./StatusIcon"; + +const CellSkeleton: React.FC = () => ( +
+ +
+ + +
+
+); type DeploymentEnvironmentCellProps = { - environment: SCHEMA.Environment; - deployment: SCHEMA.Deployment; - workspace: SCHEMA.Workspace; + environmentId: string; + deployment: { id: string; slug: string }; systemSlug: string; }; const DeploymentEnvironmentCell: React.FC = ({ - environment, + environmentId, deployment, - workspace, systemSlug, }) => { - const { data: deploymentVersion, isLoading: isReleaseLoading } = - api.deployment.version.latest.byDeploymentAndEnvironment.useQuery({ - deploymentId: deployment.id, - environmentId: environment.id, - }); - - const { data: statuses, isLoading: isStatusesLoading } = - api.deployment.version.status.byEnvironmentId.useQuery( - { versionId: deploymentVersion?.id ?? "", environmentId: environment.id }, - { refetchInterval: 2_000, enabled: deploymentVersion != null }, - ); + const { workspaceSlug } = useParams<{ workspaceSlug: string }>(); - const deploy = api.deployment.version.deploy.toEnvironment.useMutation(); - const router = useRouter(); + console.log(environmentId, deployment, systemSlug); - const isLoading = isStatusesLoading || isReleaseLoading; - - if (isLoading) - return ( -
- -
- - -
-
- ); - - if (deploymentVersion == null) - return ( -

No versions released

- ); + const { data, isLoading } = api.system.table.cell.useQuery({ + environmentId, + deploymentId: deployment.id, + }); - const envResourcesUrl = urls - .workspace(workspace.slug) + const deploymentUrls = urls + .workspace(workspaceSlug) .system(systemSlug) - .environment(environment.id) - .resources(); + .deployment(deployment.slug); + + if (isLoading) return ; - if (deploymentVersion.resourceCount === 0) + if (data == null) return ( -
-
- -
-
-
- {deploymentVersion.tag} -
-
No resources
-
-
+ No jobs ); - const isAlreadyDeployed = statuses != null && statuses.length > 0; - - const hasJobAgent = deployment.jobAgentId != null; - - const isPendingApproval = - deploymentVersion.approval != null && - deploymentVersion.approval.status === "pending"; - - const showRelease = isAlreadyDeployed && !isPendingApproval; - - if (showRelease) - return ( -
- s.job.status)} - /> -
- ); - - if (!hasJobAgent) - return ( -
- No job agent -
- ); - - if (deploymentVersion.approval != null && isPendingApproval) - return ( - -
-
-
- -
-
-
- - {deploymentVersion.tag} - -
-
- Approval required -
-
-
- - -
-
- ); + const versionUrl = deploymentUrls.release(data.versionId).baseUrl(); return ( -
-
- deploy - .mutateAsync({ - environmentId: environment.id, - versionId: deploymentVersion.id, - }) - .then(() => router.refresh()) - } - // disabled={deploy.isPending} +
+ -
-
- + +
+
+ {data.versionTag}
-
-
- {deploymentVersion.tag} -
-
Click to deploy
+
+ {format(data.versionCreatedAt, "MMM d, hh:mm aa")}
- - -
+
); }; @@ -201,16 +86,11 @@ export const LazyDeploymentEnvironmentCell: React.FC< const { ref, inView } = useInView(); return ( -
- {!inView && ( -
- -
- - -
-
- )} +
+ {!inView && } {inView && }
); diff --git a/packages/api/src/router/system-table.ts b/packages/api/src/router/system-table.ts new file mode 100644 index 000000000..3fb134f4c --- /dev/null +++ b/packages/api/src/router/system-table.ts @@ -0,0 +1,68 @@ +import { z } from "zod"; + +import { and, desc, eq, sql, takeFirstOrNull } from "@ctrlplane/db"; +import * as schema from "@ctrlplane/db/schema"; +import { Permission } from "@ctrlplane/validators/auth"; + +import { createTRPCRouter, protectedProcedure } from "../trpc"; + +export const systemTableRouter = createTRPCRouter({ + cell: protectedProcedure + .input( + z.object({ + environmentId: z.string().uuid(), + deploymentId: z.string().uuid(), + }), + ) + .meta({ + authorizationCheck: ({ canUser, input }) => + canUser + .perform(Permission.DeploymentGet) + .on({ type: "deployment", id: input.deploymentId }), + }) + .query(({ ctx, input }) => { + const { deploymentId, environmentId } = input; + + return ctx.db + .select({ + statuses: sql< + schema.JobStatus[] + >`json_agg(distinct ${schema.job.status})`, + versionId: schema.deploymentVersion.id, + versionName: schema.deploymentVersion.name, + versionCreatedAt: schema.deploymentVersion.createdAt, + versionTag: schema.deploymentVersion.tag, + }) + .from(schema.job) + .innerJoin( + schema.releaseJob, + eq(schema.releaseJob.jobId, schema.job.id), + ) + .innerJoin( + schema.release, + eq(schema.release.id, schema.releaseJob.releaseId), + ) + .innerJoin( + schema.versionRelease, + eq(schema.release.versionReleaseId, schema.versionRelease.id), + ) + .innerJoin( + schema.deploymentVersion, + eq(schema.versionRelease.versionId, schema.deploymentVersion.id), + ) + .innerJoin( + schema.releaseTarget, + eq(schema.versionRelease.releaseTargetId, schema.releaseTarget.id), + ) + .where( + and( + eq(schema.releaseTarget.deploymentId, deploymentId), + eq(schema.releaseTarget.environmentId, environmentId), + ), + ) + .groupBy(schema.deploymentVersion.id) + .orderBy(desc(schema.deploymentVersion.createdAt)) + .limit(1) + .then(takeFirstOrNull); + }), +}); diff --git a/packages/api/src/router/system.ts b/packages/api/src/router/system.ts index 6fa6bfc4b..c89391d6e 100644 --- a/packages/api/src/router/system.ts +++ b/packages/api/src/router/system.ts @@ -36,6 +36,7 @@ import { import { createTRPCRouter, protectedProcedure } from "../trpc"; import { directoryRouter } from "./directory"; +import { systemTableRouter } from "./system-table"; export const systemRouter = createTRPCRouter({ list: protectedProcedure @@ -315,4 +316,5 @@ export const systemRouter = createTRPCRouter({ }), directory: directoryRouter, + table: systemTableRouter, });