Mobile + Layout Changes (#836)

* Update Server Listing

* Update Edit/Create Server Pages

Re-arrange limits, CPU->Memory->Disk

* Remove auto focus

its cancer on mobile...

* Hide Title, Quick yaml fix

* Hide columns on mobile

* Hide backup locked on mobile

* Fix schedules for mobile

* Hide Notes on mobile

* Consolidate and clean these up

* Simplify

* Remove unused imports

* Replace tabler icon package

* Update app/Filament/Server/Resources/FileResource/Pages/EditFiles.php

Co-authored-by: Lance Pioch <git@lance.sh>

* Allow the unit to be changed

* Use existing method

* Update composer and pint

* Update resources/views/tables/columns/server-entry-column.blade.php

Co-authored-by: Boy132 <Boy132@users.noreply.github.com>

* Simplify html and add small margin

* Unused

* Add enum

---------

Co-authored-by: Lance Pioch <git@lance.sh>
Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
This commit is contained in:
Charles 2024-12-28 16:02:24 -05:00 committed by GitHub
parent 66a17879a0
commit a8680c7aed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 373 additions and 333 deletions

View File

@ -53,6 +53,16 @@ enum ContainerStatus: string
};
}
public function colorHex(): string
{
return match ($this) {
self::Created, self::Restarting => '#2563EB',
self::Starting, self::Paused, self::Removing, self::Stopping => '#D97706',
self::Running => '#22C55E',
self::Exited, self::Missing, self::Dead, self::Offline => '#EF4444',
};
}
public function isStartingOrStopping(): bool
{
return in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting]);

View File

@ -0,0 +1,10 @@
<?php
namespace App\Enums;
enum ServerResourceType
{
case Unit;
case Percentage;
case Time;
}

View File

@ -534,6 +534,37 @@ class CreateServer extends CreateRecord
'lg' => 3,
])
->schema([
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->default(true)
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->live()
->options([
true => 'Unlimited',
false => 'Limited',
])
->colors([
true => 'primary',
false => 'warning',
])
->columnSpan(2),
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->default(0)
->required()
->columnSpan(2)
->numeric()
->minValue(0)
->helperText('100% equals one CPU core.'),
]),
Grid::make()
->columns(4)
->columnSpanFull()
@ -564,7 +595,6 @@ class CreateServer extends CreateRecord
->numeric()
->minValue(0),
]),
Grid::make()
->columns(4)
->columnSpanFull()
@ -596,37 +626,6 @@ class CreateServer extends CreateRecord
->minValue(0),
]),
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->default(true)
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->live()
->options([
true => 'Unlimited',
false => 'Limited',
])
->colors([
true => 'primary',
false => 'warning',
])
->columnSpan(2),
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->default(0)
->required()
->columnSpan(2)
->numeric()
->minValue(0)
->helperText('100% equals one CPU core.'),
]),
]),
Fieldset::make('Advanced Limits')
@ -638,6 +637,40 @@ class CreateServer extends CreateRecord
'lg' => 3,
])
->schema([
Hidden::make('io')
->helperText('The IO performance relative to other running containers')
->label('Block IO Proportion')
->default(500),
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('cpu_pinning')
->label('CPU Pinning')->inlineLabel()->inline()
->default(false)
->afterStateUpdated(fn (Set $set) => $set('threads', []))
->live()
->options([
false => 'Disabled',
true => 'Enabled',
])
->colors([
false => 'success',
true => 'warning',
])
->columnSpan(2),
TagsInput::make('threads')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => !$get('cpu_pinning'))
->label('Pinned Threads')->inlineLabel()
->required(fn (Get $get) => $get('cpu_pinning'))
->columnSpan(2)
->separator()
->splitKeys([','])
->placeholder('Add pinned thread, e.g. 0 or 2-4'),
]),
Grid::make()
->columns(4)
->columnSpanFull()
@ -686,41 +719,6 @@ class CreateServer extends CreateRecord
->integer(),
]),
Hidden::make('io')
->helperText('The IO performance relative to other running containers')
->label('Block IO Proportion')
->default(500),
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('cpu_pinning')
->label('CPU Pinning')->inlineLabel()->inline()
->default(false)
->afterStateUpdated(fn (Set $set) => $set('threads', []))
->live()
->options([
false => 'Disabled',
true => 'Enabled',
])
->colors([
false => 'success',
true => 'warning',
])
->columnSpan(2),
TagsInput::make('threads')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => !$get('cpu_pinning'))
->label('Pinned Threads')->inlineLabel()
->required(fn (Get $get) => $get('cpu_pinning'))
->columnSpan(2)
->separator()
->splitKeys([','])
->placeholder('Add pinned thread, e.g. 0 or 2-4'),
]),
Grid::make()
->columns(4)
->columnSpanFull()

