Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
"use client";

import { type Deployment, collection } from "@/lib/collections";
import { shortenId } from "@/lib/shorten-id";
import { trpc } from "@/lib/trpc/client";
import { CircleInfo, Cloud, CodeBranch, CodeCommit } from "@unkey/icons";
import { CircleInfo, CodeBranch, CodeCommit } from "@unkey/icons";
import { Badge, Button, DialogContainer, toast } from "@unkey/ui";
import { StatusIndicator } from "../../details/active-deployment-card/status-indicator";

type DeploymentSectionProps = {
title: string;
deployment: Deployment;
isActive: boolean;
showSignal?: boolean;
};

const DeploymentSection = ({ title, deployment, isActive, showSignal }: DeploymentSectionProps) => (
<div className="space-y-2">
<div className="flex items-center gap-2">
<h3 className="text-[13px] text-grayA-11">{title}</h3>
<CircleInfo size="sm-regular" className="text-gray-9" />
</div>
<DeploymentCard deployment={deployment} isActive={isActive} showSignal={showSignal} />
</div>
);

type RollbackDialogProps = {
isOpen: boolean;
Expand Down Expand Up @@ -84,81 +103,57 @@ export const RollbackDialog = ({
</div>
}
>
<div className="space-y-6">
{/* Current active deployment */}
<div className="space-y-2">
<div className="flex items-center gap-2">
<h3 className="text-sm font-medium text-gray-12">Current active deployment</h3>
<CircleInfo size="sm-regular" className="text-gray-9" />
</div>
<div className="space-y-9">
<DeploymentSection
title="Current active deployment"
deployment={currentDeployment}
isActive={true}
showSignal={true}
/>
<DeploymentSection title="Target version" deployment={deployment} isActive={false} />
</div>
</DialogContainer>
);
};

<div className="bg-gray-2 border border-gray-6 rounded-lg p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Cloud size="md-regular" className="text-gray-11 bg-gray-3 rounded" />
<div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-gray-12">{currentDeployment.id}</span>
<Badge variant="success" className="text-successA-11 font-medium">
<div className="flex items-center gap-2">Active</div>
</Badge>
</div>
<div className="text-xs text-gray-11">
{currentDeployment?.gitCommitMessage || "Current active deployment"}
</div>
</div>
</div>
<div className="flex flex-col gap-1.5">
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded text-xs text-gray-11">
<CodeBranch size="sm-regular" />
<span>{currentDeployment.gitBranch}</span>
</div>
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded text-xs text-gray-11">
<CodeCommit size="sm-regular" />
<span>{currentDeployment.gitCommitSha}</span>
</div>
</div>
</div>
</div>
</div>
type DeploymentCardProps = {
deployment: Deployment;
isActive: boolean;
showSignal?: boolean;
};

{/* Target version */}
<div className="space-y-2">
const DeploymentCard = ({ deployment, isActive, showSignal }: DeploymentCardProps) => (
<div className="bg-white dark:bg-black border border-grayA-5 rounded-lg p-4 relative">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<StatusIndicator withSignal={showSignal} />
<div>
<div className="flex items-center gap-2">
<h3 className="text-sm font-medium text-gray-12">Target version</h3>
<CircleInfo size="sm-regular" className="text-gray-9" />
<span className="text-xs text-accent-12 font-mono">
{`${deployment.id.slice(0, 3)}...${deployment.id.slice(-4)}`}
</span>
<Badge
variant={isActive ? "success" : "primary"}
className={`px-1.5 ${isActive ? "text-successA-11" : "text-grayA-11"}`}
>
{isActive ? "Active" : "Preview"}
</Badge>
</div>

<div className="bg-gray-2 border border-gray-6 rounded-lg p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Cloud size="md-regular" className="text-gray-11 bg-gray-3 rounded" />
<div>
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-gray-12">{deployment.id}</span>
<Badge variant="primary" className="text-primaryA-11 font-medium">
<div className="flex items-center gap-1">Inactive</div>
</Badge>
</div>
<div className="text-xs text-gray-11">
{deployment.gitCommitMessage || "Target deployment"}
</div>
</div>
</div>
<div className="flex flex-col gap-1.5">
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded text-xs text-gray-11">
<CodeBranch size="sm-regular" />
<span>{deployment.gitBranch}</span>
</div>
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded text-xs text-gray-11">
<CodeCommit size="sm-regular" />
<span>{deployment.gitCommitSha}</span>
</div>
</div>
</div>
<div className="text-xs text-grayA-9">
{deployment.gitCommitMessage || `${isActive ? "Current active" : "Target"} deployment`}
</div>
</div>
</div>
</DialogContainer>
);
};
<div className="flex gap-1.5">
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded-md text-xs text-grayA-11 max-w-[100px]">
<CodeBranch size="sm-regular" className="shrink-0 text-gray-12" />
<span className="truncate">{deployment.gitBranch}</span>
</div>
<div className="flex items-center gap-1.5 px-2 py-1 bg-gray-3 rounded-md text-xs text-grayA-11">
<CodeCommit size="sm-regular" className="shrink-0 text-gray-12" />
<span>{shortenId(deployment.gitCommitSha ?? "")}</span>
</div>
</div>
</div>
</div>
);
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ export const DeploymentsList = ({ projectId }: Props) => {
} | null>(null);
const isCompactView = useIsMobile({ breakpoint: COMPACT_BREAKPOINT });

