build logs
This commit is contained in:
202
resources/js/pages/docker/BuildHistory.vue
Normal file
202
resources/js/pages/docker/BuildHistory.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user