Add server power actions to new context menu (#1321)

* add server power action context menu

* Update app/Filament/App/Resources/ServerResource/Pages/ListServers.php

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

* Cleanup

* Add missed enable

---------

Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
Co-authored-by: RMartinOscar <40749467+RMartinOscar@users.noreply.github.com>
This commit is contained in:
Charles 2025-05-02 12:15:05 -04:00 committed by GitHub
parent 2d581c7cbd
commit 82ef6c1408
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 162 additions and 8 deletions

View File

@ -6,15 +6,22 @@ use App\Enums\ServerResourceType;
use App\Filament\App\Resources\ServerResource;
use App\Filament\Components\Tables\Columns\ServerEntryColumn;
use App\Filament\Server\Pages\Console;
use App\Models\Permission;
use App\Models\Server;
use App\Repositories\Daemon\DaemonPowerRepository;
use AymanAlhattami\FilamentContextMenu\Columns\ContextMenuTextColumn;
use Filament\Notifications\Notification;
use Filament\Resources\Components\Tab;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\Action;
use Filament\Tables\Columns\ColumnGroup;
use Filament\Tables\Columns\Layout\Stack;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Client\ConnectionException;
use Livewire\Attributes\On;
class ListServers extends ListRecords
{
@ -24,12 +31,51 @@ class ListServers extends ListRecords
public const WARNING_THRESHOLD = 0.7;
private DaemonPowerRepository $daemonPowerRepository;
public function boot(): void
{
$this->daemonPowerRepository = new DaemonPowerRepository();
}
public function table(Table $table): Table
{
$baseQuery = auth()->user()->accessibleServers();
$menuOptions = function (Server $server) {
$status = $server->retrieveStatus();
return [
Action::make('start')
->color('primary')
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_START, $server))
->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 = [
TextColumn::make('condition')
ContextMenuTextColumn::make('condition')
->label('')
->default('unknown')
->wrap()
@ -37,20 +83,24 @@ class ListServers extends ListRecords
->alignCenter()
->tooltip(fn (Server $server) => $server->formatResource('uptime', type: ServerResourceType::Time))
->icon(fn (Server $server) => $server->condition->getIcon())
->color(fn (Server $server) => $server->condition->getColor()),
->color(fn (Server $server) => $server->condition->getColor())
->contextMenuActions($menuOptions)
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
];
$viewTwo = [
TextColumn::make('name')
ContextMenuTextColumn::make('name')
->label('')
->size('md')
->searchable(),
TextColumn::make('')
->searchable()
->contextMenuActions($menuOptions)
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
ContextMenuTextColumn::make('allocation.address')
->label('')
->badge()
->copyable(request()->isSecure())
->copyMessage(fn (Server $server, string $state) => 'Copied ' . $server->allocation->address)
->state(fn (Server $server) => $server->allocation->address),
->contextMenuActions($menuOptions)
->enableContextMenu(fn (Server $server) => !$server->isInConflictState()),
];
$viewThree = [
@ -190,4 +240,25 @@ class ListServers extends ListRecords
return null;
}
#[On('powerAction')]
public function powerAction(Server $server, string $action): void
{
try {
$this->daemonPowerRepository->setServer($server)->send($action);
Notification::make()
->title('Power Action')
->body($action . ' sent to ' . $server->name)
->success()
->send();
$this->redirect(self::getUrl(['activeTab' => $this->activeTab]));
} catch (ConnectionException) {
Notification::make()
->title(trans('exceptions.node.error_connecting', ['node' => $server->node->name]))
->danger()
->send();
}
}
}

View File

@ -10,6 +10,7 @@
"ext-zip": "*",
"abdelhamiderrahmouni/filament-monaco-editor": "^0.2.5",
"aws/aws-sdk-php": "^3.342",
"aymanalhattami/filament-context-menu": "^1.0",
"calebporzio/sushi": "^2.5",
"chillerlan/php-qrcode": "^5.0.2",
"dedoc/scramble": "^0.12.10",

82
composer.lock generated
View File

@ -4,7 +4,11 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
<<<<<<< HEAD
"content-hash": "27da5be2bf613398e6fa75cdf8131bf7",
=======
"content-hash": "5c5a89d4207dd9efb7a8c3a410aa838c",
>>>>>>> main
"packages": [
{
"name": "abdelhamiderrahmouni/filament-monaco-editor",
@ -1115,6 +1119,82 @@
},
"time": "2025-05-01T18:05:02+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",
"version": "2.6.0",
@ -15903,7 +15983,7 @@
"ext-pdo": "*",
"ext-zip": "*"
},
"platform-dev": [],
"platform-dev": {},
"platform-overrides": {
"php": "8.2"
},

View File

@ -4,6 +4,7 @@ return [
'daemon_connection_failed' => 'There was an exception while attempting to communicate with the daemon resulting in a HTTP/:code response code. This exception has been logged.',
'node' => [
'servers_attached' => 'A node must have no servers linked to it in order to be deleted.',
'error_connecting' => 'Error connecting to :node',
'daemon_off_config_updated' => 'The daemon configuration <strong>has been updated</strong>, however there was an error encountered while attempting to automatically update the configuration file on the Daemon. You will need to manually update the configuration file (config.yml) for the daemon to apply these changes.',
],
'allocations' => [

File diff suppressed because one or more lines are too long