Add progress bars to client area (#1924)

This commit is contained in:
Charles 2025-11-28 18:04:40 -05:00 committed by GitHub
parent 575e5bdb0d
commit 2dd6e3d4fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 561 additions and 63 deletions

View File

@ -5,6 +5,7 @@ namespace App\Filament\App\Resources\Servers\Pages;
use App\Enums\CustomizationKey; use App\Enums\CustomizationKey;
use App\Enums\ServerResourceType; use App\Enums\ServerResourceType;
use App\Filament\App\Resources\Servers\ServerResource; use App\Filament\App\Resources\Servers\ServerResource;
use App\Filament\Components\Tables\Columns\ProgressBarColumn;
use App\Filament\Components\Tables\Columns\ServerEntryColumn; use App\Filament\Components\Tables\Columns\ServerEntryColumn;
use App\Filament\Server\Pages\Console; use App\Filament\Server\Pages\Console;
use App\Models\Permission; use App\Models\Permission;
@ -34,11 +35,11 @@ class ListServers extends ListRecords
use CanCustomizeHeaderActions; use CanCustomizeHeaderActions;
use CanCustomizeHeaderWidgets; use CanCustomizeHeaderWidgets;
protected static string $resource = ServerResource::class; public const WARNING_THRESHOLD = 0.7;
public const DANGER_THRESHOLD = 0.9; public const DANGER_THRESHOLD = 0.9;
public const WARNING_THRESHOLD = 0.7; protected static string $resource = ServerResource::class;
private DaemonServerRepository $daemonServerRepository; private DaemonServerRepository $daemonServerRepository;
@ -54,6 +55,8 @@ class ListServers extends ListRecords
return [ return [
Stack::make([ Stack::make([
ServerEntryColumn::make('server_entry') ServerEntryColumn::make('server_entry')
->warningThresholdPercent(static::WARNING_THRESHOLD)
->dangerThresholdPercent(static::DANGER_THRESHOLD)
->searchable(['name']), ->searchable(['name']),
]), ]),
]; ];
@ -70,7 +73,7 @@ class ListServers extends ListRecords
TextColumn::make('condition') TextColumn::make('condition')
->label(trans('server/dashboard.status')) ->label(trans('server/dashboard.status'))
->badge() ->badge()
->tooltip(fn (Server $server) => $server->formatResource(ServerResourceType::Uptime)) ->tooltip(fn (Server $server) => $server->formatResource(ServerResourceType::Uptime, 2))
->icon(fn (Server $server) => $server->condition->getIcon()) ->icon(fn (Server $server) => $server->condition->getIcon())
->color(fn (Server $server) => $server->condition->getColor()), ->color(fn (Server $server) => $server->condition->getColor()),
TextColumn::make('name') TextColumn::make('name')
@ -84,24 +87,27 @@ class ListServers extends ListRecords
->visibleFrom('md') ->visibleFrom('md')
->copyable() ->copyable()
->state(fn (Server $server) => $server->allocation->address ?? 'None'), ->state(fn (Server $server) => $server->allocation->address ?? 'None'),
TextColumn::make('cpuUsage') ProgressBarColumn::make('cpuUsage')
->label(trans('server/dashboard.resources'))
->icon('tabler-cpu')
->tooltip(fn (Server $server) => trans('server/dashboard.usage_limit', ['resource' => $server->formatResource(ServerResourceType::CPULimit)]))
->state(fn (Server $server) => $server->formatResource(ServerResourceType::CPU))
->color(fn (Server $server) => $this->getResourceColor($server, 'cpu')),
TextColumn::make('memoryUsage')
->label('') ->label('')
->icon('tabler-device-desktop-analytics') ->warningThresholdPercent(static::WARNING_THRESHOLD)
->tooltip(fn (Server $server) => trans('server/dashboard.usage_limit', ['resource' => $server->formatResource(ServerResourceType::MemoryLimit)])) ->dangerThresholdPercent(static::DANGER_THRESHOLD)
->state(fn (Server $server) => $server->formatResource(ServerResourceType::Memory)) ->maxValue(fn (Server $server) => ServerResourceType::CPULimit->getResourceAmount($server) === 0 ? ($server->node->systemInformation()['cpu_count'] ?? 0 * 100) : ServerResourceType::CPULimit->getResourceAmount($server))
->color(fn (Server $server) => $this->getResourceColor($server, 'memory')), ->state(fn (Server $server) => $server->retrieveResources()['cpu_absolute'] ?? 0)
TextColumn::make('diskUsage') ->helperLabel(fn (Server $server) => $server->formatResource(ServerResourceType::CPU, 0) . ' / ' . $server->formatResource(ServerResourceType::CPULimit, 0)),
ProgressBarColumn::make('memoryUsage')
->label('') ->label('')
->icon('tabler-device-sd-card') ->warningThresholdPercent(static::WARNING_THRESHOLD)
->tooltip(fn (Server $server) => trans('server/dashboard.usage_limit', ['resource' => $server->formatResource(ServerResourceType::DiskLimit)])) ->dangerThresholdPercent(static::DANGER_THRESHOLD)
->state(fn (Server $server) => $server->formatResource(ServerResourceType::Disk)) ->maxValue(fn (Server $server) => ServerResourceType::MemoryLimit->getResourceAmount($server) === 0 ? $server->node->statistics()['memory_total'] : ServerResourceType::MemoryLimit->getResourceAmount($server))
->color(fn (Server $server) => $this->getResourceColor($server, 'disk')), ->state(fn (Server $server) => $server->retrieveResources()['memory_bytes'] ?? 0)
->helperLabel(fn (Server $server) => $server->formatResource(ServerResourceType::Memory) . ' / ' . $server->formatResource(ServerResourceType::MemoryLimit)),
ProgressBarColumn::make('diskUsage')
->label('')
->warningThresholdPercent(static::WARNING_THRESHOLD)
->dangerThresholdPercent(static::DANGER_THRESHOLD)
->maxValue(fn (Server $server) => ServerResourceType::DiskLimit->getResourceAmount($server) === 0 ? $server->node->statistics()['disk_total'] : ServerResourceType::DiskLimit->getResourceAmount($server))
->state(fn (Server $server) => $server->retrieveResources()['disk_bytes'] ?? 0)
->helperLabel(fn (Server $server) => $server->formatResource(ServerResourceType::Disk) . ' / ' . $server->formatResource(ServerResourceType::DiskLimit)),
]; ];
} }

