CluPilotCloud/app/Livewire/Admin/Provisioning.php

84 lines
2.9 KiB
PHP

<?php
namespace App\Livewire\Admin;
use App\Livewire\Concerns\BuildsRunSteps;
use App\Models\Host;
use App\Models\Order;
use App\Models\ProvisioningRun;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
#[Layout('layouts.admin')]
class Provisioning extends Component
{
use BuildsRunSteps;
#[On('echo-private:admin.runs,StepAdvanced')]
public function onStepAdvanced(): void
{
// A round-trip re-renders with fresh run state.
}
private function subjectLabel(ProvisioningRun $run): string
{
$subject = $run->subject;
if ($subject instanceof Order) {
return $subject->customer?->name ?? 'Order';
}
if ($subject instanceof Host) {
return $subject->name;
}
return class_basename($run->subject_type);
}
public function render()
{
$runs = ProvisioningRun::query()->latest('id')->limit(30)->get();
$active = $runs->first(fn (ProvisioningRun $r) => in_array(
$r->status, ['pending', 'running', 'waiting'], true
)) ?? $runs->first();
return view('livewire.admin.provisioning', [
'hasActive' => $active !== null && in_array($active->status, ['pending', 'running', 'waiting'], true),
'rows' => $runs->map(fn (ProvisioningRun $r) => [
'customer' => $this->subjectLabel($r),
'pipeline' => $r->pipeline,
'step' => $r->status === 'completed' ? '—' : $this->currentStepLabel($r),
'n' => ($r->current_step + 1).'/'.count(config('provisioning.pipelines.'.$r->pipeline, [])),
'attempt' => $r->attempt,
'state' => $this->runState($r),
])->all(),
'panel' => $active ? $this->panelFor($active) : null,
]);
}
/** Compact "current run" readout for the right column. */
private function panelFor(ProvisioningRun $run): array
{
$pipeline = config('provisioning.pipelines.'.$run->pipeline, []);
$total = max(count($pipeline), 1);
$current = min($run->current_step, $total - 1);
$completed = $run->status === ProvisioningRun::STATUS_COMPLETED;
$done = $completed ? $total : $current;
return [
'subject' => $this->subjectLabel($run),
'pipeline' => $run->pipeline,
'attempt' => $run->attempt,
'status' => $this->runState($run), // running|done|failed
'failed' => $run->status === ProvisioningRun::STATUS_FAILED,
'current' => $completed ? null : (isset($pipeline[$current]) ? __(app($pipeline[$current])->label()) : null),
'next' => isset($pipeline[$current + 1]) && ! $completed ? __(app($pipeline[$current + 1])->label()) : null,
'error' => $run->error,
'done' => $done,
'total' => $total,
'percent' => (int) round($done / $total * 100),
];
}
}