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, Plus,
GitBranch, GitBranch,
} from "lucide-react"; } from "lucide-react";
import { useEffect, useState } from "react";
const deployments = [ import { Deployment } from "@/lib/types";
{ import { getDeployments } from "@/core/server/deployment";
id: "dep-001", import { getApplications } from "@/core/application";
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",
},
];
export default function DeploymentsPage() { export default function DeploymentsPage() {
const [deployments, setDeployments] = useState<Deployment[]>([]);
useEffect(() => {
const fetch = async () => {
setDeployments(
(await getDeployments(await getApplications())).filter(
(d) => d !== null
)
);
};
fetch();
}, []);
return ( return (
<DashboardLayout <DashboardLayout
title="Deployments" title="Deployments"
subtitle="Deployment history and management" subtitle="Deployment history and management"
> >
{/* Header */} {/* 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> <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" /> <Plus className="w-4 h-4" />
<span className="hidden sm:inline">New Deployment</span> New Deployment
</Button> </Button>
</div> </div>
@@ -111,16 +53,7 @@ export default function DeploymentsPage() {
<table className="w-full"> <table className="w-full">
<thead> <thead>
<tr className="border-b border-border"> <tr className="border-b border-border">
{[ {["Application", "Status", "Actions"].map((h) => (
"Application",
"Version",
"Status",
"Replicas",
"Deployed",
"Duration",
"Deployed By",
"Actions",
].map((h) => (
<th <th
key={h} key={h}
className={`text-left text-xs text-muted-foreground uppercase tracking-wider py-3 px-4 ${ className={`text-left text-xs text-muted-foreground uppercase tracking-wider py-3 px-4 ${
@@ -134,42 +67,16 @@ export default function DeploymentsPage() {
</thead> </thead>
<tbody> <tbody>
{deployments.map((dep) => ( {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"> <td className="py-3 px-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Rocket className="w-4 h-4 text-muted-foreground" /> <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>
</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>
</div> </div>
</td> </td>
<td className="py-3 px-4">{dep.status}</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"> <td className="py-3 px-4">
<div className="flex items-center justify-end gap-1"> <div className="flex items-center justify-end gap-1">
<Button variant="ghost" size="icon-sm"> <Button variant="ghost" size="icon-sm">
@@ -192,41 +99,21 @@ export default function DeploymentsPage() {
{/* Mobile cards */} {/* Mobile cards */}
<div className="md:hidden divide-y divide-border"> <div className="md:hidden divide-y divide-border">
{deployments.map((dep) => ( {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 justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Rocket className="w-4 h-4 text-muted-foreground" /> <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> </div>
{dep.status} {dep.status}
</div> </div>
<div className="flex items-center gap-2 text-xs"> {/* <div className="grid grid-cols-2 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> <div>
<span className="text-muted-foreground">By</span> <span className="text-muted-foreground">By</span>
<div className="truncate">{dep.deployedBy}</div> <div className="truncate">{dep.deployedBy}</div>
</div> </div>
</div> </div> */}
<div className="flex justify-end gap-1 pt-2"> <div className="flex justify-end gap-1 pt-2">
<Button variant="ghost" size="icon-sm"> <Button variant="ghost" size="icon-sm">