View File

@ -184,6 +184,35 @@ class EditServer extends EditRecord
'lg' => 3,
])
->schema([
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->formatStateUsing(fn (Get $get) => $get('cpu') == 0)
->live()
->options([
true => 'Unlimited',
false => 'Limited',
])
->colors([
true => 'primary',
false => 'warning',
])
->columnSpan(2),
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->required()
->columnSpan(2)
->numeric()
->minValue(0),
]),
Grid::make()
->columns(4)
->columnSpanFull()
@ -243,36 +272,6 @@ class EditServer extends EditRecord
->numeric()
->minValue(0),
]),
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->formatStateUsing(fn (Get $get) => $get('cpu') == 0)
->live()
->options([
true => 'Unlimited',
false => 'Limited',
])
->colors([
true => 'primary',
false => 'warning',
])
->columnSpan(2),
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->required()
->columnSpan(2)
->numeric()
->minValue(0),
]),
]),
Fieldset::make('Advanced Limits')
@ -287,6 +286,36 @@ class EditServer extends EditRecord
->columns(4)
->columnSpanFull()
->schema([
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('cpu_pinning')
->label('CPU Pinning')->inlineLabel()->inline()
->default(false)
->afterStateUpdated(fn (Set $set) => $set('threads', []))
->formatStateUsing(fn (Get $get) => !empty($get('threads')))
->live()
->options([
false => 'Disabled',
true => 'Enabled',
])
->colors([
false => 'success',
true => 'warning',
])
->columnSpan(2),
TagsInput::make('threads')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => !$get('cpu_pinning'))
->label('Pinned Threads')->inlineLabel()
->required(fn (Get $get) => $get('cpu_pinning'))
->columnSpan(2)
->separator()
->splitKeys([','])
->placeholder('Add pinned thread, e.g. 0 or 2-4'),
]),
ToggleButtons::make('swap_support')
->live()
->label('Swap Memory')->inlineLabel()->inline()
@ -338,37 +367,6 @@ class EditServer extends EditRecord
->helperText('The IO performance relative to other running containers')
->label('Block IO Proportion'),
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
ToggleButtons::make('cpu_pinning')
->label('CPU Pinning')->inlineLabel()->inline()
->default(false)
->afterStateUpdated(fn (Set $set) => $set('threads', []))
->formatStateUsing(fn (Get $get) => !empty($get('threads')))
->live()
->options([
false => 'Disabled',
true => 'Enabled',
])
->colors([
false => 'success',
true => 'warning',
])
->columnSpan(2),
TagsInput::make('threads')
->dehydratedWhenHidden()
->hidden(fn (Get $get) => !$get('cpu_pinning'))
->label('Pinned Threads')->inlineLabel()
->required(fn (Get $get) => $get('cpu_pinning'))
->columnSpan(2)
->separator()
->splitKeys([','])
->placeholder('Add pinned thread, e.g. 0 or 2-4'),
]),
Grid::make()
->columns(4)
->columnSpanFull()
@ -400,16 +398,19 @@ class EditServer extends EditRecord
])
->schema([
TextInput::make('allocation_limit')
->label('Allocations')
->suffixIcon('tabler-network')
->required()
->minValue(0)
->numeric(),
TextInput::make('database_limit')
->label('Databases')
->suffixIcon('tabler-database')
->required()
->minValue(0)
->numeric(),
TextInput::make('backup_limit')
->label('Backups')
->suffixIcon('tabler-copy-check')
->required()
->minValue(0)
@ -420,7 +421,7 @@ class EditServer extends EditRecord
'default' => 1,
'sm' => 2,
'md' => 3,
'lg' => 3,
'lg' => 4,
])
->schema([
Select::make('select_image')
@ -441,7 +442,12 @@ class EditServer extends EditRecord
return array_flip($images) + ['ghcr.io/custom-image' => 'Custom Image'];
})
->selectablePlaceholder(false)
->columnSpan(1),
->columnSpan([
'default' => 1,
'sm' => 2,
'md' => 3,
'lg' => 2,
]),
TextInput::make('image')
->label('Image')
@ -457,7 +463,12 @@ class EditServer extends EditRecord
}
})
->placeholder('Enter a custom Image')
->columnSpan(2),
->columnSpan([
'default' => 1,
'sm' => 2,
'md' => 3,
'lg' => 2,
]),
KeyValue::make('docker_labels')
->label('Container Labels')