View File

@ -0,0 +1,136 @@
<?php
namespace App\Filament\Components\Tables\Columns\Concerns;
use Closure;
use Filament\Support\Colors\Color;
/**
* Trait extracted for progress-related shared functionality between columns.
*
* @method mixed evaluate(mixed $value, array<string,mixed> $context = [])
*/
trait HasProgress
{
protected float|Closure|null $warningThresholdPercent = null;
protected float|Closure|null $dangerThresholdPercent = null;
/**
* @var string|array<int|string,string>|Closure|Color|null
*/
protected string|array|Closure|Color|null $dangerColor = null;
/**
* @var string|array<int|string,string>|Closure|Color|null
*/
protected string|array|Closure|Color|null $warningColor = null;
/**
* @var string|array<int|string,string>|Closure|Color|null
*/
protected string|array|Closure|Color|null $color = null;
public function warningThresholdPercent(float|Closure $value): static
{
$this->warningThresholdPercent = $value;
return $this;
}
public function getWarningThresholdPercent(): ?float
{
return $this->evaluate($this->warningThresholdPercent);
}
public function dangerThresholdPercent(float|Closure $value): static
{
$this->dangerThresholdPercent = $value;
return $this;
}
public function getDangerThresholdPercent(): ?float
{
return $this->evaluate($this->dangerThresholdPercent);
}
/**
* @param string|array<int|string,string>|Closure|Color $color
*/
public function dangerColor(string|array|Closure|Color $color): static
{
$this->dangerColor = $color;
return $this;
}
/**
* @return string|array<int|string,string>|Color|null
*/
public function getDangerColor(): string|array|Color|null
{
return $this->evaluate($this->dangerColor);
}
/**
* @param string|array<int|string,string>|Closure|Color $color
*/
public function warningColor(string|array|Closure|Color $color): static
{
$this->warningColor = $color;
return $this;
}
/**
* @return string|array<int|string,string>|Color|null
*/
public function getWarningColor(): string|array|Color|null
{
return $this->evaluate($this->warningColor);
}
/**
* @param string|array<int|string,string>|Closure|Color $color
*/
public function color(string|array|Closure|Color $color): static
{
$this->color = $color;
return $this;
}
/**
* @return string|array<int|string,string>|Color|null
*/
public function getColor(): string|array|Color|null
{
return $this->evaluate($this->color);
}
/**
* Resolve a progress color for a given status string ('danger','warning','success').
*
* @return string|array<int|string,string>|Color
*/
public function getProgressColorForStatus(string $status): string|array|Color
{
$color = match ($status) {
'danger' => $this->getDangerColor(),
'warning' => $this->getWarningColor(),
'success' => $this->getColor(),
default => $this->getColor(),
};
if ($color === null) {
$color = $this->getColor();
}
if ($color === null) {
return 'gray';
}
return $color;
}
}

