Layout primitives
Pipeline Card code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/pipeline-card.blade.php
@props([
'title',
'branch' => null,
'commit' => null,
'meta' => null,
'status' => null,
'statusVariant' => 'brand',
'steps' => [],
'href' => null,
])
@php
/*
| Compact CI/CD pipeline card with branch metadata and vertical run steps.
| Useful for deploy queues, build monitors and release dashboards.
|
| statusVariant: gray, brand, green, red, amber, blue
| steps: array of [
| 'label' => 'Build',
| 'state' => 'complete', // complete, running, pending, failed
| 'duration' => '42s', // optional
| 'progress' => 78, // optional, for running steps
| ]
|
| Usage:
| <x-ui.pipeline-card
| title="Production deploy"
| branch="main"
| commit="fc4a19f"
| meta="Triggered 6m ago by deploy-bot"
| status="Deploying"
| :steps="[
| ['label' => 'Build', 'state' => 'complete', 'duration' => '42s'],
| ['label' => 'Deploy', 'state' => 'running', 'progress' => 78],
| ['label' => 'Smoke tests', 'state' => 'pending'],
| ]"
| href="/deployments/842"
| />
*/
$stateStyles = [
'complete' => 'bg-green-50 text-green-600 dark:bg-green-950/60 dark:text-green-400',
'running' => 'bg-brand-50 text-brand-600 dark:bg-brand-950/60 dark:text-brand-400',
'pending' => 'border border-gray-200 bg-white text-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-600',
'failed' => 'bg-red-50 text-red-600 dark:bg-red-950/60 dark:text-red-400',
];
$stateIcons = [
'complete' => 'check',
'running' => 'circle-notch',
'pending' => null,
'failed' => 'x',
];
@endphp
<x-ui.card padding="sm" :href="$href" {{ $attributes }}>
<div class="flex items-start justify-between gap-3">
<div class="min-w-0">
<h3 class="truncate text-sm font-semibold text-gray-900 dark:text-white">{{ $title }}</h3>
@if ($branch || $commit)
<p class="mt-1 flex min-w-0 items-center gap-1.5 font-mono text-[11px] text-gray-500 dark:text-gray-400">
@if ($branch)
<x-ui.icon name="git-branch" size="sm" class="shrink-0" />
<span class="truncate">{{ $branch }}</span>
@endif
@if ($branch && $commit)
<span class="text-gray-300 dark:text-gray-600">·</span>
@endif
@if ($commit)
<span class="truncate">{{ $commit }}</span>
@endif
</p>
@endif
@if ($meta)
<p class="mt-0.5 truncate text-xs text-gray-500 dark:text-gray-400">{{ $meta }}</p>
@endif
</div>
@if ($status)
<x-ui.badge :variant="$statusVariant" size="sm" class="shrink-0">{{ $status }}</x-ui.badge>
@endif
</div>
@if (count($steps) > 0)
<ol class="mt-4 min-w-0 space-y-2.5 border-t border-gray-100 pt-4 dark:border-gray-800">
@foreach ($steps as $step)
@php
$state = $step['state'] ?? 'pending';
$isRunning = $state === 'running';
@endphp
<li class="min-w-0 space-y-1.5">
<div class="flex items-center gap-2.5">
<span @class([
'flex h-4 w-4 shrink-0 items-center justify-center rounded-full',
$stateStyles[$state] ?? $stateStyles['pending'],
])>
@if ($stateIcons[$state] ?? null)
<x-ui.icon
:name="$stateIcons[$state]"
weight="bold"
size="xs"
@class(['animate-spin' => $isRunning])
/>
@endif
</span>
<span @class([
'min-w-0 flex-1 truncate text-xs',
$isRunning ? 'font-medium text-gray-900 dark:text-white' : 'text-gray-600 dark:text-gray-400',
])>{{ $step['label'] }}</span>
@if ($isRunning && isset($step['progress']))
<span class="shrink-0 text-xs font-medium tabular-nums text-brand-600 dark:text-brand-400">{{ $step['progress'] }}%</span>
@elseif (filled($step['duration'] ?? null))
<span class="shrink-0 text-xs tabular-nums text-gray-400 dark:text-gray-500">{{ $step['duration'] }}</span>
@elseif ($state === 'pending')
<span class="shrink-0 text-xs text-gray-400 dark:text-gray-500">Pending</span>
@endif
</div>
@if ($isRunning && isset($step['progress']))
<div class="pl-6">
<x-ui.progress :value="$step['progress']" size="sm" />
</div>
@endif
</li>
@endforeach
</ol>
@endif
{{ $slot }}
</x-ui.card>