const columns: Column<{ deployment: Deployment; environment?: Environment }>[] = useMemo(() => {
const columns: Column<{
deployment: Deployment;
environment?: Environment;
}>[] = useMemo(() => {
return [
{
key: "deployment_id",
Expand Down Expand Up @@ -386,7 +389,10 @@ export const DeploymentsList = ({ projectId }: Props) => {
render: ({
deployment,
environment,
}: { deployment: Deployment; environment?: Environment }) => {
}: {
deployment: Deployment;
environment?: Environment;
}) => {
return (
<DeploymentListTableActions
deployment={deployment}
Expand All @@ -397,7 +403,7 @@ export const DeploymentsList = ({ projectId }: Props) => {
},
},
];
}, [selectedDeployment?.deployment.id, isCompactView, deployments, activeDeployment]);
}, [selectedDeployment?.deployment.id, isCompactView, activeDeployment, activeDeploymentId]);

return (
<VirtualTable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,29 @@ export const statusIndicator = (
) => {
switch (status) {
case "pending":
return { variant: "warning" as const, icon: CircleWarning, text: "Queued" };
return {
variant: "warning" as const,
icon: CircleWarning,
text: "Queued",
};
case "building":
return { variant: "warning" as const, icon: CircleWarning, text: "Building" };
return {
variant: "warning" as const,
icon: CircleWarning,
text: "Building",
};
case "deploying":
return { variant: "warning" as const, icon: CircleWarning, text: "Deploying" };
return {
variant: "warning" as const,
icon: CircleWarning,
text: "Deploying",
};
case "network":
return { variant: "warning" as const, icon: CircleWarning, text: "Assigning Domains" };
return {
variant: "warning" as const,
icon: CircleWarning,
text: "Assigning Domains",
};
case "ready":
return { variant: "success" as const, icon: CircleCheck, text: "Ready" };
case "failed":
Expand Down Expand Up @@ -84,7 +100,7 @@ export const ActiveDeploymentCard: React.FC<Props> = ({ deploymentId }) => {
<Card className="rounded-[14px] pt-[14px] flex justify-between flex-col overflow-hidden border-gray-4">
<div className="flex w-full justify-between items-center px-[22px]">
<div className="flex gap-5 items-center">
<StatusIndicator />
<StatusIndicator withSignal />
<div className="flex flex-col gap-1">
<div className="text-accent-12 font-medium text-xs">{deployment.id}</div>
<div className="text-gray-9 text-xs">TODO</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import { Cloud } from "@unkey/icons";
import { cn } from "@unkey/ui/src/lib/utils";

export function StatusIndicator() {
export function StatusIndicator({
withSignal = false,
}: {
withSignal?: boolean;
}) {
return (
<div className="relative">
<div className="size-5 rounded flex items-center justify-center cursor-pointer border border-grayA-3 transition-all duration-100 bg-grayA-3">
<Cloud size="sm-regular" className="text-gray-12" />
</div>
<div className="absolute -top-0.5 -right-0.5">
{[0, 0.15, 0.3, 0.45].map((delay, index) => (
<div
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
key={index}
className={cn(
"absolute inset-0 size-2 rounded-full",
index === 0 && "bg-successA-9 opacity-75",
index === 1 && "bg-successA-10 opacity-60",
index === 2 && "bg-successA-11 opacity-40",
index === 3 && "bg-successA-12 opacity-25",
)}
style={{
animation: "ping 2s cubic-bezier(0, 0, 0.2, 1) infinite",
animationDelay: `${delay}s`,
}}
/>
))}
<div className="relative size-2 bg-successA-9 rounded-full" />
</div>
{withSignal && (
<div className="absolute -top-0.5 -right-0.5">
{[0, 0.15, 0.3, 0.45].map((delay, index) => (
<div
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
key={index}
className={cn(
"absolute inset-0 size-2 rounded-full",
index === 0 && "bg-successA-9 opacity-75",
index === 1 && "bg-successA-10 opacity-60",
index === 2 && "bg-successA-11 opacity-40",
index === 3 && "bg-successA-12 opacity-25",
)}
style={{
animation: "ping 2s cubic-bezier(0, 0, 0.2, 1) infinite",
animationDelay: `${delay}s`,
}}
/>
))}
<div className="relative size-2 bg-successA-9 rounded-full" />
</div>
)}
</div>
);
}