View File

@ -0,0 +1,162 @@
<?php
namespace App\Filament\Components\Tables\Columns;
use App\Filament\Components\Tables\Columns\Concerns\HasProgress;
use Closure;
use Filament\Support\Facades\FilamentColor;
use Filament\Tables\Columns\Column;
class ProgressBarColumn extends Column
{
use HasProgress;
protected string $view = 'livewire.columns.progress-bar-column';
protected int|float|Closure|null $maxValue = null;
protected string|Closure|null $helperLabel = null;
protected function setUp(): void
{
parent::setUp();
$this->dangerColor = FilamentColor::getColor('danger');
$this->warningColor = FilamentColor::getColor('warning');
$this->color = FilamentColor::getColor('primary');
$this->helperLabel = fn ($state) => $state !== null ? (string) $state : '0';
}
public function maxValue(int|float|Closure $value): static
{
$this->maxValue = $value;
return $this;
}
public function getMaxValue(): ?float
{
return $this->evaluate($this->maxValue);
}
public function helperLabel(string|Closure $label): static
{
$this->helperLabel = $label;
return $this;
}
public function getHelperLabel(mixed $currentValue = null): string
{
$result = $this->evaluate($this->helperLabel, [
'state' => $currentValue,
'percentage' => $this->getProgressPercentage(),
]);
return $result !== null ? (string) $result : '';
}
public function getProgressPercentage(): float
{
$currentValue = $this->getState();
$maxValue = $this->getMaxValue();
if ($currentValue === null || $maxValue === null || $maxValue <= 0) {
return 0;
}
return min(100, max(0, ($currentValue / $maxValue) * 100));
}
public function getProgressStatus(): string
{
$percentage = $this->getProgressPercentage();
$dangerPercent = $this->getDangerThresholdPercent();
$warningPercent = $this->getWarningThresholdPercent();
$dangerThreshold = ($dangerPercent !== null ? $dangerPercent : 0.9) * 100;
$warningThreshold = ($warningPercent !== null ? $warningPercent : 0.7) * 100;
if ($percentage >= $dangerThreshold) {
return 'danger';
}
if ($percentage >= $warningThreshold) {
return 'warning';
}
return 'success';
}
public function getProgressLabel(): string
{
$currentValue = $this->getState();
$label = $this->getHelperLabel($currentValue);
if ($label !== '') {
return $label;
}
return sprintf('%d%%', (int) round($this->getProgressPercentage()));
}
/**
* @return string|array<int|string,string>
*/
public function getProgressColor(): string|array
{
$status = $this->getProgressStatus();
$color = match ($status) {
'danger' => $this->getDangerColor(),
'warning' => $this->getWarningColor(),
'success' => $this->getColor(),
default => $this->getColor(),
};
if ($color === null) {
$color = $this->getColor();
}
if ($color === null) {
return 'gray';
}
return $color;
}
public static function resolveColor(mixed $color): ?string
{
$resolvedColor = null;
if (is_object($color)) {
if (method_exists($color, 'toCss')) {
$resolvedColor = $color->toCss();
} elseif (method_exists($color, 'toRgb')) {
$resolvedColor = $color->toRgb();
} elseif (method_exists($color, 'toHex')) {
$resolvedColor = $color->toHex();
} else {
$resolvedColor = $color;
}
} elseif (is_array($color)) {
$resolvedColor = $color[500] ?? reset($color) ?? null;
} else {
$resolvedColor = (string) $color;
}
if (is_string($resolvedColor)) {
return $resolvedColor;
}
return null;
}
public function getResolvedProgressColor(): ?string
{
return self::resolveColor($this->getProgressColor());
}
}

