feat: aggiunge launcher esterno per aggiornamenti supporto

This commit is contained in:
michele 2026-04-05 08:37:17 +00:00
parent 04e6c71f78
commit 50941f1130
4 changed files with 203 additions and 1 deletions

View File

@ -0,0 +1,22 @@
<?php
namespace App\Filament\Pages\Supporto;
use BackedEnum;
use UnitEnum;
class AggiornamentoLauncher extends Modifiche
{
protected static ?string $navigationLabel = 'Aggiornamento Nodo';
protected static ?string $title = 'Launcher Aggiornamento Nodo';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-arrow-path';
protected static UnitEnum|string|null $navigationGroup = 'Supporto';
protected static ?int $navigationSort = 29;
protected static ?string $slug = 'supporto/aggiornamento-nodo';
protected string $view = 'filament.pages.supporto.aggiornamento-launcher';
}

View File

@ -230,7 +230,7 @@ public function canRunUpdate(): bool
{
$user = Auth::user();
return $user instanceof User
return is_object($user)
&& method_exists($user, 'hasAnyRole')
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore']);
}

View File

@ -0,0 +1,174 @@
<x-filament-panels::page>
@php($supportUpdateAuthUser = auth()->user())
@php($supportCanRunUpdate = $supportUpdateAuthUser && method_exists($supportUpdateAuthUser, 'hasAnyRole') && $supportUpdateAuthUser->hasAnyRole(['super-admin', 'admin', 'amministratore']))
<div class="space-y-4 text-xs">
<div class="rounded-xl border border-sky-200 bg-sky-50 p-4">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<div class="text-sm font-semibold text-sky-900">Launcher esterno per update e sync Git</div>
<div class="mt-1 text-[11px] text-sky-800">
Usa questa pagina per lanciare aggiornamenti senza restare dentro la pagina completa Modifiche mentre Livewire e i file vengono riallineati.
</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ \App\Filament\Pages\Supporto\Modifiche::getUrl(panel: 'admin-filament') }}" class="inline-flex items-center rounded-md bg-white px-3 py-1.5 text-xs font-medium text-sky-900 ring-1 ring-sky-200 hover:bg-sky-100">
Apri Modifiche completo
</a>
<x-filament::button size="sm" color="gray" wire:click="reloadDashboardData">
Rileggi stato
</x-filament::button>
</div>
</div>
@if(! $supportCanRunUpdate)
<div class="mt-3 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-[11px] text-amber-900">
I lanci update/sync sono abilitati solo per super-admin, admin e amministratore.
</div>
@endif
</div>
<div class="grid gap-4 xl:grid-cols-[1.2fr_0.8fr]">
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold text-slate-900">Sync Git da Gitea</div>
<div class="mt-1 text-[11px] text-slate-500">Flusso consigliato per staging e nodi interni.</div>
<div class="mt-3 grid gap-2 sm:grid-cols-3">
<label class="block">
<span class="mb-1 block text-[11px] font-medium">Remote</span>
<input type="text" wire:model="gitRemote" class="w-full rounded-md border-gray-300 text-xs" />
</label>
<label class="block">
<span class="mb-1 block text-[11px] font-medium">Branch</span>
<input type="text" wire:model="gitBranch" class="w-full rounded-md border-gray-300 text-xs" />
</label>
<label class="inline-flex items-center gap-2 rounded-md border bg-white px-2 py-1.5 text-[11px] sm:mt-6">
<input type="checkbox" wire:model="gitForce" class="rounded border-gray-300" />
Force con working tree sporco
</label>
</div>
<div class="mt-3 flex flex-wrap gap-2">
<x-filament::button size="sm" wire:click="runGitSync" :disabled="!$supportCanRunUpdate">
Aggiorna staging da Gitea
</x-filament::button>
<x-filament::button size="sm" color="info" wire:click="refreshGitSyncProgress" :disabled="!$this->gitSyncInProgress">
Aggiorna avanzamento Git
</x-filament::button>
</div>
@if($this->gitSyncInProgress)
<div class="mt-3 rounded-lg border bg-slate-50 p-3" wire:poll.2s="refreshGitSyncProgress">
@else
<div class="mt-3 rounded-lg border bg-slate-50 p-3">
@endif
<div class="mb-1 flex items-center justify-between text-[11px] text-gray-600">
<span class="font-semibold">Avanzamento sync Git</span>
<span class="font-mono">{{ (int) $this->gitSyncProgressPercent }}%</span>
</div>
<div class="h-2 w-full overflow-hidden rounded bg-gray-200">
<div class="h-2 {{ $this->gitSyncProgressStatus === 'failed' ? 'bg-rose-500' : 'bg-emerald-500' }}" style="width: {{ max(0, min(100, (int) $this->gitSyncProgressPercent)) }}%"></div>
</div>
<div class="mt-1 text-[11px] text-gray-600">{{ $this->gitSyncProgressMessage }}</div>
@if(filled($this->lastGitSyncIssue))
<div class="mt-2 rounded border border-amber-300 bg-amber-50 px-2 py-2 text-[11px] text-amber-900">{{ $this->lastGitSyncIssue }}</div>
@endif
</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold text-slate-900">Stato nodo</div>
<div class="mt-3 space-y-1 text-[11px] text-slate-600">
<div>Branch locale: <span class="font-mono font-medium">{{ $this->gitCurrentBranch ?? '-' }}</span></div>
<div>Commit locale: <span class="font-mono font-medium">{{ $this->gitCurrentCommit ?? '-' }}</span></div>
<div>Commit remoto: <span class="font-mono font-medium">{{ $this->gitRemoteCommit ?? '-' }}</span></div>
<div>Tracking: <span class="font-medium">{{ $this->gitAheadBehind }}</span></div>
<div>Working tree: <span class="font-medium {{ $this->gitWorkingTreeDirty ? 'text-rose-700' : 'text-emerald-700' }}">{{ $this->gitWorkingTreeDirty ? 'sporco' : 'pulito' }}</span></div>
<div>Ultima sync Git: <span class="font-medium">{{ $this->lastGitSyncAt ?? '-' }}</span></div>
<div>Ultimo update: <span class="font-medium">{{ $this->lastUpdateAt ?? '-' }}</span></div>
</div>
</div>
</div>
<div class="grid gap-4 xl:grid-cols-[1.2fr_0.8fr]">
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold text-slate-900">Aggiornamento distribution</div>
<div class="mt-1 text-[11px] text-slate-500">Usare solo quando il manifest update sul server distribution e valido.</div>
<div class="mt-3 grid gap-2 sm:grid-cols-4">
<label class="block">
<span class="mb-1 block text-[11px] font-medium">Canale</span>
<select wire:model="updateChannel" class="w-full rounded-md border-gray-300 text-xs">
<option value="free">free</option>
<option value="licensed">licensed</option>
</select>
</label>
<label class="inline-flex items-center gap-2 rounded-md border bg-white px-2 py-1.5 text-[11px] sm:mt-6">
<input type="checkbox" wire:model="updateDryRun" class="rounded border-gray-300" />
Dry run
</label>
<label class="inline-flex items-center gap-2 rounded-md border bg-white px-2 py-1.5 text-[11px] sm:mt-6">
<input type="checkbox" wire:model="updateForce" class="rounded border-gray-300" />
Force
</label>
<label class="inline-flex items-center gap-2 rounded-md border border-amber-300 bg-amber-50 px-2 py-1.5 text-[11px] text-amber-900 sm:mt-6">
<input type="checkbox" wire:model="updateSkipBackup" class="rounded border-gray-300" />
Salta backup
</label>
</div>
<div class="mt-3 flex flex-wrap gap-2">
<x-filament::button size="sm" wire:click="runUpdate" :disabled="!$supportCanRunUpdate">
Lancia aggiornamento
</x-filament::button>
<x-filament::button size="sm" color="warning" wire:click="runUpdateFallback" :disabled="!$supportCanRunUpdate">
Lancia aggiornamento (riserva)
</x-filament::button>
<x-filament::button size="sm" color="info" wire:click="runUpdateConnectivityCheck">
Check connettivita update
</x-filament::button>
<x-filament::button size="sm" color="gray" wire:click="runMaintenanceOptimizeClear" :disabled="!$supportCanRunUpdate">
optimize:clear
</x-filament::button>
<x-filament::button size="sm" color="gray" wire:click="runMaintenanceViewRebuild" :disabled="!$supportCanRunUpdate">
Rebuild view
</x-filament::button>
</div>
@if($this->updateInProgress)
<div class="mt-3 rounded-lg border bg-slate-50 p-3" wire:poll.2s="refreshUpdateProgress">
@else
<div class="mt-3 rounded-lg border bg-slate-50 p-3">
@endif
<div class="mb-1 flex items-center justify-between text-[11px] text-gray-600">
<span class="font-semibold">Avanzamento aggiornamento</span>
<span class="font-mono">{{ (int) $this->updateProgressPercent }}%</span>
</div>
<div class="h-2 w-full overflow-hidden rounded bg-gray-200">
<div class="h-2 {{ $this->updateProgressStatus === 'failed' ? 'bg-rose-500' : 'bg-emerald-500' }}" style="width: {{ max(0, min(100, (int) $this->updateProgressPercent)) }}%"></div>
</div>
<div class="mt-1 text-[11px] text-gray-600">{{ $this->updateProgressMessage }}</div>
@if(filled($this->lastUpdateIssue))
<div class="mt-2 rounded border border-amber-300 bg-amber-50 px-2 py-2 text-[11px] text-amber-900">{{ $this->lastUpdateIssue }}</div>
@endif
</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-sm font-semibold text-slate-900">Esito e backup</div>
<div class="mt-3 space-y-1 text-[11px] text-slate-600">
<div>Exit update: <span class="font-medium">{{ $this->lastUpdateExitCode !== null ? $this->lastUpdateExitCode : '-' }}</span></div>
<div>Exit sync Git: <span class="font-medium">{{ $this->lastGitSyncExitCode !== null ? $this->lastGitSyncExitCode : '-' }}</span></div>
<div>Backup snapshot: <span class="font-medium">{{ $this->latestBackupSummary['snapshot_id'] ?? '-' }}</span></div>
<div>Backup creato il: <span class="font-medium">{{ $this->latestBackupSummary['created_at'] ?? '-' }}</span></div>
</div>
@if(filled($this->lastConnectivityCheckOutput))
<div class="mt-3 rounded-lg border bg-slate-950 p-3">
<div class="mb-1 text-[11px] font-semibold text-slate-200">Ultimo check connettivita</div>
<pre class="max-h-48 overflow-auto whitespace-pre-wrap text-[11px] leading-relaxed text-slate-100">{{ $this->lastConnectivityCheckOutput }}</pre>
</div>
@endif
</div>
</div>
</div>
</x-filament-panels::page>

View File

@ -17,6 +17,12 @@
Versione corrente: <span class="font-mono font-semibold">{{ $this->currentVersion }}</span>
<span class="ml-2 rounded bg-gray-100 px-1.5 py-0.5 text-[10px] uppercase">fonte {{ $this->versionSource }}</span>
</div>
<div class="pt-1 text-[11px] text-sky-700">
Per sync Git e update piu sicuri usa il launcher esterno:
<a href="{{ \App\Filament\Pages\Supporto\AggiornamentoLauncher::getUrl(panel: 'admin-filament') }}" class="font-semibold text-sky-900 underline underline-offset-2 hover:text-sky-700">
Apri Aggiornamento Nodo
</a>
</div>
</div>
<div class="space-y-1 text-xs text-gray-600">