mirror of
https://github.com/pelican-dev/panel.git
synced 2025-06-20 16:31:08 +02:00
Cleanup & fix server list (#1433)
This commit is contained in:
parent
b05eabfdb0
commit
1dc5ec027e
@ -88,7 +88,7 @@ enum ContainerStatus: string implements HasColor, HasIcon, HasLabel
|
|||||||
|
|
||||||
public function isStartable(): bool
|
public function isStartable(): bool
|
||||||
{
|
{
|
||||||
return !in_array($this, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting]);
|
return !in_array($this, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Missing]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isRestartable(): bool
|
public function isRestartable(): bool
|
||||||
@ -97,18 +97,16 @@ enum ContainerStatus: string implements HasColor, HasIcon, HasLabel
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !in_array($this, [ContainerStatus::Offline]);
|
return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Missing]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isStoppable(): bool
|
public function isStoppable(): bool
|
||||||
{
|
{
|
||||||
return !in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline]);
|
return !in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline, ContainerStatus::Missing]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isKillable(): bool
|
public function isKillable(): bool
|
||||||
{
|
{
|
||||||
// [ContainerStatus::Restarting, ContainerStatus::Removing, ContainerStatus::Dead, ContainerStatus::Created]
|
return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Running, ContainerStatus::Exited, ContainerStatus::Missing]);
|
||||||
|
|
||||||
return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Running, ContainerStatus::Exited]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,16 @@ enum ServerState: string implements HasColor, HasIcon, HasLabel
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getColor(): string
|
public function getColor(bool $hex = false): string
|
||||||
{
|
{
|
||||||
|
if ($hex) {
|
||||||
|
return match ($this) {
|
||||||
|
self::Normal, self::Installing, self::RestoringBackup => '#2563EB',
|
||||||
|
self::Suspended => '#D97706',
|
||||||
|
self::InstallFailed, self::ReinstallFailed => '#EF4444',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Normal => 'primary',
|
self::Normal => 'primary',
|
||||||
self::Installing => 'primary',
|
self::Installing => 'primary',
|
||||||
|
@ -9,12 +9,13 @@ use App\Filament\Server\Pages\Console;
|
|||||||
use App\Models\Permission;
|
use App\Models\Permission;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||||
use AymanAlhattami\FilamentContextMenu\Columns\ContextMenuTextColumn;
|
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Components\Tab;
|
use Filament\Resources\Components\Tab;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
use Filament\Support\Enums\Alignment;
|
||||||
use Filament\Tables\Actions\Action;
|
use Filament\Tables\Actions\Action;
|
||||||
use Filament\Tables\Columns\ColumnGroup;
|
use Filament\Tables\Actions\ActionGroup;
|
||||||
|
use Filament\Tables\Columns\Column;
|
||||||
use Filament\Tables\Columns\Layout\Stack;
|
use Filament\Tables\Columns\Layout\Stack;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Filters\SelectFilter;
|
use Filament\Tables\Filters\SelectFilter;
|
||||||
@ -38,121 +39,73 @@ class ListServers extends ListRecords
|
|||||||
$this->daemonPowerRepository = new DaemonPowerRepository();
|
$this->daemonPowerRepository = new DaemonPowerRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function table(Table $table): Table
|
/** @return Stack[] */
|
||||||
|
protected function gridColumns(): array
|
||||||
{
|
{
|
||||||
$baseQuery = auth()->user()->accessibleServers();
|
|
||||||
|
|
||||||
$menuOptions = function (Server $server) {
|
|
||||||
$status = $server->retrieveStatus();
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Action::make('start')
|
Stack::make([
|
||||||
->color('primary')
|
ServerEntryColumn::make('server_entry')
|
||||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_START, $server))
|
->searchable(['name']),
|
||||||
->visible(fn () => $status->isStartable())
|
]),
|
||||||
->dispatch('powerAction', ['server' => $server, 'action' => 'start'])
|
|
||||||
->icon('tabler-player-play-filled'),
|
|
||||||
Action::make('restart')
|
|
||||||
->color('gray')
|
|
||||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_RESTART, $server))
|
|
||||||
->visible(fn () => $status->isRestartable())
|
|
||||||
->dispatch('powerAction', ['server' => $server, 'action' => 'restart'])
|
|
||||||
->icon('tabler-refresh'),
|
|
||||||
Action::make('stop')
|
|
||||||
->color('danger')
|
|
||||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
|
||||||
->visible(fn () => $status->isStoppable())
|
|
||||||
->dispatch('powerAction', ['server' => $server, 'action' => 'stop'])
|
|
||||||
->icon('tabler-player-stop-filled'),
|
|
||||||
Action::make('kill')
|
|
||||||
->color('danger')
|
|
||||||
->tooltip('This can result in data corruption and/or data loss!')
|
|
||||||
->dispatch('powerAction', ['server' => $server, 'action' => 'kill'])
|
|
||||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
|
||||||
->visible(fn () => $status->isKillable())
|
|
||||||
->icon('tabler-alert-square'),
|
|
||||||
];
|
];
|
||||||
};
|
}
|
||||||
|
|
||||||
$viewOne = [
|
/** @return Column[] */
|
||||||
ContextMenuTextColumn::make('condition')
|
protected function tableColumns(): array
|
||||||
->label('')
|
{
|
||||||
->default('unknown')
|
return [
|
||||||
->wrap()
|
TextColumn::make('condition')
|
||||||
|
->label('Status')
|
||||||
->badge()
|
->badge()
|
||||||
->alignCenter()
|
|
||||||
->tooltip(fn (Server $server) => $server->formatResource('uptime', type: ServerResourceType::Time))
|
->tooltip(fn (Server $server) => $server->formatResource('uptime', type: ServerResourceType::Time))
|
||||||
->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()),
|
||||||
->contextMenuActions($menuOptions)
|
TextColumn::make('name')
|
||||||
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
|
->label('Server')
|
||||||
];
|
->description(fn (Server $server) => $server->description)
|
||||||
|
->grow()
|
||||||
$viewTwo = [
|
->searchable(),
|
||||||
ContextMenuTextColumn::make('name')
|
TextColumn::make('allocation.address')
|
||||||
->label('')
|
|
||||||
->size('md')
|
|
||||||
->searchable()
|
|
||||||
->contextMenuActions($menuOptions)
|
|
||||||
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
|
|
||||||
ContextMenuTextColumn::make('allocation.address')
|
|
||||||
->label('')
|
->label('')
|
||||||
->badge()
|
->badge()
|
||||||
->copyable(request()->isSecure())
|
->visibleFrom('md')
|
||||||
->contextMenuActions($menuOptions)
|
->copyable(request()->isSecure()),
|
||||||
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
|
|
||||||
];
|
|
||||||
|
|
||||||
$viewThree = [
|
|
||||||
TextColumn::make('cpuUsage')
|
TextColumn::make('cpuUsage')
|
||||||
->label('')
|
->label('Resources')
|
||||||
->icon('tabler-cpu')
|
->icon('tabler-cpu')
|
||||||
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('cpu', limit: true, type: ServerResourceType::Percentage, precision: 0))
|
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('cpu', limit: true, type: ServerResourceType::Percentage, precision: 0))
|
||||||
->state(fn (Server $server) => $server->formatResource('cpu_absolute', type: ServerResourceType::Percentage))
|
->state(fn (Server $server) => $server->formatResource('cpu_absolute', type: ServerResourceType::Percentage))
|
||||||
->color(fn (Server $server) => $this->getResourceColor($server, 'cpu')),
|
->color(fn (Server $server) => $this->getResourceColor($server, 'cpu')),
|
||||||
TextColumn::make('memoryUsage')
|
TextColumn::make('memoryUsage')
|
||||||
->label('')
|
->label('')
|
||||||
->icon('tabler-memory')
|
->icon('tabler-device-desktop-analytics')
|
||||||
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('memory', limit: true))
|
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('memory', limit: true))
|
||||||
->state(fn (Server $server) => $server->formatResource('memory_bytes'))
|
->state(fn (Server $server) => $server->formatResource('memory_bytes'))
|
||||||
->color(fn (Server $server) => $this->getResourceColor($server, 'memory')),
|
->color(fn (Server $server) => $this->getResourceColor($server, 'memory')),
|
||||||
TextColumn::make('diskUsage')
|
TextColumn::make('diskUsage')
|
||||||
->label('')
|
->label('')
|
||||||
->icon('tabler-device-floppy')
|
->icon('tabler-device-sd-card')
|
||||||
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('disk', limit: true))
|
->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('disk', limit: true))
|
||||||
->state(fn (Server $server) => $server->formatResource('disk_bytes'))
|
->state(fn (Server $server) => $server->formatResource('disk_bytes'))
|
||||||
->color(fn (Server $server) => $this->getResourceColor($server, 'disk')),
|
->color(fn (Server $server) => $this->getResourceColor($server, 'disk')),
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table(Table $table): Table
|
||||||
|
{
|
||||||
|
$baseQuery = auth()->user()->accessibleServers();
|
||||||
|
|
||||||
|
$usingGrid = (auth()->user()->getCustomization()['dashboard_layout'] ?? 'grid') === 'grid';
|
||||||
|
|
||||||
return $table
|
return $table
|
||||||
->paginated(false)
|
->paginated(false)
|
||||||
->query(fn () => $baseQuery)
|
->query(fn () => $baseQuery)
|
||||||
->poll('15s')
|
->poll('15s')
|
||||||
->columns(
|
->columns($usingGrid ? $this->gridColumns() : $this->tableColumns())
|
||||||
(auth()->user()->getCustomization()['dashboard_layout'] ?? 'grid') === 'grid'
|
->recordUrl(!$usingGrid ? (fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server)) : null)
|
||||||
? [
|
->actions(!$usingGrid ? ActionGroup::make(static::getPowerActions()) : [])
|
||||||
Stack::make([
|
->actionsAlignment(Alignment::Center->value)
|
||||||
ServerEntryColumn::make('server_entry')
|
->contentGrid($usingGrid ? ['default' => 1, 'md' => 2] : null)
|
||||||
->searchable(['name']),
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
ColumnGroup::make('Status')
|
|
||||||
->label('Status')
|
|
||||||
->columns($viewOne),
|
|
||||||
ColumnGroup::make('Server')
|
|
||||||
->label('Servers')
|
|
||||||
->columns($viewTwo),
|
|
||||||
ColumnGroup::make('Resources')
|
|
||||||
->label('Resources')
|
|
||||||
->columns($viewThree),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
->recordUrl(fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server))
|
|
||||||
->contentGrid([
|
|
||||||
'default' => 1,
|
|
||||||
'md' => 2,
|
|
||||||
])
|
|
||||||
->emptyStateIcon('tabler-brand-docker')
|
->emptyStateIcon('tabler-brand-docker')
|
||||||
->emptyStateDescription('')
|
->emptyStateDescription('')
|
||||||
->emptyStateHeading(fn () => $this->activeTab === 'my' ? 'You don\'t own any servers!' : 'You don\'t have access to any servers!')
|
->emptyStateHeading(fn () => $this->activeTab === 'my' ? 'You don\'t own any servers!' : 'You don\'t have access to any servers!')
|
||||||
@ -195,36 +148,33 @@ class ListServers extends ListRecords
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResourceColor(Server $server, string $resource): ?string
|
protected function getResourceColor(Server $server, string $resource): ?string
|
||||||
{
|
{
|
||||||
$current = null;
|
$current = null;
|
||||||
$limit = null;
|
$limit = null;
|
||||||
|
|
||||||
switch ($resource) {
|
switch ($resource) {
|
||||||
case 'cpu':
|
case 'cpu':
|
||||||
$current = $server->resources()['cpu_absolute'] ?? 0;
|
$current = $server->retrieveResources()['cpu_absolute'] ?? 0;
|
||||||
$limit = $server->cpu;
|
$limit = $server->cpu;
|
||||||
if ($server->cpu === 0) {
|
if ($server->cpu === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'memory':
|
case 'memory':
|
||||||
$current = $server->resources()['memory_bytes'] ?? 0;
|
$current = $server->retrieveResources()['memory_bytes'] ?? 0;
|
||||||
$limit = $server->memory * 2 ** 20;
|
$limit = $server->memory * 2 ** 20;
|
||||||
if ($server->memory === 0) {
|
if ($server->memory === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'disk':
|
case 'disk':
|
||||||
$current = $server->resources()['disk_bytes'] ?? 0;
|
$current = $server->retrieveResources()['disk_bytes'] ?? 0;
|
||||||
$limit = $server->disk * 2 ** 20;
|
$limit = $server->disk * 2 ** 20;
|
||||||
if ($server->disk === 0) {
|
if ($server->disk === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -238,7 +188,6 @@ class ListServers extends ListRecords
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[On('powerAction')]
|
#[On('powerAction')]
|
||||||
@ -253,6 +202,8 @@ class ListServers extends ListRecords
|
|||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
cache()->forget("servers.$server->uuid.status");
|
||||||
|
|
||||||
$this->redirect(self::getUrl(['activeTab' => $this->activeTab]));
|
$this->redirect(self::getUrl(['activeTab' => $this->activeTab]));
|
||||||
} catch (ConnectionException) {
|
} catch (ConnectionException) {
|
||||||
Notification::make()
|
Notification::make()
|
||||||
@ -261,4 +212,36 @@ class ListServers extends ListRecords
|
|||||||
->send();
|
->send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return Action[] */
|
||||||
|
public static function getPowerActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Action::make('start')
|
||||||
|
->color('primary')
|
||||||
|
->icon('tabler-player-play-filled')
|
||||||
|
->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_START, $server))
|
||||||
|
->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isStartable())
|
||||||
|
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'start']),
|
||||||
|
Action::make('restart')
|
||||||
|
->color('gray')
|
||||||
|
->icon('tabler-reload')
|
||||||
|
->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_RESTART, $server))
|
||||||
|
->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isRestartable())
|
||||||
|
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'restart']),
|
||||||
|
Action::make('stop')
|
||||||
|
->color('danger')
|
||||||
|
->icon('tabler-player-stop-filled')
|
||||||
|
->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
||||||
|
->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isStoppable())
|
||||||
|
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'stop']),
|
||||||
|
Action::make('kill')
|
||||||
|
->color('danger')
|
||||||
|
->icon('tabler-alert-square')
|
||||||
|
->tooltip('This can result in data corruption and/or data loss!')
|
||||||
|
->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
||||||
|
->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isKillable())
|
||||||
|
->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'kill']),
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,26 +333,6 @@ class Node extends Model implements Validatable
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<array-key, mixed>
|
|
||||||
*/
|
|
||||||
public function serverStatuses(): array
|
|
||||||
{
|
|
||||||
$statuses = [];
|
|
||||||
try {
|
|
||||||
$statuses = Http::daemon($this)->connectTimeout(1)->timeout(1)->get('/api/servers')->json() ?? [];
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
report($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($statuses as $status) {
|
|
||||||
$uuid = fluent($status)->get('configuration.uuid');
|
|
||||||
cache()->remember("servers.$uuid.container.status", now()->addMinute(), fn () => fluent($status)->get('state'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $statuses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return array{
|
/** @return array{
|
||||||
* memory_total: int, memory_used: int,
|
* memory_total: int, memory_used: int,
|
||||||
* swap_total: int, swap_used: int,
|
* swap_total: int, swap_used: int,
|
||||||
|
@ -435,25 +435,24 @@ class Server extends Model implements Validatable
|
|||||||
|
|
||||||
public function retrieveStatus(): ContainerStatus
|
public function retrieveStatus(): ContainerStatus
|
||||||
{
|
{
|
||||||
$status = cache()->get("servers.$this->uuid.container.status");
|
return cache()->remember("servers.$this->uuid.status", now()->addSeconds(15), function () {
|
||||||
|
// @phpstan-ignore myCustomRules.forbiddenGlobalFunctions
|
||||||
|
$details = app(DaemonServerRepository::class)->setServer($this)->getDetails();
|
||||||
|
|
||||||
if ($status === null) {
|
return ContainerStatus::tryFrom(Arr::get($details, 'state')) ?? ContainerStatus::Missing;
|
||||||
$this->node->serverStatuses();
|
});
|
||||||
|
|
||||||
$status = cache()->get("servers.$this->uuid.container.status");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ContainerStatus::tryFrom($status) ?? ContainerStatus::Missing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<mixed>
|
* @return array<mixed>
|
||||||
*/
|
*/
|
||||||
public function resources(): array
|
public function retrieveResources(): array
|
||||||
{
|
{
|
||||||
return cache()->remember("resources:$this->uuid", now()->addSeconds(15), function () {
|
return cache()->remember("servers.$this->uuid.resources", now()->addSeconds(15), function () {
|
||||||
// @phpstan-ignore myCustomRules.forbiddenGlobalFunctions
|
// @phpstan-ignore myCustomRules.forbiddenGlobalFunctions
|
||||||
return Arr::get(app(DaemonServerRepository::class)->setServer($this)->getDetails(), 'utilization', []);
|
$details = app(DaemonServerRepository::class)->setServer($this)->getDetails();
|
||||||
|
|
||||||
|
return Arr::get($details, 'utilization', []);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +460,7 @@ class Server extends Model implements Validatable
|
|||||||
{
|
{
|
||||||
$resourceAmount = $this->{$resourceKey} ?? 0;
|
$resourceAmount = $this->{$resourceKey} ?? 0;
|
||||||
if (!$limit) {
|
if (!$limit) {
|
||||||
$resourceAmount = $this->resources()[$resourceKey] ?? 0;
|
$resourceAmount = $this->retrieveResources()[$resourceKey] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type === ServerResourceType::Time) {
|
if ($type === ServerResourceType::Time) {
|
||||||
@ -494,7 +493,7 @@ class Server extends Model implements Validatable
|
|||||||
public function condition(): Attribute
|
public function condition(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
get: fn () => $this->isSuspended() ? ServerState::Suspended : $this->status ?? $this->retrieveStatus(),
|
get: fn () => $this->status ?? $this->retrieveStatus(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"ext-zip": "*",
|
"ext-zip": "*",
|
||||||
"abdelhamiderrahmouni/filament-monaco-editor": "^0.2.5",
|
"abdelhamiderrahmouni/filament-monaco-editor": "^0.2.5",
|
||||||
"aws/aws-sdk-php": "^3.344",
|
"aws/aws-sdk-php": "^3.344",
|
||||||
"aymanalhattami/filament-context-menu": "^1.0",
|
|
||||||
"calebporzio/sushi": "^2.5",
|
"calebporzio/sushi": "^2.5",
|
||||||
"chillerlan/php-qrcode": "^5.0.2",
|
"chillerlan/php-qrcode": "^5.0.2",
|
||||||
"dedoc/scramble": "^0.12.10",
|
"dedoc/scramble": "^0.12.10",
|
||||||
|
82
composer.lock
generated
82
composer.lock
generated
@ -1113,83 +1113,7 @@
|
|||||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.344.3"
|
"source": "https://github.com/aws/aws-sdk-php/tree/3.344.3"
|
||||||
},
|
},
|
||||||
"time": "2025-06-09T18:04:12+00:00"
|
"time": "2025-06-02T18:04:47+00:00"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "aymanalhattami/filament-context-menu",
|
|
||||||
"version": "1.0.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/aymanalhattami/filament-context-menu.git",
|
|
||||||
"reference": "5118d36303e86891d3037e6e26882d548b880b9c"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/aymanalhattami/filament-context-menu/zipball/5118d36303e86891d3037e6e26882d548b880b9c",
|
|
||||||
"reference": "5118d36303e86891d3037e6e26882d548b880b9c",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"filament/filament": "^3.0",
|
|
||||||
"php": "^8.2",
|
|
||||||
"spatie/laravel-package-tools": "^1.15.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"larastan/larastan": "^2.0",
|
|
||||||
"laravel/pint": "^1.0",
|
|
||||||
"nunomaduro/collision": "^8.0",
|
|
||||||
"orchestra/testbench": "^9.0",
|
|
||||||
"pestphp/pest": "^3.0",
|
|
||||||
"pestphp/pest-plugin-arch": "^3.0",
|
|
||||||
"pestphp/pest-plugin-laravel": "^3.0",
|
|
||||||
"phpstan/extension-installer": "^1.0",
|
|
||||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
|
||||||
"phpstan/phpstan-phpunit": "^1.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"laravel": {
|
|
||||||
"aliases": {
|
|
||||||
"Skeleton": "AymanAlhattami\\FilamentContextMenu\\Facades\\FilamentContextMenu"
|
|
||||||
},
|
|
||||||
"providers": [
|
|
||||||
"AymanAlhattami\\FilamentContextMenu\\FilamentContextMenuServiceProvider"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"AymanAlhattami\\FilamentContextMenu\\": "src/",
|
|
||||||
"AymanAlhattami\\FilamentContextMenu\\Database\\Factories\\": "database/factories/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Ayman Alhattami",
|
|
||||||
"email": "ayman.m.alhattami@gmail.com",
|
|
||||||
"role": "Developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "context menu (right click menu) for filament",
|
|
||||||
"homepage": "https://github.com/aymanalhattami/filament-context-menu",
|
|
||||||
"keywords": [
|
|
||||||
"ayman alhattami",
|
|
||||||
"context menu",
|
|
||||||
"filament",
|
|
||||||
"filament admin panel",
|
|
||||||
"filament context menu",
|
|
||||||
"filament_context_menu",
|
|
||||||
"laravel"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/aymanalhattami/filament-context-menu/issues",
|
|
||||||
"source": "https://github.com/aymanalhattami/filament-context-menu"
|
|
||||||
},
|
|
||||||
"time": "2024-09-22T10:47:31+00:00"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "blade-ui-kit/blade-heroicons",
|
"name": "blade-ui-kit/blade-heroicons",
|
||||||
@ -15981,7 +15905,7 @@
|
|||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {},
|
"stability-flags": [],
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
@ -15992,7 +15916,7 @@
|
|||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
"ext-zip": "*"
|
"ext-zip": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": [],
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
"php": "8.2"
|
"php": "8.2"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<div class="relative">
|
<div wire:poll.15s class="relative">
|
||||||
|
<a href="{{ \App\Filament\Server\Pages\Console::getUrl(panel: 'server', tenant: $server) }}" wire:navigate>
|
||||||
<div
|
<div
|
||||||
class="absolute left-0 top-1 bottom-0 w-1 rounded-lg"
|
class="absolute left-0 top-1 bottom-0 w-1 rounded-lg"
|
||||||
style="background-color: {{ $server->condition->getColor(true) }};">
|
style="background-color: {{ $server->condition->getColor(true) }};">
|
||||||
@ -44,4 +45,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<x-filament-tables::actions
|
||||||
|
:actions="\App\Filament\App\Resources\ServerResource\Pages\ListServers::getPowerActions()"
|
||||||
|
:alignment="\Filament\Support\Enums\Alignment::Center"
|
||||||
|
:record="$server"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
Loading…
x
Reference in New Issue
Block a user