View File

@ -2,9 +2,22 @@
namespace App\Filament\Components\Tables\Columns; namespace App\Filament\Components\Tables\Columns;
use App\Filament\Components\Tables\Columns\Concerns\HasProgress;
use Filament\Support\Facades\FilamentColor;
use Filament\Tables\Columns\Column; use Filament\Tables\Columns\Column;
class ServerEntryColumn extends Column class ServerEntryColumn extends Column
{ {
use HasProgress;
protected string $view = 'livewire.columns.server-entry-column'; protected string $view = 'livewire.columns.server-entry-column';
protected function setUp(): void
{
parent::setUp();
$this->dangerColor = FilamentColor::getColor('danger');
$this->warningColor = FilamentColor::getColor('warning');
$this->color = FilamentColor::getColor('primary');
}
} }

View File

@ -314,7 +314,7 @@ class Node extends Model implements Validatable
/** @return array<mixed> */ /** @return array<mixed> */
public function systemInformation(): array public function systemInformation(): array
{ {
return once(function () { return cache()->remember("nodes.$this->id.system_information", now()->addSeconds(360), function () {
try { try {
return (new DaemonSystemRepository()) return (new DaemonSystemRepository())
->setNode($this) ->setNode($this)
@ -358,21 +358,23 @@ class Node extends Model implements Validatable
'disk_used' => 0, 'disk_used' => 0,
]; ];
try { return cache()->remember("nodes.$this->id.statistics", now()->addSeconds(360), function () use ($default) {
try {
$data = Http::daemon($this) $data = Http::daemon($this)
->connectTimeout(1) ->connectTimeout(1)
->timeout(1) ->timeout(1)
->get('/api/system/utilization') ->get('/api/system/utilization')
->json(); ->json();
if ($data['memory_total']) { if (!empty($data['memory_total'])) {
return $data; return $data;
}
} catch (Exception) {
} }
} catch (Exception) {
}
return $default; return $default;
});
} }
/** @return string[] */ /** @return string[] */

View File

@ -482,7 +482,7 @@ class Server extends Model implements HasAvatar, Validatable
}); });
} }
public function formatResource(ServerResourceType $resourceType): string public function formatResource(ServerResourceType $resourceType, int $precision = 2): string
{ {
$resourceAmount = $resourceType->getResourceAmount($this); $resourceAmount = $resourceType->getResourceAmount($this);
@ -504,10 +504,10 @@ class Server extends Model implements HasAvatar, Validatable
} }
if ($resourceType->isPercentage()) { if ($resourceType->isPercentage()) {
return format_number($resourceAmount, precision: 2) . '%'; return format_number($resourceAmount, precision: $precision) . '%';
} }
return convert_bytes_to_readable($resourceAmount, base: 3); return convert_bytes_to_readable($resourceAmount, decimals: $precision, base: 3);
} }
public function condition(): Attribute public function condition(): Attribute

View File