View File

@ -6,15 +6,12 @@ use App\Filament\App\Resources\ServerResource;
use App\Filament\Components\Tables\Columns\ServerEntryColumn;
use App\Filament\Server\Pages\Console;
use App\Models\Server;
use Carbon\CarbonInterface;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Columns\Layout\Stack;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Number;
class ListServers extends ListRecords
{
@ -36,7 +33,7 @@ class ListServers extends ListRecords
])
->contentGrid([
'default' => 1,
'xl' => 2,
'md' => 2,
])
->recordUrl(fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server))
->emptyStateIcon('tabler-brand-docker')
@ -61,64 +58,4 @@ class ListServers extends ListRecords
->preload(),
]);
}
// @phpstan-ignore-next-line
private function uptime(Server $server): string
{
$uptime = Arr::get($server->resources(), 'uptime', 0);
if ($uptime === 0) {
return 'Offline';
}
return now()->subMillis($uptime)->diffForHumans(syntax: CarbonInterface::DIFF_ABSOLUTE, short: true, parts: 2);
}
// @phpstan-ignore-next-line
private function cpu(Server $server): string
{
$cpu = Number::format(Arr::get($server->resources(), 'cpu_absolute', 0), maxPrecision: 2, locale: auth()->user()->language) . '%';
$max = Number::format($server->cpu, locale: auth()->user()->language) . '%';
return $cpu . ($server->cpu > 0 ? ' Of ' . $max : '');
}
// @phpstan-ignore-next-line
private function memory(Server $server): string
{
$latestMemoryUsed = Arr::get($server->resources(), 'memory_bytes', 0);
$totalMemory = Arr::get($server->resources(), 'memory_limit_bytes', 0);
$used = config('panel.use_binary_prefix')
? Number::format($latestMemoryUsed / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB'
: Number::format($latestMemoryUsed / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB';
if ($totalMemory === 0) {
$total = config('panel.use_binary_prefix')
? Number::format($server->memory / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB'
: Number::format($server->memory / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB';
} else {
$total = config('panel.use_binary_prefix')
? Number::format($totalMemory / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB'
: Number::format($totalMemory / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB';
}
return $used . ($server->memory > 0 ? ' Of ' . $total : '');
}
// @phpstan-ignore-next-line
private function disk(Server $server): string
{
$usedDisk = Arr::get($server->resources(), 'disk_bytes', 0);
$used = config('panel.use_binary_prefix')
? Number::format($usedDisk / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB'
: Number::format($usedDisk / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB';
$total = config('panel.use_binary_prefix')
? Number::format($server->disk / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB'
: Number::format($server->disk / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB';
return $used . ($server->disk > 0 ? ' Of ' . $total : '');
}
}

View File

@ -35,6 +35,7 @@ class ListAllocations extends ListRecords
->hidden(),
TextColumn::make('port'),
TextInputColumn::make('notes')
->visibleFrom('sm')
->disabled(fn () => !auth()->user()->can(Permission::ACTION_ALLOCATION_UPDATE, $server))
->label('Notes')
->placeholder('No Notes'),

View File

@ -74,6 +74,7 @@ class ListBackups extends ListRecords
->label('Successful')
->boolean(),
IconColumn::make('is_locked')
->visibleFrom('md')
->label('Lock Status')
->icon(fn (Backup $backup) => !$backup->is_locked ? 'tabler-lock-open' : 'tabler-lock'),
])

View File

@ -42,6 +42,8 @@ class EditFiles extends Page
protected static string $view = 'filament.server.pages.edit-file';
protected static ?string $title = '';
#[Locked]
public string $path;
@ -63,9 +65,13 @@ class EditFiles extends Page
->options(EditorLanguages::class)
->hidden() //TODO Fix Dis
->default(function () {
$split = explode('.', $this->path);
$ext = pathinfo($this->path, PATHINFO_EXTENSION);
return end($split);
if ($ext === 'yml') {
return 'yaml';
}
return $ext;
}),
Section::make('Editing: ' . $this->path)
->footerActions([

View File

@ -88,8 +88,10 @@ class ListFiles extends ListRecords
->sortable()
->icon(fn (File $file) => $file->getIcon()),
BytesColumn::make('size')
->visibleFrom('md')
->sortable(),
DateTimeColumn::make('modified_at')
->visibleFrom('md')
->since()
->sortable(),
])

View File

@ -64,10 +64,17 @@ class ScheduleResource extends Resource
public static function form(Form $form): Form
{
return $form
->columns(10)
->columns([
'default' => 4,
'lg' => 5,
])
->schema([
TextInput::make('name')
->columnSpan(fn ($operation) => $operation !== 'view' ? 10 : 5)
->columnSpan([
'default' => 4,
'md' => 3,
'lg' => 4,
])
->label('Schedule Name')
->placeholder('A human readable identifier for this schedule.')
->autocomplete(false)
@ -81,13 +88,20 @@ class ScheduleResource extends Resource
'active' => 'success',
])
->visibleOn('view')
->columnSpan(5),
->columnSpan([
'default' => 4,
'md' => 1,
'lg' => 1,
]),
Toggle::make('only_when_online')
->label('Only when Server is Online?')
->hintIconTooltip('Only execute this schedule when the server is in a running state.')
->hintIcon('tabler-question-mark')
->inline(false)
->columnSpan(5)
->columnSpan([
'default' => 2,
'lg' => 3,
])
->required()
->default(1),
Toggle::make('is_active')
@ -95,36 +109,55 @@ class ScheduleResource extends Resource
->hintIconTooltip('This schedule will be executed automatically if enabled.')
->hintIcon('tabler-question-mark')
->inline(false)
->columnSpan(5)
->columnSpan([
'default' => 2,
'lg' => 2,
])
->required()
->default(1),
TextInput::make('cron_minute')
->columnSpan(2)
->columnSpan([
'default' => 2,
'lg' => 1,
])
->label('Minute')
->default('*/5')
->required(),
TextInput::make('cron_hour')
->columnSpan(2)
->columnSpan([
'default' => 2,
'lg' => 1,
])
->label('Hour')
->default('*')
->required(),
TextInput::make('cron_day_of_month')
->columnSpan(2)
->columnSpan([
'default' => 2,
'lg' => 1,
])
->label('Day of Month')
->default('*')
->required(),
TextInput::make('cron_month')
->columnSpan(2)
->columnSpan([
'default' => 2,
'lg' => 1,
])
->label('Month')
->default('*')
->required(),
TextInput::make('cron_day_of_week')
->columnSpan(2)
->columnSpan([
'default' => 2,
'lg' => 1,
])
->label('Day of Week')
->default('*')
->required(),
Section::make('Presets')
->hiddenOn('view')
->columns(1)
->schema([
Actions::make([
Action::make('hourly')

View File

@ -3,9 +3,11 @@
namespace App\Models;
use App\Enums\ContainerStatus;
use App\Enums\ServerResourceType;
use App\Enums\ServerState;
use App\Exceptions\Http\Connection\DaemonConnectionException;
use App\Repositories\Daemon\DaemonServerRepository;
use Carbon\CarbonInterface;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@ -13,6 +15,7 @@ use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Number;
use Psr\Http\Message\ResponseInterface;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
@ -453,6 +456,32 @@ class Server extends Model
});
}
public function formatResource(string $resourceKey, bool $limit = false, ServerResourceType $type = ServerResourceType::Unit, int $precision = 2): string
{
$resourceAmount = $this->{$resourceKey} ?? 0;
if (!$limit) {
$resourceAmount = $this->resources()[$resourceKey] ?? 0;
}
if ($type === ServerResourceType::Time) {
if ($resourceAmount === 0) {
return 'Offline';
}
return now()->subMillis($resourceAmount)->diffForHumans(syntax: CarbonInterface::DIFF_ABSOLUTE, short: true, parts: 4);
}
if ($resourceAmount === 0 & $limit) {
return 'Unlimited';
}
if ($type === ServerResourceType::Percentage) {
return Number::format($resourceAmount, precision: $precision, locale: auth()->user()->language ?? 'en') . '%';
}
return convert_bytes_to_readable($resourceAmount, decimals: $precision, base: 3);
}
public function condition(): Attribute
{
return Attribute::make(
@ -481,4 +510,9 @@ class Server extends Model
return $this->status->color();
}
public function conditionColorHex(): string
{
return ContainerStatus::from($this->retrieveStatus())->colorHex();
}
}

View File

@ -19,7 +19,7 @@ if (!function_exists('is_ip')) {
}
if (!function_exists('convert_bytes_to_readable')) {
function convert_bytes_to_readable(int $bytes, int $decimals = 2): string
function convert_bytes_to_readable(int $bytes, int $decimals = 2, ?int $base = null): string
{
$conversionUnit = config('panel.use_binary_prefix') ? 1024 : 1000;
$suffix = config('panel.use_binary_prefix') ? ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB'] : ['Bytes', 'KB', 'MB', 'GB', 'TB'];
@ -28,10 +28,10 @@ if (!function_exists('convert_bytes_to_readable')) {
return '0 ' . $suffix[0];
}
$base = log($bytes) / log($conversionUnit);
$f_base = floor($base);
$fromBase = log($bytes) / log($conversionUnit);
$base ??= floor($fromBase);
return round(pow($conversionUnit, $base - $f_base), $decimals) . ' ' . $suffix[$f_base];
return round(pow($conversionUnit, $fromBase - $base), $decimals) . ' ' . $suffix[$base];
}
}

View File

@ -29,8 +29,8 @@
"phpseclib/phpseclib": "~3.0.18",
"pragmarx/google2fa": "~8.0.0",
"predis/predis": "~2.1.1",
"ryangjchandler/blade-tabler-icons": "^2.3",
"s1lentium/iptools": "~1.2.0",
"secondnetwork/blade-tabler-icons": "^3.26",
"socialiteproviders/authentik": "^5.2",
"socialiteproviders/discord": "^4.2",
"socialiteproviders/steam": "^4.2",
@ -93,4 +93,4 @@
},
"minimum-stability": "stable",
"prefer-stable": true
}
}

122
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2fddfe7f5db269cdf9e906b83c815756",
"content-hash": "4c83ce23eb3e0fab5738cdd7212e4fe3",
"packages": [
{
"name": "abdelhamiderrahmouni/filament-monaco-editor",
@ -6762,68 +6762,6 @@
],
"time": "2024-02-26T18:08:49+00:00"
},
{
"name": "ryangjchandler/blade-tabler-icons",
"version": "v2.3.0",
"source": {
"type": "git",
"url": "https://github.com/ryangjchandler/blade-tabler-icons.git",
"reference": "cd359f5d3b406a982dae1aaaf121d84067576a2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ryangjchandler/blade-tabler-icons/zipball/cd359f5d3b406a982dae1aaaf121d84067576a2e",
"reference": "cd359f5d3b406a982dae1aaaf121d84067576a2e",
"shasum": ""
},
"require": {
"blade-ui-kit/blade-icons": "^1.5",
"illuminate/support": "^10.0 || ^11.0",
"php": "^8.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.14",
"orchestra/testbench": "^8.0 || ^9.0",
"phpunit/phpunit": "^9.5.10 || ^10.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"RyanChandler\\TablerIcons\\BladeTablerIconsServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"RyanChandler\\TablerIcons\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ryan Chandler",
"email": "support@ryangjchandler.co.uk",
"homepage": "https://ryangjchandler.co.uk",
"role": "Developer"
}
],
"description": "A package to easily make use of Tabler icons in your Laravel Blade views.",
"homepage": "https://github.com/ryangjchandler/blade-tabler-icons",
"keywords": [
"blade",
"laravel",
"tabler"
],
"support": {
"issues": "https://github.com/ryangjchandler/blade-tabler-icons/issues",
"source": "https://github.com/ryangjchandler/blade-tabler-icons/tree/v2.3.0"
},
"time": "2024-03-12T23:54:24+00:00"
},
{
"name": "s1lentium/iptools",
"version": "v1.2.0",
@ -6879,6 +6817,64 @@
},
"time": "2022-08-17T14:28:59+00:00"
},
{
"name": "secondnetwork/blade-tabler-icons",
"version": "v3.26.0",
"source": {
"type": "git",
"url": "https://github.com/secondnetwork/blade-tabler-icons.git",
"reference": "d25677773f7b3a534faedcbba089bff7a25568e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/secondnetwork/blade-tabler-icons/zipball/d25677773f7b3a534faedcbba089bff7a25568e8",
"reference": "d25677773f7b3a534faedcbba089bff7a25568e8",
"shasum": ""
},
"require": {
"blade-ui-kit/blade-icons": "^1.1|^1.5|^1.6",
"illuminate/support": "^8.0|^9.0|^10.0|^11.0",
"php": "^7.4|^8.0"
},
"require-dev": {
"orchestra/testbench": "^6.0|^7.0|^9.0",
"phpunit/phpunit": "^9.0|^10.0|^11.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"secondnetwork\\TablerIcons\\BladeTablerIconsServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"secondnetwork\\TablerIcons\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Andreas Farah"
}
],
"description": "A package to easily make use of tabler-icons in your Laravel Blade views.",
"homepage": "https://github.com/secondnetwork/blade-tabler-icons",
"keywords": [
"blade",
"laravel",
"tabler-icons"
],
"support": {
"issues": "https://github.com/secondnetwork/blade-tabler-icons/issues",
"source": "https://github.com/secondnetwork/blade-tabler-icons/tree/v3.26.0"
},
"time": "2024-12-21T15:50:20+00:00"
},
{
"name": "socialiteproviders/authentik",
"version": "5.2.0",

View File

@ -20,7 +20,6 @@
class="w-full focus:outline-none focus:ring-0 border-none"
style="background-color: #202A32;"
type="text"
autofocus
:readonly="{{ $this->canSendCommand() ? 'false' : 'true' }}"
title="{{ $this->canSendCommand() ? '' : 'Can\'t send command when the server is Offline' }}"
placeholder="{{ $this->canSendCommand() ? 'Type a command...' : 'Server Offline...' }}"
@ -126,7 +125,7 @@
case 'status':
handlePowerChangeEvent(args[0]);
$wire.dispatch('console-status', {state: args[0]})
$wire.dispatch('console-status', { state: args[0] });
break;
case 'transfer status':
handleTransferStatus(args[0]);

View File

@ -1,65 +1,67 @@
@php
use App\Enums\ServerResourceType;
/** @var \App\Models\Server $server */
$server = $getRecord();
@endphp
<head>
<style>
.inline-flex {
display: inline-flex;
align-items: center;
gap: 0.75rem;
hr {
border-color: #9ca3af;
}
</style>
</head>
<div class="w-full grid gap-y-2 overflow-x-auto">
<div class="flex items-center gap-x-1">
<x-filament::icon-button
:icon="$getRecord()->conditionIcon()"
:color="$getRecord()->conditionColor()"
:tooltip="\Illuminate\Support\Str::title($getRecord()->condition)" size="xl"
/>
<div class="w-full">
<!-- Wrapper for Positioning -->
<div class="relative flex">
<!-- Status Strip Outside the Box -->
<div
class="absolute left-0 top-1 bottom-0 w-1 rounded-lg"
style="background-color: {{ $server->conditionColorHex() }};">
</div>
<span class="text-2xl font-semibold text-gray-500 dark:text-gray-400">
{{ $getRecord()->name }} ({{ $this->uptime($getRecord()) }})
</span>
</div>
<!-- Card Component -->
<div class="flex-1 bg-gray-800 text-white rounded-lg overflow-hidden p-3">
<!-- Header -->
<div class="flex items-center mb-5 gap-2">
<x-filament::icon-button
:icon="$server->conditionIcon()"
:color="$server->conditionColor()"
:tooltip="\Illuminate\Support\Str::title($server->condition)"
size="xl"
/>
<h2 class="text-xl font-bold">
{{ $server->name }}
<span class="text-gray-400">({{ $server->formatResource('uptime', type: ServerResourceType::Time) }})</span>
</h2>
</div>
<div class="flex">
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="Egg Name">
<x-filament::icon
icon="tabler-egg"
/>
{{ $getRecord()->egg->name }}
</div>
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="Owner">
<x-filament::icon
icon="tabler-user"
/>
{{ $getRecord()->user->username }}
</div>
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="Primary Allocation">
<x-filament::icon
icon="tabler-network"
/>
{{ $getRecord()->allocation->address }}
</div>
</div>
<div class="flex">
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="CPU Usage">
<x-filament::icon
icon="tabler-cpu"
/>
{{ $this->cpu($getRecord()) }}
</div>
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="Memory Usage">
<x-filament::icon
icon="tabler-device-desktop-analytics"
/>
{{ $this->memory($getRecord()) }}
</div>
<div class="flex-1 text-md font-medium text-gray-850 dark:text-white inline-flex" title="Disk Usage">
<x-filament::icon
icon="tabler-packages"
/>
{{ $this->disk($getRecord()) }}
<!-- Resource Usage -->
<div class="flex justify-between text-center">
<div>
<p class="text-sm text-gray-400">CPU</p>
<p class="text-md font-semibold">{{ $server->formatResource('cpu_absolute', type: ServerResourceType::Percentage) }}</p>
<hr class="p-0.5">
<p class="text-xs text-gray-400">{{ $server->formatResource('cpu', type: ServerResourceType::Percentage, limit: true) }}</p>
</div>
<div>
<p class="text-sm text-gray-400">Memory</p>
<p class="text-md font-semibold">{{ $server->formatResource('memory_bytes') }}</p>
<hr class="p-0.5">
<p class="text-xs text-gray-400">{{ $server->formatResource('memory', limit: true) }}</p>
</div>
<div>
<p class="text-sm text-gray-400">Disk</p>
<p class="text-md font-semibold">{{ $server->formatResource('disk_bytes') }}</p>
<hr class="p-0.5">
<p class="text-xs text-gray-400">{{ $server->formatResource('disk', limit: true) }}</p>
</div>
<div class="hidden sm:block">
<p class="text-sm text-gray-400">Network</p>
<p class="text-md font-semibold">{{ $server->allocation->address }} </p>
</div>
</div>
</div>
</div>
</div>