mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-07 17:02:34 +00:00
Add phpstan level 7(#544)
This commit is contained in:
@ -7,6 +7,7 @@
|
||||
use App\Enums\SiteType;
|
||||
use App\Models\Site;
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\SourceControls\Actions\Create;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
@ -41,6 +42,9 @@ public function getWidgets(): array
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
Action::make('read-the-docs')
|
||||
->label('Read the Docs')
|
||||
@ -51,17 +55,17 @@ protected function getHeaderActions(): array
|
||||
Action::make('create')
|
||||
->label('Create a Site')
|
||||
->icon('heroicon-o-plus')
|
||||
->authorize(fn () => auth()->user()?->can('create', [Site::class, $this->server]))
|
||||
->authorize(fn () => $user->can('create', [Site::class, $this->server]))
|
||||
->modalWidth(MaxWidth::FiveExtraLarge)
|
||||
->slideOver()
|
||||
->form([
|
||||
Select::make('type')
|
||||
->label('Site Type')
|
||||
->options(
|
||||
collect(config('core.site_types'))->mapWithKeys(fn ($type) => [$type => $type])
|
||||
collect((array) config('core.site_types'))->mapWithKeys(fn ($type) => [$type => $type])
|
||||
)
|
||||
->reactive()
|
||||
->afterStateUpdated(function (?string $state, Set $set) {
|
||||
->afterStateUpdated(function (?string $state, Set $set): void {
|
||||
if ($state === SiteType::LARAVEL) {
|
||||
$set('web_directory', 'public');
|
||||
} else {
|
||||
@ -78,12 +82,12 @@ protected function getHeaderActions(): array
|
||||
Select::make('php_version')
|
||||
->label('PHP Version')
|
||||
->options(collect($this->server->installedPHPVersions())->mapWithKeys(fn ($version) => [$version => $version]))
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['php_version']))
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['php_version']))
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['php_version']),
|
||||
TextInput::make('web_directory')
|
||||
->placeholder('For / leave empty')
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['web_directory'])
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['web_directory']))
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['web_directory']))
|
||||
->helperText(
|
||||
sprintf(
|
||||
'The relative path of your website from /home/%s/your-domain/',
|
||||
@ -94,7 +98,7 @@ protected function getHeaderActions(): array
|
||||
->label('Source Control')
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['source_control'])
|
||||
->options(
|
||||
SourceControl::getByProjectId(auth()->user()->current_project_id)
|
||||
SourceControl::getByProjectId($user->current_project_id)
|
||||
->pluck('profile', 'id')
|
||||
)
|
||||
->suffixAction(
|
||||
@ -105,24 +109,24 @@ protected function getHeaderActions(): array
|
||||
->icon('heroicon-o-wifi')
|
||||
->tooltip('Connect to a source control')
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->authorize(fn () => auth()->user()->can('create', SourceControl::class))
|
||||
->authorize(fn () => $user->can('create', SourceControl::class))
|
||||
->action(fn (array $data) => Create::action($data))
|
||||
)
|
||||
->placeholder('Select source control')
|
||||
->live()
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['source_control'])),
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['source_control'])),
|
||||
TextInput::make('repository')
|
||||
->placeholder('organization/repository')
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['repository'])
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['repository'])),
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['repository'])),
|
||||
TextInput::make('branch')
|
||||
->placeholder('main')
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['branch'])
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['branch'])),
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['branch'])),
|
||||
Checkbox::make('composer')
|
||||
->label('Run `composer install --no-dev`')
|
||||
->default(false)
|
||||
->visible(fn (Get $get) => isset(CreateSite::rules($this->server, $get())['composer'])),
|
||||
->visible(fn (Get $get): bool => isset(CreateSite::rules($this->server, $get())['composer'])),
|
||||
// PHPMyAdmin
|
||||
Select::make('version')
|
||||
->label('PHPMyAdmin Version')
|
||||
@ -130,7 +134,7 @@ protected function getHeaderActions(): array
|
||||
->options([
|
||||
'5.2.1' => '5.2.1',
|
||||
])
|
||||
->visible(fn (Get $get) => $get('type') === SiteType::PHPMYADMIN)
|
||||
->visible(fn (Get $get): bool => $get('type') === SiteType::PHPMYADMIN)
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['version']),
|
||||
// WordPress
|
||||
$this->wordpressFields(),
|
||||
@ -142,7 +146,7 @@ protected function getHeaderActions(): array
|
||||
collect(LoadBalancerMethod::all())
|
||||
->mapWithKeys(fn ($method) => [$method => $method])
|
||||
)
|
||||
->visible(fn (Get $get) => $get('type') === SiteType::LOAD_BALANCER)
|
||||
->visible(fn (Get $get): bool => $get('type') === SiteType::LOAD_BALANCER)
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['method'] ?? []),
|
||||
// User
|
||||
TextInput::make('user')
|
||||
@ -153,7 +157,7 @@ protected function getHeaderActions(): array
|
||||
)
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['user']),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
->action(function (array $data): void {
|
||||
$this->authorize('create', [Site::class, $this->server]);
|
||||
|
||||
$this->validate();
|
||||
@ -178,9 +182,12 @@ protected function getHeaderActions(): array
|
||||
|
||||
private function wordpressFields(): Component
|
||||
{
|
||||
/** @var User */
|
||||
$user = auth()->user();
|
||||
|
||||
return Grid::make()
|
||||
->columns(3)
|
||||
->visible(fn (Get $get) => $get('type') === SiteType::WORDPRESS)
|
||||
->visible(fn (Get $get): bool => $get('type') === SiteType::WORDPRESS)
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label('Site Title')
|
||||
@ -188,7 +195,7 @@ private function wordpressFields(): Component
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['title']),
|
||||
TextInput::make('email')
|
||||
->label('WP Admin Email')
|
||||
->default(auth()->user()?->email)
|
||||
->default($user->email)
|
||||
->rules(fn (Get $get) => CreateSite::rules($this->server, $get())['email']),
|
||||
TextInput::make('username')
|
||||
->label('WP Admin Username')
|
||||
|
@ -20,6 +20,7 @@ abstract class Page extends BasePage implements HasSecondSubNav
|
||||
|
||||
public function getSecondSubNavigation(): array
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
$items = [];
|
||||
|
||||
@ -99,7 +100,10 @@ protected static function getSiteFromRoute(): ?Site
|
||||
}
|
||||
|
||||
if ($site) {
|
||||
return Site::query()->find($site);
|
||||
/** @var Site $site */
|
||||
$site = Site::query()->findOrFail($site);
|
||||
|
||||
return $site;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -67,8 +67,8 @@ protected function getHeaderActions(): array
|
||||
->default(false),
|
||||
]),
|
||||
])
|
||||
->using(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->using(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(CreateQueue::class)->create($this->site, $data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -27,8 +27,14 @@ class QueuesList extends Widget
|
||||
{
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Queue>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Queue::query()->where('site_id', $this->site->id);
|
||||
@ -75,12 +81,15 @@ public function table(Table $table): Table
|
||||
|
||||
private function operationAction(string $type, string $icon): Action
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return Action::make($type)
|
||||
->authorize(fn (Queue $record) => auth()->user()->can('update', [$record, $this->site, $this->site->server]))
|
||||
->authorize(fn (Queue $record) => $user->can('update', [$record, $this->site, $this->site->server]))
|
||||
->label(ucfirst($type).' queue')
|
||||
->icon($icon)
|
||||
->action(function (Queue $record) use ($type) {
|
||||
run_action($this, function () use ($record, $type) {
|
||||
->action(function (Queue $record) use ($type): void {
|
||||
run_action($this, function () use ($record, $type): void {
|
||||
app(ManageQueue::class)->$type($record);
|
||||
$this->dispatch('$refresh');
|
||||
});
|
||||
@ -89,27 +98,31 @@ private function operationAction(string $type, string $icon): Action
|
||||
|
||||
private function logsAction(): Action
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return Action::make('logs')
|
||||
->icon('heroicon-o-eye')
|
||||
->authorize(fn (Queue $record) => auth()->user()->can('view', [$record, $this->site, $this->site->server]))
|
||||
->authorize(fn (Queue $record) => $user->can('view', [$record, $this->site, $this->site->server]))
|
||||
->modalHeading('View Log')
|
||||
->modalContent(function (Queue $record) {
|
||||
return view('components.console-view', [
|
||||
'slot' => app(GetQueueLogs::class)->getLogs($record),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]);
|
||||
})
|
||||
->modalContent(fn (Queue $record) => view('components.console-view', [
|
||||
'slot' => app(GetQueueLogs::class)->getLogs($record),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Close');
|
||||
}
|
||||
|
||||
private function editAction(): Action
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return EditAction::make('edit')
|
||||
->icon('heroicon-o-pencil-square')
|
||||
->authorize(fn (Queue $record) => auth()->user()->can('update', [$record, $this->site, $this->site->server]))
|
||||
->authorize(fn (Queue $record) => $user->can('update', [$record, $this->site, $this->site->server]))
|
||||
->modalWidth(MaxWidth::ExtraLarge)
|
||||
->fillForm(fn (Queue $record) => [
|
||||
->fillForm(fn (Queue $record): array => [
|
||||
'command' => $record->command,
|
||||
'user' => $record->user,
|
||||
'numprocs' => $record->numprocs,
|
||||
@ -138,8 +151,8 @@ private function editAction(): Action
|
||||
->default(false),
|
||||
]),
|
||||
])
|
||||
->using(function (Queue $record, array $data) {
|
||||
run_action($this, function () use ($record, $data) {
|
||||
->using(function (Queue $record, array $data): void {
|
||||
run_action($this, function () use ($record, $data): void {
|
||||
app(EditQueue::class)->edit($record, $data);
|
||||
$this->dispatch('$refresh');
|
||||
});
|
||||
@ -148,11 +161,14 @@ private function editAction(): Action
|
||||
|
||||
private function deleteAction(): Action
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return DeleteAction::make('delete')
|
||||
->icon('heroicon-o-trash')
|
||||
->authorize(fn (Queue $record) => auth()->user()->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (Queue $record) {
|
||||
run_action($this, function () use ($record) {
|
||||
->authorize(fn (Queue $record) => $user->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (Queue $record): void {
|
||||
run_action($this, function () use ($record): void {
|
||||
app(DeleteQueue::class)->delete($record);
|
||||
$this->dispatch('$refresh');
|
||||
});
|
||||
|
@ -47,11 +47,11 @@ protected function getHeaderActions(): array
|
||||
->openUrlInNewTab(),
|
||||
Action::make('force-ssl')
|
||||
->label('Force SSL')
|
||||
->tooltip(fn () => $this->site->force_ssl ? 'Disable force SSL' : 'Enable force SSL')
|
||||
->icon(fn () => $this->site->force_ssl ? 'icon-force-ssl-enabled' : 'icon-force-ssl-disabled')
|
||||
->tooltip(fn (): string => $this->site->force_ssl ? 'Disable force SSL' : 'Enable force SSL')
|
||||
->icon(fn (): string => $this->site->force_ssl ? 'icon-force-ssl-enabled' : 'icon-force-ssl-disabled')
|
||||
->requiresConfirmation()
|
||||
->modalSubmitActionLabel(fn () => $this->site->force_ssl ? 'Disable' : 'Enable')
|
||||
->action(function () {
|
||||
->modalSubmitActionLabel(fn (): string => $this->site->force_ssl ? 'Disable' : 'Enable')
|
||||
->action(function (): void {
|
||||
$this->site->update([
|
||||
'force_ssl' => ! $this->site->force_ssl,
|
||||
]);
|
||||
@ -72,34 +72,34 @@ protected function getHeaderActions(): array
|
||||
->message('Let\'s Encrypt has rate limits. Read more about them <a href="https://letsencrypt.org/docs/rate-limits/" target="_blank" class="underline">here</a>.'),
|
||||
Select::make('type')
|
||||
->options(
|
||||
collect(config('core.ssl_types'))->mapWithKeys(fn ($type) => [$type => $type])
|
||||
collect((array) config('core.ssl_types'))->mapWithKeys(fn ($type) => [$type => $type])
|
||||
)
|
||||
->rules(fn (Get $get) => CreateSSL::rules($get())['type'])
|
||||
->reactive(),
|
||||
TextInput::make('email')
|
||||
->rules(fn (Get $get) => CreateSSL::rules($get())['email'] ?? [])
|
||||
->visible(fn (Get $get) => $get('type') === SslType::LETSENCRYPT)
|
||||
->visible(fn (Get $get): bool => $get('type') === SslType::LETSENCRYPT)
|
||||
->helperText('Email address to provide to Certbot.'),
|
||||
Textarea::make('certificate')
|
||||
->rows(5)
|
||||
->rules(fn (Get $get) => CreateSSL::rules($get())['certificate'])
|
||||
->visible(fn (Get $get) => $get('type') === SslType::CUSTOM),
|
||||
->visible(fn (Get $get): bool => $get('type') === SslType::CUSTOM),
|
||||
Textarea::make('private')
|
||||
->label('Private Key')
|
||||
->rows(5)
|
||||
->rules(fn (Get $get) => CreateSSL::rules($get())['private'])
|
||||
->visible(fn (Get $get) => $get('type') === SslType::CUSTOM),
|
||||
->visible(fn (Get $get): bool => $get('type') === SslType::CUSTOM),
|
||||
DatePicker::make('expires_at')
|
||||
->format('Y-m-d')
|
||||
->rules(fn (Get $get) => CreateSSL::rules($get())['expires_at'])
|
||||
->visible(fn (Get $get) => $get('type') === SslType::CUSTOM),
|
||||
->visible(fn (Get $get): bool => $get('type') === SslType::CUSTOM),
|
||||
Checkbox::make('aliases')
|
||||
->label("Set SSL for site's aliases as well"),
|
||||
])
|
||||
->createAnother(false)
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->using(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->using(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(CreateSSL::class)->create($this->site, $data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
|
@ -20,8 +20,14 @@ class SslsList extends Widget
|
||||
{
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Ssl>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Ssl::query()->where('site_id', $this->site->id);
|
||||
@ -29,10 +35,12 @@ protected function getTableQuery(): Builder
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
auth()->user();
|
||||
|
||||
return [
|
||||
IconColumn::make('is_active')
|
||||
->color(fn (Ssl $record) => $record->is_active ? 'green' : 'gray')
|
||||
->icon(fn (Ssl $record) => $record->is_active ? 'heroicon-o-lock-closed' : 'heroicon-o-lock-open'),
|
||||
->color(fn (Ssl $record): string => $record->is_active ? 'green' : 'gray')
|
||||
->icon(fn (Ssl $record): string => $record->is_active ? 'heroicon-o-lock-closed' : 'heroicon-o-lock-open'),
|
||||
TextColumn::make('type')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
@ -40,7 +48,7 @@ protected function getTableColumns(): array
|
||||
->formatStateUsing(fn (Ssl $record) => $record->created_at_by_timezone)
|
||||
->sortable(),
|
||||
TextColumn::make('expires_at')
|
||||
->formatStateUsing(fn (Ssl $record) => $record->getDateTimeByTimezone($record->expires_at))
|
||||
->formatStateUsing(fn (Ssl $record): string => $record->getDateTimeByTimezone($record->expires_at))
|
||||
->sortable(),
|
||||
TextColumn::make('status')
|
||||
->label('Status')
|
||||
@ -53,6 +61,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
@ -60,15 +71,15 @@ public function table(Table $table): Table
|
||||
->actions([
|
||||
Action::make('activate-ssl')
|
||||
->hiddenLabel()
|
||||
->visible(fn (Ssl $record) => ! $record->is_active)
|
||||
->visible(fn (Ssl $record): bool => ! $record->is_active)
|
||||
->tooltip('Activate SSL')
|
||||
->icon('heroicon-o-lock-closed')
|
||||
->authorize(fn (Ssl $record) => auth()->user()->can('update', [$record->site, $this->site->server]))
|
||||
->authorize(fn (Ssl $record) => $user->can('update', [$record->site, $this->site->server]))
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Activate SSL')
|
||||
->modalSubmitActionLabel('Activate')
|
||||
->action(function (Ssl $record) {
|
||||
run_action($this, function () use ($record) {
|
||||
->action(function (Ssl $record): void {
|
||||
run_action($this, function () use ($record): void {
|
||||
app(ActivateSSL::class)->activate($record);
|
||||
|
||||
Notification::make()
|
||||
@ -81,23 +92,21 @@ public function table(Table $table): Table
|
||||
->hiddenLabel()
|
||||
->tooltip('Logs')
|
||||
->icon('heroicon-o-eye')
|
||||
->authorize(fn (Ssl $record) => auth()->user()->can('view', [$record, $this->site, $this->site->server]))
|
||||
->authorize(fn (Ssl $record) => $user->can('view', [$record, $this->site, $this->site->server]))
|
||||
->modalHeading('View Log')
|
||||
->modalContent(function (Ssl $record) {
|
||||
return view('components.console-view', [
|
||||
'slot' => $record->log?->getContent(),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]);
|
||||
})
|
||||
->modalContent(fn (Ssl $record) => view('components.console-view', [
|
||||
'slot' => $record->log?->getContent(),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Close'),
|
||||
DeleteAction::make('delete')
|
||||
->hiddenLabel()
|
||||
->tooltip('Delete')
|
||||
->icon('heroicon-o-trash')
|
||||
->authorize(fn (Ssl $record) => auth()->user()->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (Ssl $record) {
|
||||
run_action($this, function () use ($record) {
|
||||
->authorize(fn (Ssl $record) => $user->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (Ssl $record): void {
|
||||
run_action($this, function () use ($record): void {
|
||||
app(DeleteSSL::class)->delete($record);
|
||||
$this->dispatch('$refresh');
|
||||
});
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace App\Web\Pages\Servers\Sites;
|
||||
|
||||
use App\Actions\Site\DeleteSite;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Web\Fields\CodeEditorField;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\DeleteAction;
|
||||
@ -15,6 +14,9 @@ class Settings extends Page
|
||||
|
||||
protected static ?string $title = 'Settings';
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
public function mount(): void
|
||||
@ -44,8 +46,8 @@ private function deleteAction(): Action
|
||||
->record($this->site)
|
||||
->modalHeading('Delete Site')
|
||||
->modalDescription('Once your site is deleted, all of its resources and data will be permanently deleted and can\'t be restored')
|
||||
->using(function () {
|
||||
run_action($this, function () {
|
||||
->using(function (): void {
|
||||
run_action($this, function (): void {
|
||||
app(DeleteSite::class)->delete($this->site);
|
||||
|
||||
$this->redirect(Index::getUrl(['server' => $this->server]));
|
||||
@ -62,19 +64,12 @@ private function vhostAction(): Action
|
||||
->modalSubmitActionLabel('Save')
|
||||
->form([
|
||||
CodeEditorField::make('vhost')
|
||||
->formatStateUsing(function () {
|
||||
/** @var Webserver $handler */
|
||||
$handler = $this->server->webserver()->handler();
|
||||
|
||||
return $handler->getVhost($this->site);
|
||||
})
|
||||
->formatStateUsing(fn (): string => $this->site->webserver()->getVhost($this->site))
|
||||
->rules(['required']),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
/** @var Webserver $handler */
|
||||
$handler = $this->server->webserver()->handler();
|
||||
$handler->updateVHost($this->site, $data['vhost']);
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
$this->site->webserver()->updateVHost($this->site, $data['vhost']);
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('VHost updated!')
|
||||
|
@ -114,7 +114,7 @@ private function deployAction(): Action
|
||||
{
|
||||
return Action::make('deploy')
|
||||
->icon('heroicon-o-rocket-launch')
|
||||
->action(function () {
|
||||
->action(function (): void {
|
||||
if (! $this->site->deploymentScript?->content) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
@ -123,7 +123,7 @@ private function deployAction(): Action
|
||||
|
||||
return;
|
||||
}
|
||||
run_action($this, function () {
|
||||
run_action($this, function (): void {
|
||||
app(Deploy::class)->run($this->site);
|
||||
|
||||
Notification::make()
|
||||
@ -139,12 +139,12 @@ private function deployAction(): Action
|
||||
private function autoDeploymentAction(): Action
|
||||
{
|
||||
return Action::make('auto-deployment')
|
||||
->label(fn () => $this->site->isAutoDeployment() ? 'Disable Auto Deployment' : 'Enable Auto Deployment')
|
||||
->modalHeading(fn () => $this->site->isAutoDeployment() ? 'Disable Auto Deployment' : 'Enable Auto Deployment')
|
||||
->modalIconColor(fn () => $this->site->isAutoDeployment() ? 'red' : 'green')
|
||||
->label(fn (): string => $this->site->isAutoDeployment() ? 'Disable Auto Deployment' : 'Enable Auto Deployment')
|
||||
->modalHeading(fn (): string => $this->site->isAutoDeployment() ? 'Disable Auto Deployment' : 'Enable Auto Deployment')
|
||||
->modalIconColor(fn (): string => $this->site->isAutoDeployment() ? 'red' : 'green')
|
||||
->requiresConfirmation()
|
||||
->action(function () {
|
||||
run_action($this, function () {
|
||||
->action(function (): void {
|
||||
run_action($this, function (): void {
|
||||
$this->site->isAutoDeployment()
|
||||
? $this->site->disableAutoDeployment()
|
||||
: $this->site->enableAutoDeployment();
|
||||
@ -168,8 +168,8 @@ private function deploymentScriptAction(): Action
|
||||
->default($this->site->deploymentScript?->content)
|
||||
->rules(UpdateDeploymentScript::rules()['script']),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdateDeploymentScript::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
@ -188,15 +188,13 @@ private function dotEnvAction(): Action
|
||||
->modalHeading('Update .env file')
|
||||
->form([
|
||||
CodeEditorField::make('env')
|
||||
->formatStateUsing(function () {
|
||||
return $this->site->getEnv();
|
||||
})
|
||||
->formatStateUsing(fn (): string => $this->site->getEnv())
|
||||
->rules([
|
||||
'env' => 'required',
|
||||
]),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdateEnv::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
@ -219,8 +217,8 @@ private function branchAction(): Action
|
||||
->default($this->site->branch)
|
||||
->rules(UpdateBranch::rules()['branch']),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdateBranch::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
|
@ -25,18 +25,31 @@ class Commands extends Widget
|
||||
{
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Command>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Command::query()->where('site_id', $this->site->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<Command> $query
|
||||
* @return Builder<Command>
|
||||
*/
|
||||
protected function applySortingToTableQuery(Builder $query): Builder
|
||||
{
|
||||
return $query->latest('created_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
@ -56,14 +69,17 @@ protected function getTableColumns(): array
|
||||
|
||||
protected function getTableHeaderActions(): array
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
Action::make('new-command')
|
||||
->label('Create a Command')
|
||||
->modalDescription('The command will be executed inside the site\'s directory')
|
||||
->icon('heroicon-o-plus')
|
||||
->authorize(fn () => auth()->user()->can('create', [Command::class, $this->site, $this->site->server]))
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->authorize(fn () => $user->can('create', [Command::class, $this->site, $this->site->server]))
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(CreateCommand::class)->create($this->site, $data);
|
||||
|
||||
$this->dispatch('$refresh');
|
||||
@ -91,6 +107,9 @@ protected function getTableHeaderActions(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->query($this->getTableQuery())
|
||||
->headerActions($this->getTableHeaderActions())
|
||||
@ -118,10 +137,8 @@ public function table(Table $table): Table
|
||||
|
||||
return $form;
|
||||
})
|
||||
->authorize(fn (Command $record) => auth()->user()->can('update', [$record->site, $record->site->server]))
|
||||
->action(function (array $data, Command $record) {
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
->authorize(fn (Command $record) => $user->can('update', [$record->site, $record->site->server]))
|
||||
->action(function (array $data, Command $record) use ($user): void {
|
||||
app(ExecuteCommand::class)->execute($record, $user, $data);
|
||||
$this->dispatch('$refresh');
|
||||
}),
|
||||
@ -130,24 +147,20 @@ public function table(Table $table): Table
|
||||
->tooltip('Last Log')
|
||||
->icon('heroicon-o-eye')
|
||||
->modalHeading('View Last Execution Log')
|
||||
->modalContent(function (Command $record) {
|
||||
return view('components.console-view', [
|
||||
'slot' => $record->lastExecution?->serverLog?->getContent() ?? 'Not executed yet',
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]);
|
||||
})
|
||||
->modalContent(fn (Command $record) => view('components.console-view', [
|
||||
'slot' => $record->lastExecution?->serverLog?->getContent() ?? 'Not executed yet',
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Close'),
|
||||
EditAction::make('edit')
|
||||
->hiddenLabel()
|
||||
->tooltip('Edit')
|
||||
->modalHeading('Edit Command')
|
||||
->mutateRecordDataUsing(function (array $data, Command $record) {
|
||||
return [
|
||||
'name' => $record->name,
|
||||
'command' => $record->command,
|
||||
];
|
||||
})
|
||||
->mutateRecordDataUsing(fn (array $data, Command $record): array => [
|
||||
'name' => $record->name,
|
||||
'command' => $record->command,
|
||||
])
|
||||
->form([
|
||||
TextInput::make('name')
|
||||
->rules(EditCommand::rules()['name']),
|
||||
@ -156,8 +169,8 @@ public function table(Table $table): Table
|
||||
->helperText('You can use variables like ${VARIABLE_NAME} in the command. The variables will be asked when executing the command'),
|
||||
|
||||
])
|
||||
->authorize(fn (Command $record) => auth()->user()->can('update', [$record, $this->site, $this->site->server]))
|
||||
->using(function (array $data, Command $record) {
|
||||
->authorize(fn (Command $record) => $user->can('update', [$record, $this->site, $this->site->server]))
|
||||
->using(function (array $data, Command $record): void {
|
||||
app(EditCommand::class)->edit($record, $data);
|
||||
$this->dispatch('$refresh');
|
||||
})
|
||||
@ -167,8 +180,8 @@ public function table(Table $table): Table
|
||||
->hiddenLabel()
|
||||
->tooltip('Delete')
|
||||
->modalHeading('Delete Command')
|
||||
->authorize(fn (Command $record) => auth()->user()->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (array $data, Command $record) {
|
||||
->authorize(fn (Command $record) => $user->can('delete', [$record, $this->site, $this->site->server]))
|
||||
->using(function (array $data, Command $record): void {
|
||||
$record->delete();
|
||||
}),
|
||||
]);
|
||||
|
@ -15,13 +15,23 @@ class DeploymentsList extends Widget
|
||||
{
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
/**
|
||||
* @return Builder<Deployment>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Deployment::query()->where('site_id', $this->site->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<Deployment> $query
|
||||
* @return Builder<Deployment>
|
||||
*/
|
||||
protected function applySortingToTableQuery(Builder $query): Builder
|
||||
{
|
||||
return $query->latest('created_at');
|
||||
@ -53,6 +63,9 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->query($this->getTableQuery())
|
||||
->columns($this->getTableColumns())
|
||||
@ -62,14 +75,12 @@ public function table(Table $table): Table
|
||||
->hiddenLabel()
|
||||
->tooltip('View')
|
||||
->icon('heroicon-o-eye')
|
||||
->authorize(fn ($record) => auth()->user()->can('view', $record->log))
|
||||
->authorize(fn ($record) => $user->can('view', $record->log))
|
||||
->modalHeading('View Log')
|
||||
->modalContent(function (Deployment $record) {
|
||||
return view('components.console-view', [
|
||||
'slot' => $record->log?->getContent(),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]);
|
||||
})
|
||||
->modalContent(fn (Deployment $record) => view('components.console-view', [
|
||||
'slot' => $record->log?->getContent(),
|
||||
'attributes' => new ComponentAttributeBag,
|
||||
]))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('Close'),
|
||||
Action::make('download')
|
||||
@ -77,7 +88,7 @@ public function table(Table $table): Table
|
||||
->tooltip('Download')
|
||||
->color('gray')
|
||||
->icon('heroicon-o-archive-box-arrow-down')
|
||||
->authorize(fn ($record) => auth()->user()->can('view', $record->log))
|
||||
->authorize(fn ($record) => $user->can('view', $record->log))
|
||||
->action(fn (Deployment $record) => $record->log?->download()),
|
||||
]);
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ class Installing extends Widget implements HasForms, HasInfolists
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
|
@ -5,6 +5,7 @@
|
||||
use App\Actions\Site\UpdateLoadBalancer;
|
||||
use App\Enums\LoadBalancerMethod;
|
||||
use App\Models\LoadBalancerServer;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
@ -29,12 +30,15 @@ class LoadBalancerServers extends Widget implements HasForms
|
||||
|
||||
public string $method;
|
||||
|
||||
/**
|
||||
* @var array<int, mixed>
|
||||
*/
|
||||
public array $servers = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->setLoadBalancerServers();
|
||||
if (empty($this->servers)) {
|
||||
if ($this->servers === []) {
|
||||
$this->servers = [
|
||||
[
|
||||
'server' => null,
|
||||
@ -50,14 +54,12 @@ public function mount(): void
|
||||
#[On('load-balancer-updated')]
|
||||
public function setLoadBalancerServers(): void
|
||||
{
|
||||
$this->servers = $this->site->loadBalancerServers->map(function (LoadBalancerServer $server) {
|
||||
return [
|
||||
'server' => $server->ip,
|
||||
'port' => $server->port,
|
||||
'weight' => $server->weight,
|
||||
'backup' => $server->backup,
|
||||
];
|
||||
})->toArray();
|
||||
$this->servers = $this->site->loadBalancerServers->map(fn (LoadBalancerServer $server): array => [
|
||||
'server' => $server->ip,
|
||||
'port' => $server->port,
|
||||
'weight' => $server->weight,
|
||||
'backup' => $server->backup,
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
@ -84,14 +86,14 @@ public function form(Form $form): Form
|
||||
->searchable()
|
||||
->required()
|
||||
->rules(UpdateLoadBalancer::rules($this->site)['servers.*.server'])
|
||||
->options(function () {
|
||||
return $this->site->project->servers()
|
||||
->where('id', '!=', $this->site->server_id)
|
||||
->get()
|
||||
->mapWithKeys(function ($server) {
|
||||
return [$server->local_ip => $server->name.' ('.$server->local_ip.')'];
|
||||
});
|
||||
}),
|
||||
->options(fn () => $this->site->project->servers()
|
||||
->where('id', '!=', $this->site->server_id)
|
||||
->whereNotNull('local_ip')
|
||||
->get()
|
||||
->mapWithKeys(function ($server): array {
|
||||
/** @var Server $server */
|
||||
return $server->local_ip ? [$server->local_ip => $server->name.' ('.$server->local_ip.')'] : [];
|
||||
})),
|
||||
TextInput::make('port')
|
||||
->default(80)
|
||||
->required()
|
||||
@ -124,7 +126,7 @@ public function save(): void
|
||||
|
||||
$this->validate();
|
||||
|
||||
run_action($this, function () {
|
||||
run_action($this, function (): void {
|
||||
app(UpdateLoadBalancer::class)->update($this->site, [
|
||||
'method' => $this->method,
|
||||
'servers' => $this->servers,
|
||||
|
@ -7,6 +7,7 @@
|
||||
use App\Actions\Site\UpdateSourceControl;
|
||||
use App\Models\Site;
|
||||
use App\Models\SourceControl;
|
||||
use App\Models\User;
|
||||
use App\Web\Pages\Settings\SourceControls\Actions\Create;
|
||||
use App\Web\Pages\Settings\Tags\Actions\EditTags;
|
||||
use Filament\Forms\Components\Select;
|
||||
@ -28,6 +29,9 @@ class SiteDetails extends Widget implements HasForms, HasInfolists
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
@ -38,6 +42,9 @@ class SiteDetails extends Widget implements HasForms, HasInfolists
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $infolist
|
||||
->schema([
|
||||
Section::make()
|
||||
@ -59,15 +66,15 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->inlineLabel(),
|
||||
TextEntry::make('type')
|
||||
->extraAttributes(['class' => 'capitalize'])
|
||||
->icon(fn ($state) => 'icon-'.$state)
|
||||
->icon(fn ($state): string => 'icon-'.$state)
|
||||
->inlineLabel(),
|
||||
TextEntry::make('tags.*')
|
||||
->default('No tags')
|
||||
->formatStateUsing(fn ($state) => is_object($state) ? $state->name : $state)
|
||||
->formatStateUsing(fn ($state) => is_object($state) && isset($state->name) ? $state->name : $state)
|
||||
->inlineLabel()
|
||||
->badge()
|
||||
->color(fn ($state) => is_object($state) ? $state->color : 'gray')
|
||||
->icon(fn ($state) => is_object($state) ? 'heroicon-o-tag' : '')
|
||||
->color(fn ($state) => is_object($state) && isset($state->color) ? $state->color : 'gray')
|
||||
->icon(fn ($state): string => is_object($state) ? 'heroicon-o-tag' : '')
|
||||
->suffixAction(
|
||||
EditTags::infolist($this->site)
|
||||
),
|
||||
@ -93,8 +100,8 @@ public function infolist(Infolist $infolist): Infolist
|
||||
),
|
||||
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdatePHPVersion::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
@ -108,7 +115,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->inlineLabel()
|
||||
->badge()
|
||||
->default('No aliases')
|
||||
->color(fn ($state) => $state == 'No aliases' ? 'gray' : 'primary')
|
||||
->color(fn ($state): string => $state == 'No aliases' ? 'gray' : 'primary')
|
||||
->suffixAction(
|
||||
Action::make('edit_aliases')
|
||||
->icon('heroicon-o-pencil-square')
|
||||
@ -124,8 +131,8 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->nestedRecursiveRules(UpdateAliases::rules()['aliases.*']),
|
||||
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdateAliases::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
@ -152,7 +159,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->label('Source Control')
|
||||
->rules(UpdateSourceControl::rules()['source_control'])
|
||||
->options(
|
||||
SourceControl::getByProjectId(auth()->user()->current_project_id)
|
||||
SourceControl::getByProjectId($user->current_project_id)
|
||||
->pluck('profile', 'id')
|
||||
)
|
||||
->default($this->site->source_control_id)
|
||||
@ -164,13 +171,13 @@ public function infolist(Infolist $infolist): Infolist
|
||||
->icon('heroicon-o-wifi')
|
||||
->tooltip('Connect to a source control')
|
||||
->modalWidth(MaxWidth::Large)
|
||||
->authorize(fn () => auth()->user()->can('create', SourceControl::class))
|
||||
->authorize(fn () => $user->can('create', SourceControl::class))
|
||||
->action(fn (array $data) => Create::action($data))
|
||||
)
|
||||
->placeholder('Select source control'),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
run_action($this, function () use ($data) {
|
||||
->action(function (array $data): void {
|
||||
run_action($this, function () use ($data): void {
|
||||
app(UpdateSourceControl::class)->update($this->site, $data);
|
||||
|
||||
Notification::make()
|
||||
|
@ -18,6 +18,9 @@ class SiteSummary extends Widget implements HasForms, HasInfolists
|
||||
use InteractsWithForms;
|
||||
use InteractsWithInfolists;
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $listeners = ['$refresh'];
|
||||
|
||||
protected static bool $isLazy = false;
|
||||
@ -44,9 +47,7 @@ public function infolist(Infolist $infolist): Infolist
|
||||
TextEntry::make('status')
|
||||
->label('Status')
|
||||
->badge()
|
||||
->color(static function ($state): string {
|
||||
return Site::$statusColors[$state];
|
||||
}),
|
||||
->color(static fn ($state): string => Site::$statusColors[$state]),
|
||||
])
|
||||
->columns(3),
|
||||
])
|
||||
|
@ -17,6 +17,9 @@ class SitesList extends Widget
|
||||
{
|
||||
public Server $server;
|
||||
|
||||
/**
|
||||
* @return Builder<Site>
|
||||
*/
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Site::query()->where('server_id', $this->server->id);
|
||||
@ -26,7 +29,7 @@ protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
IconColumn::make('type')
|
||||
->icon(fn (Site $record) => 'icon-'.$record->type)
|
||||
->icon(fn (Site $record): string => 'icon-'.$record->type)
|
||||
->tooltip(fn (Site $record) => $record->type)
|
||||
->width(24),
|
||||
TextColumn::make('domain')
|
||||
@ -54,17 +57,20 @@ protected function getTableColumns(): array
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth()->user();
|
||||
|
||||
return $table
|
||||
->heading(null)
|
||||
->query($this->getTableQuery())
|
||||
->columns($this->getTableColumns())
|
||||
->recordUrl(fn (Site $record) => View::getUrl(parameters: ['server' => $this->server, 'site' => $record]))
|
||||
->recordUrl(fn (Site $record): string => View::getUrl(parameters: ['server' => $this->server, 'site' => $record]))
|
||||
->actions([
|
||||
Action::make('settings')
|
||||
->label('Settings')
|
||||
->icon('heroicon-o-cog-6-tooth')
|
||||
->authorize(fn (Site $record) => auth()->user()->can('update', [$record, $this->server]))
|
||||
->url(fn (Site $record) => Settings::getUrl(parameters: ['server' => $this->server, 'site' => $record])),
|
||||
->authorize(fn (Site $record) => $user->can('update', [$record, $this->server]))
|
||||
->url(fn (Site $record): string => Settings::getUrl(parameters: ['server' => $this->server, 'site' => $record])),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user