@ -0,0 +1,86 @@
@php
$currentValue = $getState();
$maxValue = $getMaxValue();
$status = $getProgressStatus();
$percentage = $getProgressPercentage();
$label = $getProgressLabel();
$color = $getProgressColor();
$resolved = \App\Filament\Components\Tables\Columns\ProgressBarColumn::resolveColor($color);
$color = $resolved ?? (is_string($color) ? $color : 'gray');
$colorStr = is_string($color) ? $color : 'gray';
$isRgb = str_starts_with($colorStr, 'rgb(');
if ($isRgb) {
$lightBackgroundColor = str_replace('rgb(', 'rgba(', rtrim($colorStr, ')') . ', 0.15)');
} else {
$lightBackgroundColor = "color-mix(in srgb, {$colorStr} 15%, transparent)";
}
$isDanger = $status === 'danger';
$lighterColor = $colorStr;
$animClass = null;
if ($isDanger) {
$lighterColor = "color-mix(in srgb, {$colorStr} 50%, #ffffff)";
$animClass = 'danger-pulse-' . substr(md5($colorStr), 0, 8);
}
@endphp
<div
@class(['fi-ta-text block w-full px-3'])
>
@if($isDanger && $animClass)
<style>
@keyframes {{ $animClass }} {
0% {
color: {{ $colorStr }};
}
50% {
color: {{ $lighterColor }};
}
100% {
color: {{ $colorStr }};
}
}
.{{ $animClass }} {
animation: {{ $animClass }} 1s ease-in-out infinite;
}
</style>
@endif
<div @class(['flex flex-col gap-2'])>
<div
@class(['relative rounded-full overflow-hidden w-full'])
style="height: 0.725rem; background-color: {{ $lightBackgroundColor }};"
role="progressbar"
aria-valuenow="{{ $currentValue }}"
aria-valuemin="0"
aria-valuemax="{{ $maxValue ?? 100 }}"
aria-label="{{ $label }}"
>
<div
@class(['h-full rounded-full transition-all duration-300 ease-in-out'])
style="width: {{ $percentage }}%; background-color: {{ $colorStr }};"
></div>
</div>
<span
@class([
'text-sm text-center',
'text-gray-500 dark:text-gray-400' => ! $isDanger,
'font-bold' => $isDanger,
$animClass => $isDanger && $animClass,
])
@if($isDanger)
role="status"
aria-live="assertive"
style="color: {{ $colorStr }};"
@else
style="color: unset;"
@endif
>
{{ $label }}
</span>
</div>
</div>

View File

@ -1,5 +1,6 @@
@php @php
$backgroundImage = $server->icon ?? $server->egg->image; $backgroundImage = $server->icon ?? $server->egg->image;
$serverEntryColumn = $column ?? \App\Filament\Components\Tables\Columns\ServerEntryColumn::make('server_entry');
@endphp @endphp
<div class="relative cursor-pointer" <div class="relative cursor-pointer"
@ -41,26 +42,64 @@
<div class="flex justify-between text-center items-center gap-4"> <div class="flex justify-between text-center items-center gap-4">
<div> <div>
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.cpu') }}</p> @php
<p class="text-md font-semibold">{{ format_number(0, precision: 2) . '%' }}</p> $cpuCurrent = 0;
<hr class="p-0.5"> $cpuMax = \App\Enums\ServerResourceType::CPULimit->getResourceAmount($server) ?: 100;
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::CPULimit) }}</p> $getState = fn() => $cpuCurrent;
$getMaxValue = fn() => $cpuMax;
$getProgressLabel = fn () => $server->formatResource(App\Enums\ServerResourceType::CPU, 0) . ' / ' . $server->formatResource(App\Enums\ServerResourceType::CPULimit, 0);
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => fn() => 'success',
'getProgressPercentage' => fn () => 0,
'getProgressColor' => fn () => $serverEntryColumn->getProgressColorForStatus('success'),
])
</div> </div>
<div> <div>
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.memory') }}</p> @php
<p class="text-md font-semibold">{{ convert_bytes_to_readable(0, decimals: 2) }}</p> $memCurrent = 0;
<hr class="p-0.5"> $memMax = \App\Enums\ServerResourceType::MemoryLimit->getResourceAmount($server);
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::MemoryLimit) }}</p> $getState = fn() => $memCurrent;
$getMaxValue = fn() => $memMax > 0 ? $memMax : null;
$getProgressLabel = fn() => convert_bytes_to_readable($memCurrent) . ' / ' . ($memMax > 0 ? convert_bytes_to_readable($memMax) : "\u{221E}");
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => fn() => 'success',
'getProgressPercentage' => fn () => 0,
'getProgressColor' => fn () => $serverEntryColumn->getProgressColorForStatus('success'),
])
</div> </div>
<div> <div>
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.disk') }}</p> @php
<p class="text-md font-semibold">{{ convert_bytes_to_readable(0, decimals: 2) }}</p> $diskCurrent = 0;
<hr class="p-0.5"> $diskMax = \App\Enums\ServerResourceType::DiskLimit->getResourceAmount($server);
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::DiskLimit) }}</p> $getState = fn() => $diskCurrent;
$getMaxValue = fn() => $diskMax > 0 ? $diskMax : null;
$getProgressLabel = fn() => convert_bytes_to_readable($diskCurrent) . ' / ' . ($diskMax > 0 ? convert_bytes_to_readable($diskMax) : "\u{221E}");
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => fn() => 'success',
'getProgressPercentage' => fn () => 0,
'getProgressColor' => fn () => $serverEntryColumn->getProgressColorForStatus('success'),
])
</div> </div>
<div class="hidden sm:block"> <div class="hidden sm:block">
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.network') }}</p> <p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.network') }}</p>
<hr class="p-0.5">
<p class="text-md font-semibold">{{ $server->allocation?->address ?? trans('server/dashboard.none') }}</p> <p class="text-md font-semibold">{{ $server->allocation?->address ?? trans('server/dashboard.none') }}</p>
</div> </div>
</div> </div>

