Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
"use client";

import type { DeploymentStatus } from "@/lib/collections";
import { formatCpuParts, formatMemoryParts } from "@/lib/utils/deployment-formatters";
import { Bolt, Cloud, Grid, LayoutRight } from "@unkey/icons";
import { Button, InfoTooltip } from "@unkey/ui";
import { ActiveDeploymentCard } from "../../../../components/active-deployment-card";
import {
type DeploymentStatus,
DeploymentStatusBadge,
} from "../../../../components/deployment-status-badge";
import { DeploymentStatusBadge } from "../../../../components/deployment-status-badge";
import { InfoChip } from "../../../../components/info-chip";
import { RegionFlags } from "../../../../components/region-flags";
import { Section, SectionHeader } from "../../../../components/section";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function DeploymentProgress({ stepsData }: { stepsData?: StepsData }) {

const { getDomainsForDeployment, projectId } = useProjectData();

const [now, setNow] = useState(0);
const [now, setNow] = useState(Date.now);
useEffect(() => {
if (isFailed) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"use client";

import { cn } from "@/lib/utils";
import { formatCompoundDuration } from "@/lib/utils/metric-formatters";
import { Check, CircleHalfDottedClock, TriangleWarning2 } from "@unkey/icons";
import { Badge, Loading, SettingCard } from "@unkey/ui";
import ms from "ms";

type DeploymentStepProps = {
icon: React.ReactNode;
Expand Down Expand Up @@ -87,7 +87,9 @@ export function DeploymentStep({
contentWidth="w-fit"
>
<div className="flex items-center gap-4 justify-end w-full absolute right-14">
<span className="text-gray-10 text-xs">{duration ? ms(duration) : null}</span>
<span className="text-gray-10 text-xs">
{duration !== null && duration !== undefined ? formatCompoundDuration(duration) : null}
</span>
{status === "completed" ? (
<Check iconSize="md-regular" className="text-success-11" />
) : status === "started" ? (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { DeploymentStatus } from "@/lib/collections";
import type { StepsData } from "./(deployment-progress)/deployment-progress";

const DEPLOYMENT_STATUSES: ReadonlySet<string> = new Set<DeploymentStatus>([
"pending",
"starting",
"building",
"deploying",
"network",
"finalizing",
"ready",
"failed",
]);

function isDeploymentStatus(value: string): value is DeploymentStatus {
return DEPLOYMENT_STATUSES.has(value);
}

export function deriveStatusFromSteps(
steps: StepsData | undefined,
fallback: string,
): DeploymentStatus {
if (!steps) {
return isDeploymentStatus(fallback) ? fallback : "pending";
}

const { queued, building, deploying, network, finalizing, starting } = steps;

if ([queued, building, deploying, network, finalizing, starting].some((s) => s?.error)) {
return "failed";
}
if (finalizing && !finalizing.endedAt) {
return "finalizing";
}
if (finalizing?.completed) {
return "ready";
}
if (network && !network.endedAt) {
return "network";
}
if (deploying && !deploying.endedAt) {
return "deploying";
}
if (building && !building.endedAt) {
return "building";
}
if (starting && !starting.endedAt) {
return "starting";
}
if (queued && !queued.endedAt) {
return "pending";
}

return isDeploymentStatus(fallback) ? fallback : "pending";
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import { trpc } from "@/lib/trpc/client";
import { useEffect, useMemo } from "react";
import { DeploymentDomainsCard } from "../../../components/deployment-domains-card";
import type { DeploymentStatus } from "../../../components/deployment-status-badge";
import { ProjectContentWrapper } from "../../../components/project-content-wrapper";
import { useProjectData } from "../../data-provider";
import { DeploymentInfo } from "./(deployment-progress)/deployment-info";
import { DeploymentProgress, type StepsData } from "./(deployment-progress)/deployment-progress";
import { DeploymentProgress } from "./(deployment-progress)/deployment-progress";
import { DeploymentNetworkSection } from "./(overview)/components/sections/deployment-network-section";
import { deriveStatusFromSteps } from "./deployment-utils";
import { useDeployment } from "./layout-provider";

export default function DeploymentOverview() {
Expand Down Expand Up @@ -49,45 +49,3 @@ export default function DeploymentOverview() {
</ProjectContentWrapper>
);
}

const DEPLOYMENT_STATUSES: ReadonlySet<string> = new Set<DeploymentStatus>([
"pending",
"building",
"deploying",
"network",
"ready",
"failed",
]);

function isDeploymentStatus(value: string): value is DeploymentStatus {
return DEPLOYMENT_STATUSES.has(value);
}

function deriveStatusFromSteps(steps: StepsData | undefined, fallback: string): DeploymentStatus {
if (!steps) {
return isDeploymentStatus(fallback) ? fallback : "pending";
}

const { queued, building, deploying, network } = steps;

if ([queued, building, deploying, network].some((s) => s?.error)) {
return "failed";
}
if (network?.completed) {
return "ready";
}
if (network && !network.endedAt) {
return "network";
}
if (deploying && !deploying.endedAt) {
return "deploying";
}
if (building && !building.endedAt) {
return "building";
}
if (queued && !queued.endedAt) {
return "pending";
}

return isDeploymentStatus(fallback) ? fallback : "pending";
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { DeploymentStatus } from "@/lib/collections/deploy/deployment-status";
import { InfoTooltip } from "@unkey/ui";
import { useProjectData } from "../../../../data-provider";
import type { DeploymentStatus } from "../../../filters.schema";
import { DomainListSkeleton } from "./skeletons";

type Props = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { cn } from "@unkey/ui/src/lib/utils";
import dynamic from "next/dynamic";
import { useRouter } from "next/navigation";
import { useCallback, useMemo } from "react";
import { DeploymentStatusBadge } from "../../../../components/deployment-status-badge";
import { Avatar } from "../../../../components/git-avatar";
import { StatusIndicator } from "../../../../components/status-indicator";
import { useProjectData } from "../../../data-provider";
import { useDeployments } from "../../hooks/use-deployments";
import { DeploymentStatusBadge } from "./components/deployment-status-badge";
import { DomainList } from "./components/domain_list";
import { EnvStatusBadge } from "./components/env-status-badge";
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,9 @@ import type {
} from "@/components/logs/validation/filter.types";
import { parseAsFilterValueArray } from "@/components/logs/validation/utils/nuqs-parsers";
import { createFilterOutputSchema } from "@/components/logs/validation/utils/structured-output-schema-generator";
import type { DeploymentStatus } from "@/lib/collections/deploy/deployment-status";
import { z } from "zod";

export const DEPLOYMENT_STATUSES = [
"pending",
"starting",
"building",
"deploying",
"network",
"finalizing",
"ready",
"failed",
] as const;

// Define grouped statuses for client filtering
const GROUPED_DEPLOYMENT_STATUSES = [
"pending",
Expand All @@ -28,7 +18,6 @@ const GROUPED_DEPLOYMENT_STATUSES = [

const DEPLOYMENT_ENVIRONMENTS = ["production", "preview"] as const;

export type DeploymentStatus = (typeof DEPLOYMENT_STATUSES)[number];
export type GroupedDeploymentStatus = (typeof GROUPED_DEPLOYMENT_STATUSES)[number];
export type DeploymentEnvironment = (typeof DEPLOYMENT_ENVIRONMENTS)[number];

Expand Down
Loading