mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 06:56:15 +00:00
2.x
This commit is contained in:
263
app/Web/Pages/Servers/Widgets/CreateServer.php
Normal file
263
app/Web/Pages/Servers/Widgets/CreateServer.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Actions\Server\CreateServer as CreateServerAction;
|
||||
use App\Enums\ServerProvider;
|
||||
use App\Enums\ServerType;
|
||||
use App\Enums\Webserver;
|
||||
use App\Models\Server;
|
||||
use App\Web\Fields\AlertField;
|
||||
use App\Web\Fields\ProviderField;
|
||||
use App\Web\Pages\Servers\Index;
|
||||
use App\Web\Pages\Settings\ServerProviders\Actions\Create;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Filament\Widgets\Widget;
|
||||
use Throwable;
|
||||
|
||||
class CreateServer extends Widget implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static string $view = 'web.components.form';
|
||||
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
||||
public ?string $provider = ServerProvider::HETZNER;
|
||||
|
||||
public ?string $server_provider = '';
|
||||
|
||||
public ?string $region = '';
|
||||
|
||||
public ?string $plan = '';
|
||||
|
||||
public ?string $public_key = '';
|
||||
|
||||
public ?string $name = '';
|
||||
|
||||
public ?string $ip = '';
|
||||
|
||||
public ?string $port = '';
|
||||
|
||||
public ?string $os = '';
|
||||
|
||||
public ?string $type = ServerType::REGULAR;
|
||||
|
||||
public ?string $webserver = Webserver::NGINX;
|
||||
|
||||
public ?string $database = '';
|
||||
|
||||
public ?string $php = '';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
$publicKey = __('servers.create.public_key_text', [
|
||||
'public_key' => get_public_key_content(),
|
||||
]);
|
||||
|
||||
return $form
|
||||
->schema([
|
||||
ProviderField::make('provider')
|
||||
->label('Select a provider')
|
||||
->default(ServerProvider::CUSTOM)
|
||||
->live()
|
||||
->reactive()
|
||||
->reactive()
|
||||
->afterStateUpdated(function (callable $set) {
|
||||
$set('server_provider', null);
|
||||
$set('region', null);
|
||||
$set('plan', null);
|
||||
})
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['provider']),
|
||||
AlertField::make('alert')
|
||||
->warning()
|
||||
->message(__('servers.create.public_key_warning'))
|
||||
->visible(fn ($get) => $this->provider === ServerProvider::CUSTOM),
|
||||
Select::make('server_provider')
|
||||
->visible(fn ($get) => $this->provider !== ServerProvider::CUSTOM)
|
||||
->label('Server provider connection')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['server_provider'])
|
||||
->options(function ($get) {
|
||||
return \App\Models\ServerProvider::getByProjectId(auth()->user()->current_project_id)
|
||||
->where('provider', $this->provider)
|
||||
->pluck('profile', 'id');
|
||||
})
|
||||
->live()
|
||||
->suffixAction(
|
||||
Action::make('connect')
|
||||
->form(Create::form())
|
||||
->modalHeading('Connect to a new server provider')
|
||||
->modalSubmitActionLabel('Connect')
|
||||
->icon('heroicon-o-wifi')
|
||||
->tooltip('Connect to a new server provider')
|
||||
->modalWidth(MaxWidth::Medium)
|
||||
->authorize(fn () => auth()->user()->can('create', \App\Models\ServerProvider::class))
|
||||
// TODO: remove this after filament #14319 is fixed
|
||||
->url(\App\Web\Pages\Settings\ServerProviders\Index::getUrl())
|
||||
->action(fn (array $data) => Create::action($data))
|
||||
)
|
||||
->placeholder('Select profile')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->visible(fn ($get) => $this->provider !== ServerProvider::CUSTOM),
|
||||
Grid::make()
|
||||
->schema([
|
||||
Select::make('region')
|
||||
->label('Region')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['region'])
|
||||
->live()
|
||||
->reactive()
|
||||
->options(function () {
|
||||
if (! $this->server_provider) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return \App\Models\ServerProvider::regions($this->server_provider);
|
||||
})
|
||||
->loadingMessage('Loading regions...')
|
||||
->disabled(fn ($get) => ! $this->server_provider)
|
||||
->placeholder(fn ($get) => $this->server_provider ? 'Select region' : 'Select connection first')
|
||||
->searchable(),
|
||||
Select::make('plan')
|
||||
->label('Plan')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['plan'])
|
||||
->reactive()
|
||||
->options(function () {
|
||||
if (! $this->server_provider || ! $this->region) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return \App\Models\ServerProvider::plans($this->server_provider, $this->region);
|
||||
})
|
||||
->loadingMessage('Loading plans...')
|
||||
->disabled(fn ($get) => ! $this->region)
|
||||
->placeholder(fn ($get) => $this->region ? 'Select plan' : 'Select plan first')
|
||||
->searchable(),
|
||||
])
|
||||
->visible(fn ($get) => $this->provider !== ServerProvider::CUSTOM),
|
||||
TextInput::make('public_key')
|
||||
->label('Public Key')
|
||||
->default($publicKey)
|
||||
->suffixAction(
|
||||
Action::make('copy')
|
||||
->icon('heroicon-o-clipboard-document-list')
|
||||
->tooltip('Copy')
|
||||
->action(function ($livewire, $state) {
|
||||
$livewire->js(
|
||||
'window.navigator.clipboard.writeText("'.$state.'");'
|
||||
);
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Copied!')
|
||||
->send();
|
||||
})
|
||||
)
|
||||
->helperText('Run this command on your server as root user')
|
||||
->disabled()
|
||||
->visible(fn ($get) => $this->provider === ServerProvider::CUSTOM),
|
||||
TextInput::make('name')
|
||||
->label('Name')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['name']),
|
||||
Grid::make()
|
||||
->schema([
|
||||
TextInput::make('ip')
|
||||
->label('SSH IP Address')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['ip']),
|
||||
TextInput::make('port')
|
||||
->label('SSH Port')
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['port']),
|
||||
])
|
||||
->visible(fn ($get) => $this->provider === ServerProvider::CUSTOM),
|
||||
Grid::make()
|
||||
->schema([
|
||||
Select::make('os')
|
||||
->label('OS')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['os'])
|
||||
->options(function () {
|
||||
return collect(config('core.operating_systems'))
|
||||
->mapWithKeys(fn ($value) => [$value => $value]);
|
||||
}),
|
||||
Select::make('type')
|
||||
->label('Server Type')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['type'])
|
||||
->options(function () {
|
||||
return collect(config('core.server_types'))
|
||||
->mapWithKeys(fn ($value) => [$value => $value]);
|
||||
})
|
||||
->default(ServerType::REGULAR),
|
||||
]),
|
||||
Grid::make(3)
|
||||
->schema([
|
||||
Select::make('webserver')
|
||||
->label('Webserver')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['webserver'] ?? [])
|
||||
->options(function () {
|
||||
return collect(config('core.webservers'))
|
||||
->mapWithKeys(fn ($value) => [$value => $value]);
|
||||
}),
|
||||
Select::make('database')
|
||||
->label('Database')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['database'] ?? [])
|
||||
->options(function () {
|
||||
return collect(config('core.databases_name'))
|
||||
->mapWithKeys(fn ($value, $key) => [
|
||||
$key => $value.' '.config('core.databases_version')[$key],
|
||||
]);
|
||||
}),
|
||||
Select::make('php')
|
||||
->label('PHP')
|
||||
->native(false)
|
||||
->selectablePlaceholder(false)
|
||||
->rules(fn ($get) => CreateServerAction::rules($this->all())['php'] ?? [])
|
||||
->options(function () {
|
||||
return collect(config('core.php_versions'))
|
||||
->mapWithKeys(fn ($value) => [$value => $value]);
|
||||
}),
|
||||
]),
|
||||
Actions::make([
|
||||
Action::make('create')
|
||||
->label('Create Server')
|
||||
->button()
|
||||
->action(fn () => $this->submit()),
|
||||
]),
|
||||
])
|
||||
->columns(1);
|
||||
}
|
||||
|
||||
public function submit(): void
|
||||
{
|
||||
$this->authorize('create', Server::class);
|
||||
|
||||
$this->validate();
|
||||
|
||||
try {
|
||||
$server = app(CreateServerAction::class)->create(auth()->user(), $this->all()['data']);
|
||||
|
||||
$this->redirect(Index::getUrl());
|
||||
} catch (Throwable $e) {
|
||||
Notification::make()
|
||||
->title($e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
}
|
57
app/Web/Pages/Servers/Widgets/Installing.php
Normal file
57
app/Web/Pages/Servers/Widgets/Installing.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Models\Server;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
use Filament\Infolists\Concerns\InteractsWithInfolists;
|
||||
use Filament\Infolists\Contracts\HasInfolists;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Filament\Widgets\Widget;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
class Installing extends Widget implements HasForms, HasInfolists
|
||||
{
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
||||
protected static string $view = 'web.components.infolist';
|
||||
|
||||
public Server $server;
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->schema([
|
||||
Section::make()
|
||||
->heading('Installing Server')
|
||||
->icon(function () {
|
||||
if ($this->server->isInstallationFailed()) {
|
||||
return 'heroicon-o-x-circle';
|
||||
}
|
||||
|
||||
return view('filament::components.loading-indicator')
|
||||
->with('attributes', new ComponentAttributeBag([
|
||||
'class' => 'mr-2 size-[24px] text-primary-400',
|
||||
]));
|
||||
})
|
||||
->iconColor($this->server->isInstallationFailed() ? 'danger' : 'primary')
|
||||
->schema([
|
||||
ViewEntry::make('progress')
|
||||
->hiddenLabel()
|
||||
->view('components.progress-bar')
|
||||
->viewData([
|
||||
'value' => $this->server->progress,
|
||||
]),
|
||||
]),
|
||||
])
|
||||
->record($this->server->refresh());
|
||||
}
|
||||
}
|
101
app/Web/Pages/Servers/Widgets/SelectServer.php
Normal file
101
app/Web/Pages/Servers/Widgets/SelectServer.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Web\Resources\Server\Pages\CreateServer;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Widgets\Widget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class SelectServer extends Widget implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static string $view = 'web.components.form';
|
||||
|
||||
public int|string|null $server = null;
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function mount(): void
|
||||
{
|
||||
$server = Server::query()
|
||||
->where('project_id', auth()->user()->current_project_id)
|
||||
->find(session()->get('current_server_id'));
|
||||
if ($server && auth()->user()->can('view', $server)) {
|
||||
$this->server = $server->id;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getFormSchema(): array
|
||||
{
|
||||
$options = $this->query()
|
||||
->limit(10)
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
|
||||
return [
|
||||
Select::make('server')
|
||||
->name('server')
|
||||
->model($this->server)
|
||||
->searchable()
|
||||
->options($options)
|
||||
->searchPrompt('Search...')
|
||||
->getSearchResultsUsing(function ($search) {
|
||||
return $this->query()
|
||||
->where('name', 'like', "%{$search}%")
|
||||
->limit(10)
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
})
|
||||
->extraAttributes(['class' => '-mx-2 pointer-choices'])
|
||||
->live()
|
||||
->hintIcon('heroicon-o-question-mark-circle')
|
||||
->hintIconTooltip('Filter resources by default based on a server')
|
||||
->suffixAction(
|
||||
Action::make('create')
|
||||
->icon('heroicon-o-plus')
|
||||
->tooltip('Create a new server')
|
||||
->url(CreateServer::getUrl())
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
private function query(): Builder
|
||||
{
|
||||
return Server::query()
|
||||
->where(function (Builder $query) {
|
||||
$query->where('project_id', auth()->user()->current_project_id);
|
||||
});
|
||||
}
|
||||
|
||||
public function updatedServer($value): void
|
||||
{
|
||||
if (! $value) {
|
||||
session()->forget('current_server_id');
|
||||
$this->redirect(url()->previous());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$server = Server::query()->find($value);
|
||||
if (! $server) {
|
||||
session()->forget('current_server_id');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->authorize('view', $server);
|
||||
session()->put('current_server_id', $value);
|
||||
|
||||
$this->redirect(url()->previous());
|
||||
}
|
||||
}
|
95
app/Web/Pages/Servers/Widgets/ServerDetails.php
Normal file
95
app/Web/Pages/Servers/Widgets/ServerDetails.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Actions\Server\Update;
|
||||
use App\Models\Server;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Concerns\InteractsWithInfolists;
|
||||
use Filament\Infolists\Contracts\HasInfolists;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Widgets\Widget;
|
||||
|
||||
class ServerDetails extends Widget implements HasForms, HasInfolists
|
||||
{
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
||||
protected static string $view = 'web.components.infolist';
|
||||
|
||||
public Server $server;
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->schema([
|
||||
Section::make()
|
||||
->heading('Server Details')
|
||||
->description('More details about your server')
|
||||
->columns(1)
|
||||
->schema([
|
||||
TextEntry::make('id')
|
||||
->label('ID')
|
||||
->inlineLabel()
|
||||
->hintIcon('heroicon-o-information-circle')
|
||||
->hintIconTooltip('Server unique identifier to use in the API'),
|
||||
TextEntry::make('created_at_by_timezone')
|
||||
->label('Created At')
|
||||
->inlineLabel(),
|
||||
TextEntry::make('last_updated_check')
|
||||
->label('Last Updated Check')
|
||||
->inlineLabel()
|
||||
->state(fn (Server $record) => $record->getDateTimeByTimezone($record->last_update_check) ?? '-')
|
||||
->suffixAction(
|
||||
Action::make('check-update')
|
||||
->icon('heroicon-o-arrow-path')
|
||||
->tooltip('Check Now')
|
||||
->action(fn (Server $record) => $record->checkForUpdates())
|
||||
),
|
||||
TextEntry::make('available_updates')
|
||||
->label('Available Updates')
|
||||
->inlineLabel()
|
||||
->suffixAction(
|
||||
Action::make('update-server')
|
||||
->icon('heroicon-o-check-circle')
|
||||
->tooltip('Update Now')
|
||||
->action(function (Server $record) {
|
||||
app(Update::class)->update($record);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
||||
Notification::make()
|
||||
->info()
|
||||
->title('Updating the server...')
|
||||
->send();
|
||||
})
|
||||
),
|
||||
TextEntry::make('provider')
|
||||
->label('Provider')
|
||||
->inlineLabel(),
|
||||
TextEntry::make('tags')
|
||||
->label('Tags')
|
||||
->inlineLabel()
|
||||
->state(fn (Server $record) => view('web.components.tags', ['tags' => $record->tags]))
|
||||
->suffixAction(
|
||||
Action::make('edit-tags')
|
||||
->icon('heroicon-o-pencil')
|
||||
->tooltip('Edit Tags')
|
||||
->action(fn (Server $record) => $this->dispatch('$editTags', $record))
|
||||
->tooltip('Edit Tags')
|
||||
),
|
||||
|
||||
]),
|
||||
])
|
||||
->record($this->server);
|
||||
}
|
||||
}
|
73
app/Web/Pages/Servers/Widgets/ServerSummary.php
Normal file
73
app/Web/Pages/Servers/Widgets/ServerSummary.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Web\Pages\Servers\View;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\Fieldset;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Concerns\InteractsWithInfolists;
|
||||
use Filament\Infolists\Contracts\HasInfolists;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Widgets\Widget;
|
||||
|
||||
class ServerSummary extends Widget implements HasForms, HasInfolists
|
||||
{
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
||||
protected static string $view = 'web.components.infolist';
|
||||
|
||||
public Server $server;
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->schema([
|
||||
Fieldset::make('info')
|
||||
->label('Server Summary')
|
||||
->schema([
|
||||
TextEntry::make('name')
|
||||
->label('Name')
|
||||
->url(fn (Server $record) => View::getUrl(parameters: ['server' => $record])),
|
||||
TextEntry::make('ip')
|
||||
->label('IP Address')
|
||||
->icon('heroicon-o-clipboard-document')
|
||||
->iconPosition(IconPosition::After)
|
||||
->copyable(),
|
||||
TextEntry::make('status')
|
||||
->label('Status')
|
||||
->badge()
|
||||
->color(static function ($state): string {
|
||||
return Server::$statusColors[$state];
|
||||
})
|
||||
->suffixAction(
|
||||
Action::make('check-status')
|
||||
->icon('heroicon-o-arrow-path')
|
||||
->tooltip('Check Connection')
|
||||
->action(function (Server $record) {
|
||||
$record = $record->checkConnection();
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
||||
Notification::make()
|
||||
->status(Server::$statusColors[$record->status])
|
||||
->title('Server is '.$record->status)
|
||||
->send();
|
||||
})
|
||||
),
|
||||
])
|
||||
->columns(3),
|
||||
])
|
||||
->record($this->server->refresh());
|
||||
}
|
||||
}
|
63
app/Web/Pages/Servers/Widgets/ServersList.php
Normal file
63
app/Web/Pages/Servers/Widgets/ServersList.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Web\Pages\Servers\View;
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Columns\ViewColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Widgets\TableWidget as Widget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ServersList extends Widget
|
||||
{
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Server::query()->where('project_id', auth()->user()->current_project_id);
|
||||
}
|
||||
|
||||
protected static ?string $heading = '';
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
TextColumn::make('id')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
ViewColumn::make('tags.name')
|
||||
->label('Tags')
|
||||
->view('web.components.tags')
|
||||
->extraCellAttributes(['class' => 'px-3'])
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('status')
|
||||
->label('Status')
|
||||
->badge()
|
||||
->color(fn (Server $server) => Server::$statusColors[$server->status])
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('created_at_by_timezone')
|
||||
->label('Created At')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTable(): Table
|
||||
{
|
||||
return $this->table
|
||||
->recordUrl(fn (Server $record) => View::getUrl(parameters: ['server' => $record]))
|
||||
->actions([
|
||||
Action::make('settings')
|
||||
->label('Settings')
|
||||
->icon('heroicon-o-cog-6-tooth')
|
||||
->authorize(fn ($record) => auth()->user()->can('update', $record))
|
||||
->url(fn (Server $record) => '/'),
|
||||
]);
|
||||
}
|
||||
}
|
82
app/Web/Pages/Servers/Widgets/UpdateServerInfo.php
Normal file
82
app/Web/Pages/Servers/Widgets/UpdateServerInfo.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Web\Pages\Servers\Widgets;
|
||||
|
||||
use App\Actions\Server\EditServer;
|
||||
use App\Models\Server;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Widgets\Widget;
|
||||
|
||||
class UpdateServerInfo extends Widget implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
||||
protected static string $view = 'web.components.form';
|
||||
|
||||
public Server $server;
|
||||
|
||||
public string $name;
|
||||
|
||||
public string $ip;
|
||||
|
||||
public string $port;
|
||||
|
||||
public function mount(Server $server): void
|
||||
{
|
||||
$this->server = $server;
|
||||
$this->name = $server->name;
|
||||
$this->ip = $server->ip;
|
||||
$this->port = $server->port;
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make()
|
||||
->heading('Update Server')
|
||||
->description('You can edit your server\'s information here')
|
||||
->columns(1)
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label('Name')
|
||||
->rules(EditServer::rules($this->server)['name']),
|
||||
TextInput::make('ip')
|
||||
->label('IP Address')
|
||||
->rules(EditServer::rules($this->server)['ip']),
|
||||
TextInput::make('port')
|
||||
->label('Port')
|
||||
->rules(EditServer::rules($this->server)['port']),
|
||||
])
|
||||
->footerActions([
|
||||
Actions\Action::make('submit')
|
||||
->label('Save')
|
||||
->action(fn () => $this->submit()),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function submit(): void
|
||||
{
|
||||
$this->authorize('update', $this->server);
|
||||
|
||||
$this->validate();
|
||||
|
||||
app(EditServer::class)->edit($this->server, $this->all());
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Server updated!')
|
||||
->send();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user