View File

@ -1,6 +1,13 @@
@php @php
$actiongroup = \App\Filament\App\Resources\Servers\Pages\ListServers::getPowerActionGroup()->record($server); $actiongroup = \App\Filament\App\Resources\Servers\Pages\ListServers::getPowerActionGroup()->record($server);
$backgroundImage = $server->icon ?? $server->egg->image; $backgroundImage = $server->icon ?? $server->egg->image;
$serverEntryColumn = $column ?? \App\Filament\Components\Tables\Columns\ServerEntryColumn::make('server_entry');
$serverNodeStatistics = $server->node->statistics();
$serverNodeSystemInfo = $server->node->systemInformation();
$warningPercent = $serverEntryColumn->getWarningThresholdPercent() ?? 0.7;
$dangerPercent = $serverEntryColumn->getDangerThresholdPercent() ?? 0.9;
@endphp @endphp
<div wire:poll.15s <div wire:poll.15s
class="relative cursor-pointer" class="relative cursor-pointer"
@ -57,27 +64,74 @@
@endif @endif
<div class="flex justify-between text-center items-center gap-4"> <div class="flex justify-between text-center items-center gap-4">
<div> <div class="w-full max-w-xs">
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.cpu') }}</p> @php
<p class="text-md font-semibold">{{ $server->formatResource(\App\Enums\ServerResourceType::CPU) }}</p> $cpuCurrent = \App\Enums\ServerResourceType::CPU->getResourceAmount($server);
<hr class="p-0.5"> $cpuMax = \App\Enums\ServerResourceType::CPULimit->getResourceAmount($server) === 0 ? (($serverNodeSystemInfo['cpu_count'] ?? 0) * 100) : \App\Enums\ServerResourceType::CPULimit->getResourceAmount($server);
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::CPULimit) }}</p> $getState = fn() => $cpuCurrent;
$getMaxValue = fn() => $cpuMax;
$getProgressPercentage = fn() => $cpuMax > 0 ? ($cpuCurrent / $cpuMax) * 100 : 0;
$getProgressLabel = fn () => $server->formatResource(\App\Enums\ServerResourceType::CPU, 0) . ' / ' . $server->formatResource(\App\Enums\ServerResourceType::CPULimit, 0);
$getProgressStatus = fn() => ($cpuMax > 0 && ($cpuCurrent / $cpuMax) * 100 >= ($dangerPercent * 100)) ? 'danger' : (( $cpuMax > 0 && ($cpuCurrent / $cpuMax) * 100 >= ($warningPercent * 100)) ? 'warning' : 'success');
$getProgressColor = fn() => $serverEntryColumn->getProgressColorForStatus($getProgressStatus());
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressPercentage' => $getProgressPercentage,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => $getProgressStatus,
'getProgressColor' => $getProgressColor,
])
</div> </div>
<div>
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.memory') }}</p> <div class="w-full max-w-xs">
<p class="text-md font-semibold">{{ $server->formatResource(\App\Enums\ServerResourceType::Memory) }}</p> @php
<hr class="p-0.5"> $memCurrent = \App\Enums\ServerResourceType::Memory->getResourceAmount($server);
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::MemoryLimit) }}</p> $memMax = \App\Enums\ServerResourceType::MemoryLimit->getResourceAmount($server) === 0 ? $serverNodeStatistics['memory_total'] : \App\Enums\ServerResourceType::MemoryLimit->getResourceAmount($server);
$getState = fn() => $memCurrent;
$getMaxValue = fn() => $memMax > 0 ? $memMax : null;
$getProgressPercentage = fn() => ($memMax > 0) ? ($memCurrent / $memMax) * 100 : 0;
$getProgressLabel = fn() => $server->formatResource(\App\Enums\ServerResourceType::Memory) . ' / ' . $server->formatResource(\App\Enums\ServerResourceType::MemoryLimit);
$getProgressStatus = fn() => ($memMax > 0 && ($memCurrent / $memMax) * 100 >= ($dangerPercent * 100)) ? 'danger' : (( $memMax > 0 && ($memCurrent / $memMax) * 100 >= ($warningPercent * 100)) ? 'warning' : 'success');
$getProgressColor = fn() => $serverEntryColumn->getProgressColorForStatus($getProgressStatus());
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressPercentage' => $getProgressPercentage,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => $getProgressStatus,
'getProgressColor' => $getProgressColor,
])
</div> </div>
<div>
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.disk') }}</p> <div class="w-full max-w-xs">
<p class="text-md font-semibold">{{ $server->formatResource(\App\Enums\ServerResourceType::Disk) }}</p> @php
<hr class="p-0.5"> $diskCurrent = \App\Enums\ServerResourceType::Disk->getResourceAmount($server);
<p class="text-xs dark:text-gray-400">{{ $server->formatResource(\App\Enums\ServerResourceType::DiskLimit) }}</p> $diskMax = \App\Enums\ServerResourceType::DiskLimit->getResourceAmount($server) === 0 ? $serverNodeStatistics['disk_total'] : \App\Enums\ServerResourceType::DiskLimit->getResourceAmount($server);
$getState = fn() => $diskCurrent;
$getMaxValue = fn() => $diskMax > 0 ? $diskMax : null;
$getProgressPercentage = fn() => ($diskMax > 0) ? ($diskCurrent / $diskMax) * 100 : 0;
$getProgressLabel = fn() => $server->formatResource(\App\Enums\ServerResourceType::Disk) . ' / ' . $server->formatResource(\App\Enums\ServerResourceType::DiskLimit);
$getProgressStatus = fn() => ($diskMax > 0 && ($diskCurrent / $diskMax) * 100 >= ($dangerPercent * 100)) ? 'danger' : (( $diskMax > 0 && ($diskCurrent / $diskMax) * 100 >= ($warningPercent * 100)) ? 'warning' : 'success');
$getProgressColor = fn() => $serverEntryColumn->getProgressColorForStatus($getProgressStatus());
@endphp
@include('livewire.columns.progress-bar-column', [
'getState' => $getState,
'getMaxValue' => $getMaxValue,
'getProgressPercentage' => $getProgressPercentage,
'getProgressLabel' => $getProgressLabel,
'getProgressStatus' => $getProgressStatus,
'getProgressColor' => $getProgressColor,
])
</div> </div>
<div class="hidden sm:block"> <div class="hidden sm:block">
<p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.network') }}</p> <p class="text-sm dark:text-gray-400">{{ trans('server/dashboard.network') }}</p>
<hr class="p-0.5">
<p class="text-md font-semibold">{{ $server->allocation?->address ?? trans('server/dashboard.none') }}</p> <p class="text-md font-semibold">{{ $server->allocation?->address ?? trans('server/dashboard.none') }}</p>
</div> </div>
</div> </div>