Deployments

This commit is contained in:
2026-01-02 12:53:36 +01:00
parent be750824c5
commit c2fd09188a
+27 -140
View File
@@ -12,95 +12,37 @@ import {
Plus,
GitBranch,
} from "lucide-react";
const deployments = [
{
id: "dep-001",
app: "api-gateway",
version: "v2.4.1",
previousVersion: "v2.4.0",
status: "running" as const,
deployedAt: "2024-01-15 14:32:18",
deployedBy: "ci/github-actions",
duration: "45s",
replicas: "3/3",
strategy: "rolling",
},
{
id: "dep-002",
app: "auth-service",
version: "v1.8.0",
previousVersion: "v1.7.9",
status: "running" as const,
deployedAt: "2024-01-15 14:18:42",
deployedBy: "[email protected]",
duration: "32s",
replicas: "2/2",
strategy: "rolling",
},
{
id: "dep-003",
app: "worker-queue",
version: "v3.1.2",
previousVersion: "v3.1.1",
status: "pending" as const,
deployedAt: "2024-01-15 13:58:05",
deployedBy: "ci/github-actions",
duration: "—",
replicas: "3/4",
strategy: "rolling",
},
{
id: "dep-004",
app: "metrics-collector",
version: "v1.2.0",
previousVersion: "v1.1.8",
status: "error" as const,
deployedAt: "2024-01-15 13:42:11",
deployedBy: "ci/github-actions",
duration: "—",
replicas: "0/2",
strategy: "rolling",
},
{
id: "dep-005",
app: "postgres-db",
version: "15-alpine",
previousVersion: "14-alpine",
status: "running" as const,
deployedAt: "2024-01-10 09:15:33",
deployedBy: "[email protected]",
duration: "2m 18s",
replicas: "1/1",
strategy: "recreate",
},
{
id: "dep-006",
app: "redis-cache",
version: "7-alpine",
previousVersion: "7-alpine",
status: "running" as const,
deployedAt: "2024-01-08 16:45:22",
deployedBy: "[email protected]",
duration: "18s",
replicas: "1/1",
strategy: "recreate",
},
];
import { useEffect, useState } from "react";
import { Deployment } from "@/lib/types";
import { getDeployments } from "@/core/server/deployment";
import { getApplications } from "@/core/application";
export default function DeploymentsPage() {
const [deployments, setDeployments] = useState<Deployment[]>([]);
useEffect(() => {
const fetch = async () => {
setDeployments(
(await getDeployments(await getApplications())).filter(
(d) => d !== null
)
);
};
fetch();
}, []);
return (
<DashboardLayout
title="Deployments"
subtitle="Deployment history and management"
>
{/* Header */}
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-6">
<div className="flex flex-row gap-3 items-center justify-between mb-6">
<Badge>{deployments.length} deployments</Badge>
<Button size="sm" className="gap-2 self-start sm:self-auto">
<Button size="sm" className="gap-2 self-auto">
<Plus className="w-4 h-4" />
<span className="hidden sm:inline">New Deployment</span>
New Deployment
</Button>
</div>
@@ -111,16 +53,7 @@ export default function DeploymentsPage() {
<table className="w-full">
<thead>
<tr className="border-b border-border">
{[
"Application",
"Version",
"Status",
"Replicas",
"Deployed",
"Duration",
"Deployed By",
"Actions",
].map((h) => (
{["Application", "Status", "Actions"].map((h) => (
<th
key={h}
className={`text-left text-xs text-muted-foreground uppercase tracking-wider py-3 px-4 ${
@@ -134,42 +67,16 @@ export default function DeploymentsPage() {
</thead>
<tbody>
{deployments.map((dep) => (
<tr key={dep.id} className="data-table-row">
<tr key={dep.image} className="data-table-row">
<td className="py-3 px-4">
<div className="flex items-center gap-2">
<Rocket className="w-4 h-4 text-muted-foreground" />
<span className="font-mono text-sm">{dep.app}</span>
</div>
</td>
<td className="py-3 px-4">
<div className="flex items-center gap-2">
<GitBranch className="w-3 h-3 text-muted-foreground" />
<span className="font-mono text-sm">{dep.version}</span>
<span className="text-[10px] text-muted-foreground">
← {dep.previousVersion}
</span>
<span className="font-mono text-sm">{dep.image}</span>
</div>
</td>
<td className="py-3 px-4">{dep.status}</td>
<td className="py-3 px-4 font-mono text-sm">
{dep.replicas}
</td>
<td className="py-3 px-4 font-mono text-xs text-muted-foreground">
{dep.deployedAt}
</td>
<td className="py-3 px-4 font-mono text-xs">
{dep.duration}
</td>
<td className="py-3 px-4 text-xs text-muted-foreground">
{dep.deployedBy}
</td>
<td className="py-3 px-4">
<div className="flex items-center justify-end gap-1">
<Button variant="ghost" size="icon-sm">
@@ -192,41 +99,21 @@ export default function DeploymentsPage() {
{/* Mobile cards */}
<div className="md:hidden divide-y divide-border">
{deployments.map((dep) => (
<div key={dep.id} className="p-4 space-y-3">
<div key={dep.image} className="p-4 space-y-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Rocket className="w-4 h-4 text-muted-foreground" />
<span className="font-mono text-sm">{dep.app}</span>
<span className="font-mono text-sm">{dep.image}</span>
</div>
{dep.status}
</div>
<div className="flex items-center gap-2 text-xs">
<GitBranch className="w-3 h-3 text-muted-foreground" />
<span className="font-mono">{dep.version}</span>
<span className="text-muted-foreground">
← {dep.previousVersion}
</span>
</div>
<div className="grid grid-cols-2 gap-2 text-xs">
<div>
<span className="text-muted-foreground">Replicas</span>
<div className="font-mono">{dep.replicas}</div>
</div>
<div>
<span className="text-muted-foreground">Duration</span>
<div className="font-mono">{dep.duration}</div>
</div>
<div>
<span className="text-muted-foreground">Deployed</span>
<div className="font-mono">{dep.deployedAt}</div>
</div>
{/* <div className="grid grid-cols-2 gap-2 text-xs">
<div>
<span className="text-muted-foreground">By</span>
<div className="truncate">{dep.deployedBy}</div>
</div>
</div>
</div> */}
<div className="flex justify-end gap-1 pt-2">
<Button variant="ghost" size="icon-sm">