Files
Virtnet.bond/extensions/Servers/ManualServers/Admin/Pages/ManualServersQueue.php

125 lines
5.7 KiB
PHP

<?php
namespace Paymenter\Extensions\Servers\ManualServers\Admin\Pages;
use App\Models\Service;
use Filament\Pages\Page;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
class ManualServersQueue extends Page implements HasTable
{
use InteractsWithTable;
protected static ?string $navigationIcon = 'ri-hard-drive-3-line';
protected static string $view = 'manual-servers::admin.pages.manual-servers-queue';
protected static ?string $navigationGroup = 'Extensions';
protected static ?string $navigationLabel = 'Manual Servers';
protected static ?int $navigationSort = 100;
public function getTitle(): string
{
return 'Manual Servers';
}
public static function canAccess(): bool
{
return auth()->check() && auth()->user()->can('viewAny', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class);
}
public function table(Table $table): Table
{
return $table
->query(
Service::query()
->whereHas('product.server', function ($query) {
$query->where('extension', 'ManualServers');
})
->with(['user', 'product', 'product.server', 'properties'])
->orderBy('created_at', 'desc')
)
->columns([
TextColumn::make('id')
->label('Service ID')
->prefix('#')
->sortable(),
TextColumn::make('user.name')
->label('Client')
->description(fn (Service $record) => $record->user->email)
->searchable(),
TextColumn::make('product.name')
->label('Product')
->sortable()
->searchable(),
TextColumn::make('deploy_status')
->label('Server Status')
->state(fn (Service $record): string => $record->properties->where('key', 'deploy_status')->first()?->value ?? 'pending')
->badge()
->formatStateUsing(fn (string $state): string => ucfirst($state))
->color(fn (string $state): string => match ($state) {
'deployed' => 'success',
'suspended' => 'danger',
'terminated' => 'gray',
default => 'warning',
}),
TextColumn::make('progress')
->label('Setup Progress')
->state(function (Service $record): string {
$processesJson = $record->properties->where('key', 'processes_data')->first()?->value ?? '[]';
$processes = json_decode($processesJson, true) ?? [];
$total = count($processes);
$completed = collect($processes)->where('completed', true)->count();
return "{$completed} / {$total} steps";
})
->description(function (Service $record): string {
$processesJson = $record->properties->where('key', 'processes_data')->first()?->value ?? '[]';
$processes = json_decode($processesJson, true) ?? [];
$lastCompleted = collect($processes)->where('completed', true)->last();
return $lastCompleted ? 'Last completed: ' . $lastCompleted['name'] : 'Setup not started';
}),
TextColumn::make('sla_elapsed')
->label('Elapsed')
->state(fn (Service $record): string => $record->created_at->diffForHumans(now(), true))
->description(function (Service $record): string {
$deadline = $record->created_at->copy()->addHours($this->getSlaHours($record));
return 'SLA deadline: ' . $deadline->format('M d, Y H:i');
}),
TextColumn::make('sla_status')
->label('SLA')
->badge()
->state(function (Service $record): string {
$status = $record->properties->where('key', 'deploy_status')->first()?->value ?? 'pending';
if ($status === 'deployed') {
return 'met';
}
$deadline = $record->created_at->copy()->addHours($this->getSlaHours($record));
return now()->gt($deadline) ? 'overdue' : 'on-time';
})
->color(fn (string $state): string => match ($state) {
'met' => 'success',
'overdue' => 'danger',
default => 'warning',
})
->formatStateUsing(fn (string $state): string => match ($state) {
'met' => 'Met',
'overdue' => 'Overdue',
default => 'On time',
}),
TextColumn::make('created_at')
->label('Order Date')
->dateTime()
->sortable(),
])
->recordUrl(fn (Service $record): string => ManualServersManage::getUrl(['service' => $record->id]))
->defaultSort('created_at', 'desc');
}
protected function getSlaHours(Service $service): int
{
$value = $service->product->settings->where('key', 'sla_hours')->first()?->value;
return max(1, (int) ($value ?: 24));
}
}