203 lines
6.9 KiB
Vue
203 lines
6.9 KiB
Vue
<script setup lang="ts">
|
|
import { Head, Link } from '@inertiajs/vue3';
|
|
import { ArrowUpRight, History, PackagePlus } from 'lucide-vue-next';
|
|
import Heading from '@/components/Heading.vue';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@/components/ui/card';
|
|
import {
|
|
history as buildHistory,
|
|
index as dockerBuilderIndex,
|
|
} from '@/routes/docker-builder';
|
|
|
|
type DockerImageBuildHistoryItem = {
|
|
id: number;
|
|
image: string;
|
|
status: string;
|
|
status_label: string;
|
|
successful: boolean | null;
|
|
exit_code: number | null;
|
|
environment_count: number;
|
|
queued_at_human: string | null;
|
|
duration: string | null;
|
|
dockerfile_preview: string;
|
|
output_preview: string | null;
|
|
};
|
|
|
|
defineProps<{
|
|
builds: DockerImageBuildHistoryItem[];
|
|
}>();
|
|
|
|
defineOptions({
|
|
layout: {
|
|
breadcrumbs: [
|
|
{
|
|
title: 'Docker builder',
|
|
href: dockerBuilderIndex(),
|
|
},
|
|
{
|
|
title: 'Build history',
|
|
href: buildHistory(),
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
function statusVariant(
|
|
status: string,
|
|
): 'default' | 'secondary' | 'destructive' | 'outline' {
|
|
if (status === 'succeeded') {
|
|
return 'default';
|
|
}
|
|
|
|
if (status === 'failed') {
|
|
return 'destructive';
|
|
}
|
|
|
|
if (status === 'running') {
|
|
return 'secondary';
|
|
}
|
|
|
|
return 'outline';
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Head title="Build history" />
|
|
|
|
<div class="flex flex-1 flex-col gap-6 p-4">
|
|
<Heading
|
|
title="Build history"
|
|
description="Review saved Docker build jobs, the Dockerfiles they used, and the latest log output captured for each run."
|
|
/>
|
|
|
|
<div class="flex justify-end">
|
|
<Button as-child>
|
|
<Link :href="dockerBuilderIndex()">
|
|
<PackagePlus />
|
|
New build
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
|
|
<div
|
|
v-if="builds.length === 0"
|
|
class="rounded-xl border border-dashed border-border/70 p-10 text-center text-sm text-muted-foreground"
|
|
>
|
|
No Docker builds have been saved yet.
|
|
</div>
|
|
|
|
<div v-else class="grid gap-4 xl:grid-cols-2">
|
|
<Card
|
|
v-for="build in builds"
|
|
:key="build.id"
|
|
class="gap-0 overflow-hidden"
|
|
>
|
|
<CardHeader class="border-b">
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div class="space-y-1">
|
|
<CardTitle class="text-base break-all">
|
|
{{ build.image }}
|
|
</CardTitle>
|
|
<CardDescription>
|
|
{{
|
|
build.queued_at_human === null
|
|
? 'Queued recently'
|
|
: `Queued ${build.queued_at_human}`
|
|
}}
|
|
</CardDescription>
|
|
</div>
|
|
|
|
<Badge :variant="statusVariant(build.status)">
|
|
{{ build.status_label }}
|
|
</Badge>
|
|
</div>
|
|
</CardHeader>
|
|
|
|
<CardContent class="space-y-4 pt-6">
|
|
<div class="grid gap-3 sm:grid-cols-3">
|
|
<div class="rounded-lg border border-border/70 p-3">
|
|
<p class="text-xs text-muted-foreground uppercase">
|
|
Duration
|
|
</p>
|
|
<p class="mt-1 text-sm font-medium">
|
|
{{ build.duration ?? 'Waiting to start' }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rounded-lg border border-border/70 p-3">
|
|
<p class="text-xs text-muted-foreground uppercase">
|
|
Environment
|
|
</p>
|
|
<p class="mt-1 text-sm font-medium">
|
|
{{ build.environment_count }} variables
|
|
</p>
|
|
</div>
|
|
|
|
<div class="rounded-lg border border-border/70 p-3">
|
|
<p class="text-xs text-muted-foreground uppercase">
|
|
Exit code
|
|
</p>
|
|
<p class="mt-1 text-sm font-medium">
|
|
{{
|
|
build.exit_code === null
|
|
? 'Pending'
|
|
: build.exit_code
|
|
}}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid gap-3 lg:grid-cols-2">
|
|
<div class="rounded-lg border border-border/70 p-3">
|
|
<p
|
|
class="mb-2 text-xs text-muted-foreground uppercase"
|
|
>
|
|
Dockerfile
|
|
</p>
|
|
<pre
|
|
class="font-mono text-xs leading-6 whitespace-pre-wrap"
|
|
><code>{{ build.dockerfile_preview }}</code></pre>
|
|
</div>
|
|
|
|
<div class="rounded-lg border border-border/70 p-3">
|
|
<p
|
|
class="mb-2 text-xs text-muted-foreground uppercase"
|
|
>
|
|
Log preview
|
|
</p>
|
|
<pre
|
|
class="font-mono text-xs leading-6 whitespace-pre-wrap text-muted-foreground"
|
|
><code>{{
|
|
build.output_preview ?? 'No build output saved yet.'
|
|
}}</code></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end">
|
|
<Button variant="outline" as-child>
|
|
<Link
|
|
:href="
|
|
dockerBuilderIndex({
|
|
query: { build: build.id },
|
|
})
|
|
"
|
|
>
|
|
<History />
|
|
Open build
|
|
<ArrowUpRight />
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</template>
|