diff --git a/app/Filament/Resources/ApiKeyResource/Pages/CreateApiKey.php b/app/Filament/Resources/ApiKeyResource/Pages/CreateApiKey.php index ffcac3fed45..a4bf3d016f8 100644 --- a/app/Filament/Resources/ApiKeyResource/Pages/CreateApiKey.php +++ b/app/Filament/Resources/ApiKeyResource/Pages/CreateApiKey.php @@ -42,7 +42,8 @@ public function form(Form $form): Form ]) ->schema( collect(ApiKey::RESOURCES)->map(fn ($resource) => ToggleButtons::make("r_$resource") - ->label(str($resource)->replace('_', ' ')->title())->inline() + ->label(str($resource)->replace('_', ' ')->title()) + ->inline() ->options([ 0 => 'None', 1 => 'Read', diff --git a/app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php b/app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php index 4dfcdd955b3..2c5a87a7d25 100644 --- a/app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php +++ b/app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php @@ -25,6 +25,8 @@ public function form(Form $form): Form TextInput::make('database')->columnSpanFull(), TextInput::make('username'), TextInput::make('password') + ->password() + ->revealable() ->hintAction( Action::make('rotate') ->icon('tabler-refresh') diff --git a/app/Filament/Resources/EggResource/Pages/CreateEgg.php b/app/Filament/Resources/EggResource/Pages/CreateEgg.php index ea21a02755d..5bcaed5a793 100644 --- a/app/Filament/Resources/EggResource/Pages/CreateEgg.php +++ b/app/Filament/Resources/EggResource/Pages/CreateEgg.php @@ -134,15 +134,21 @@ public function form(Form $form): Form ->maxLength(255) ->label('Stop Command') ->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'), - Textarea::make('config_startup')->rows(10)->json() + Textarea::make('config_startup') + ->rows(10) + ->json() ->label('Start Configuration') ->default('{}') ->helperText('List of values the daemon should be looking for when booting a server to determine completion.'), - Textarea::make('config_files')->rows(10)->json() + Textarea::make('config_files') + ->rows(10) + ->json() ->label('Configuration Files') ->default('{}') ->helperText('This should be a JSON representation of configuration files to modify and what parts should be changed.'), - Textarea::make('config_logs')->rows(10)->json() + Textarea::make('config_logs') + ->rows(10) + ->json() ->label('Log Configuration') ->default('{}') ->helperText('This should be a JSON representation of where log files are stored, and whether or not the daemon should be creating custom logs.'), @@ -156,8 +162,10 @@ public function form(Form $form): Form ->grid() ->relationship('variables') ->name('name') - ->reorderable()->orderColumn() - ->collapsible()->collapsed() + ->reorderable() + ->orderColumn() + ->collapsible() + ->collapsed() ->columnSpan(2) ->defaultItems(0) ->itemLabel(fn (array $state) => $state['name']) @@ -255,7 +263,9 @@ public function form(Form $form): Form ->view('filament.plugins.monaco-editor'), ]), - ])->columnSpanFull()->persistTabInQueryString(), + ]) + ->columnSpanFull() + ->persistTabInQueryString(), ]); } diff --git a/app/Filament/Resources/EggResource/Pages/EditEgg.php b/app/Filament/Resources/EggResource/Pages/EditEgg.php index 54e13fa0c05..21089421779 100644 --- a/app/Filament/Resources/EggResource/Pages/EditEgg.php +++ b/app/Filament/Resources/EggResource/Pages/EditEgg.php @@ -160,13 +160,19 @@ public function form(Form $form): Form ->maxLength(255) ->label('Stop Command') ->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'), - Textarea::make('config_startup')->rows(10)->json() + Textarea::make('config_startup') + ->rows(10) + ->json() ->label('Start Configuration') ->helperText('List of values the daemon should be looking for when booting a server to determine completion.'), - Textarea::make('config_files')->rows(10)->json() + Textarea::make('config_files') + ->rows(10) + ->json() ->label('Configuration Files') ->helperText('This should be a JSON representation of configuration files to modify and what parts should be changed.'), - Textarea::make('config_logs')->rows(10)->json() + Textarea::make('config_logs') + ->rows(10) + ->json() ->label('Log Configuration') ->helperText('This should be a JSON representation of where log files are stored, and whether or not the daemon should be creating custom logs.'), ]), @@ -180,7 +186,8 @@ public function form(Form $form): Form ->relationship('variables') ->name('name') ->reorderable() - ->collapsible()->collapsed() + ->collapsible() + ->collapsed() ->orderColumn() ->addActionLabel('New Variable') ->itemLabel(fn (array $state) => $state['name']) @@ -273,7 +280,9 @@ public function form(Form $form): Form ->language('shell') ->view('filament.plugins.monaco-editor'), ]), - ])->columnSpanFull()->persistTabInQueryString(), + ]) + ->columnSpanFull() + ->persistTabInQueryString(), ]); } diff --git a/app/Filament/Resources/MountResource/Pages/CreateMount.php b/app/Filament/Resources/MountResource/Pages/CreateMount.php index c736bf75875..bc423053f40 100644 --- a/app/Filament/Resources/MountResource/Pages/CreateMount.php +++ b/app/Filament/Resources/MountResource/Pages/CreateMount.php @@ -78,10 +78,12 @@ public function form(Form $form): Form ->helperText('A longer description for this mount.') ->columnSpanFull(), Hidden::make('user_mountable')->default(1), - ])->columnSpan(1)->columns([ - 'default' => 1, - 'lg' => 2, - ]), + ]) + ->columnSpan(1) + ->columns([ + 'default' => 1, + 'lg' => 2, + ]), Group::make()->schema([ Section::make()->schema([ Select::make('eggs')->multiple() diff --git a/app/Filament/Resources/MountResource/Pages/EditMount.php b/app/Filament/Resources/MountResource/Pages/EditMount.php index 71c6febb5cf..32e598a3289 100644 --- a/app/Filament/Resources/MountResource/Pages/EditMount.php +++ b/app/Filament/Resources/MountResource/Pages/EditMount.php @@ -73,10 +73,12 @@ public function form(Form $form): Form Textarea::make('description') ->helperText('A longer description for this mount.') ->columnSpanFull(), - ])->columnSpan(1)->columns([ - 'default' => 1, - 'lg' => 2, - ]), + ]) + ->columnSpan(1) + ->columns([ + 'default' => 1, + 'lg' => 2, + ]), Group::make()->schema([ Section::make()->schema([ Select::make('eggs')->multiple() diff --git a/app/Filament/Resources/NodeResource/Pages/CreateNode.php b/app/Filament/Resources/NodeResource/Pages/CreateNode.php index 90c4bb535ee..3fe97845f94 100644 --- a/app/Filament/Resources/NodeResource/Pages/CreateNode.php +++ b/app/Filament/Resources/NodeResource/Pages/CreateNode.php @@ -188,7 +188,8 @@ public function form(Forms\Form $form): Forms\Form ]) ->schema([ ToggleButtons::make('maintenance_mode') - ->label('Maintenance Mode')->inline() + ->label('Maintenance Mode') + ->inline() ->columnSpan(1) ->default(false) ->hinticon('tabler-question-mark') @@ -204,7 +205,8 @@ public function form(Forms\Form $form): Forms\Form ToggleButtons::make('public') ->default(true) ->columnSpan(1) - ->label('Use Node for deployment?')->inline() + ->label('Use Node for deployment?') + ->inline() ->options([ true => 'Yes', false => 'No', @@ -220,7 +222,8 @@ public function form(Forms\Form $form): Forms\Form ->label('Upload Limit') ->helperText('Enter the maximum size of files that can be uploaded through the web-based file manager.') ->columnSpan(1) - ->numeric()->required() + ->numeric() + ->required() ->default(256) ->minValue(1) ->maxValue(1024) @@ -242,7 +245,9 @@ public function form(Forms\Form $form): Forms\Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_mem') - ->label('Memory')->inlineLabel()->inline() + ->label('Memory') + ->inlineLabel() + ->inline() ->afterStateUpdated(function (Set $set) { $set('memory', 0); $set('memory_overallocate', 0); @@ -261,7 +266,8 @@ public function form(Forms\Form $form): Forms\Form TextInput::make('memory') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_mem')) - ->label('Memory Limit')->inlineLabel() + ->label('Memory Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->columnSpan(2) ->numeric() @@ -270,7 +276,8 @@ public function form(Forms\Form $form): Forms\Form ->required(), TextInput::make('memory_overallocate') ->dehydratedWhenHidden() - ->label('Overallocate')->inlineLabel() + ->label('Overallocate') + ->inlineLabel() ->hidden(fn (Get $get) => $get('unlimited_mem')) ->hintIcon('tabler-question-mark') ->hintIconTooltip('The % allowable to go over the set limit.') @@ -287,7 +294,9 @@ public function form(Forms\Form $form): Forms\Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_disk') - ->label('Disk')->inlineLabel()->inline() + ->label('Disk') + ->inlineLabel() + ->inline() ->live() ->afterStateUpdated(function (Set $set) { $set('disk', 0); @@ -306,7 +315,8 @@ public function form(Forms\Form $form): Forms\Form TextInput::make('disk') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Disk Limit')->inlineLabel() + ->label('Disk Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->columnSpan(2) ->numeric() @@ -316,7 +326,8 @@ public function form(Forms\Form $form): Forms\Form TextInput::make('disk_overallocate') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Overallocate')->inlineLabel() + ->label('Overallocate') + ->inlineLabel() ->hintIcon('tabler-question-mark') ->hintIconTooltip('The % allowable to go over the set limit.') ->columnSpan(2) @@ -332,7 +343,9 @@ public function form(Forms\Form $form): Forms\Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_cpu') - ->label('CPU')->inlineLabel()->inline() + ->label('CPU') + ->inlineLabel() + ->inline() ->live() ->afterStateUpdated(function (Set $set) { $set('cpu', 0); @@ -351,7 +364,8 @@ public function form(Forms\Form $form): Forms\Form TextInput::make('cpu') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('CPU Limit')->inlineLabel() + ->label('CPU Limit') + ->inlineLabel() ->suffix('%') ->columnSpan(2) ->numeric() @@ -361,7 +375,8 @@ public function form(Forms\Form $form): Forms\Form TextInput::make('cpu_overallocate') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('Overallocate')->inlineLabel() + ->label('Overallocate') + ->inlineLabel() ->hintIcon('tabler-question-mark') ->hintIconTooltip('The % allowable to go over the set limit.') ->columnSpan(2) diff --git a/app/Filament/Resources/NodeResource/Pages/EditNode.php b/app/Filament/Resources/NodeResource/Pages/EditNode.php index 3b2c8567750..3890ff36530 100644 --- a/app/Filament/Resources/NodeResource/Pages/EditNode.php +++ b/app/Filament/Resources/NodeResource/Pages/EditNode.php @@ -207,7 +207,8 @@ public function form(Forms\Form $form): Forms\Form 'http' => 'tabler-lock-open-off', 'https' => 'tabler-lock', ]) - ->default(fn () => request()->isSecure() ? 'https' : 'http'), ]), + ->default(fn () => request()->isSecure() ? 'https' : 'http'), + ]), Tab::make('Advanced Settings') ->columns(['default' => 1, 'sm' => 1, 'md' => 4, 'lg' => 6]) ->icon('tabler-server-cog') @@ -249,7 +250,8 @@ public function form(Forms\Form $form): Forms\Form ->label('Upload Limit') ->hintIcon('tabler-question-mark') ->hintIconTooltip('Enter the maximum size of files that can be uploaded through the web-based file manager.') - ->numeric()->required() + ->numeric() + ->required() ->minValue(1) ->maxValue(1024) ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'), @@ -282,7 +284,8 @@ public function form(Forms\Form $form): Forms\Form 'md' => 1, 'lg' => 3, ]) - ->label('Use Node for deployment?')->inline() + ->label('Use Node for deployment?') + ->inline() ->options([ true => 'Yes', false => 'No', @@ -298,7 +301,8 @@ public function form(Forms\Form $form): Forms\Form 'md' => 1, 'lg' => 3, ]) - ->label('Maintenance Mode')->inline() + ->label('Maintenance Mode') + ->inline() ->hinticon('tabler-question-mark') ->hintIconTooltip("If the node is marked 'Under Maintenance' users won't be able to access servers that are on this node.") ->options([ @@ -314,7 +318,9 @@ public function form(Forms\Form $form): Forms\Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_mem') - ->label('Memory')->inlineLabel()->inline() + ->label('Memory') + ->inlineLabel() + ->inline() ->afterStateUpdated(function (Set $set) { $set('memory', 0); $set('memory_overallocate', 0); @@ -322,46 +328,48 @@ public function form(Forms\Form $form): Forms\Form ->formatStateUsing(fn (Get $get) => $get('memory') == 0) ->live() ->options([ - true => 'Unlimited', - false => 'Limited', - ]) + true => 'Unlimited', + false => 'Limited', + ]) ->colors([ - true => 'primary', - false => 'warning', - ]) + true => 'primary', + false => 'warning', + ]) ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]), + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]), TextInput::make('memory') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_mem')) - ->label('Memory Limit')->inlineLabel() + ->label('Memory Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->required() ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]) + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]) ->numeric() ->minValue(0), TextInput::make('memory_overallocate') ->dehydratedWhenHidden() - ->label('Overallocate')->inlineLabel() + ->label('Overallocate') + ->inlineLabel() ->required() ->hidden(fn (Get $get) => $get('unlimited_mem')) ->hintIcon('tabler-question-mark') ->hintIconTooltip('The % allowable to go over the set limit.') ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]) + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]) ->numeric() ->minValue(-1) ->maxValue(100) @@ -370,102 +378,110 @@ public function form(Forms\Form $form): Forms\Form Grid::make() ->columns(['default' => 1, 'sm' => 1, 'md' => 3, 'lg' => 6]) ->schema([ - ToggleButtons::make('unlimited_disk') - ->label('Disk')->inlineLabel()->inline() - ->live() - ->afterStateUpdated(function (Set $set) { - $set('disk', 0); - $set('disk_overallocate', 0); - }) - ->formatStateUsing(fn (Get $get) => $get('disk') == 0) - ->options([ - true => 'Unlimited', - false => 'Limited', - ]) - ->colors([ - true => 'primary', - false => 'warning', - ]) - ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]), - TextInput::make('disk') - ->dehydratedWhenHidden() - ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Disk Limit')->inlineLabel() - ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') - ->required() - ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]) - ->numeric() - ->minValue(0), - TextInput::make('disk_overallocate') - ->dehydratedWhenHidden() - ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Overallocate')->inlineLabel() - ->hintIcon('tabler-question-mark') - ->hintIconTooltip('The % allowable to go over the set limit.') - ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 2, - ]) - ->required() - ->numeric() - ->minValue(-1) - ->maxValue(100) - ->suffix('%'), - ]), + ToggleButtons::make('unlimited_disk') + ->label('Disk') + ->inlineLabel() + ->inline() + ->live() + ->afterStateUpdated(function (Set $set) { + $set('disk', 0); + $set('disk_overallocate', 0); + }) + ->formatStateUsing(fn (Get $get) => $get('disk') == 0) + ->options([ + true => 'Unlimited', + false => 'Limited', + ]) + ->colors([ + true => 'primary', + false => 'warning', + ]) + ->columnSpan([ + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]), + TextInput::make('disk') + ->dehydratedWhenHidden() + ->hidden(fn (Get $get) => $get('unlimited_disk')) + ->label('Disk Limit') + ->inlineLabel() + ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') + ->required() + ->columnSpan([ + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]) + ->numeric() + ->minValue(0), + TextInput::make('disk_overallocate') + ->dehydratedWhenHidden() + ->hidden(fn (Get $get) => $get('unlimited_disk')) + ->label('Overallocate') + ->inlineLabel() + ->hintIcon('tabler-question-mark') + ->hintIconTooltip('The % allowable to go over the set limit.') + ->columnSpan([ + 'default' => 1, + 'sm' => 1, + 'md' => 1, + 'lg' => 2, + ]) + ->required() + ->numeric() + ->minValue(-1) + ->maxValue(100) + ->suffix('%'), + ]), Grid::make() ->columns(6) ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_cpu') - ->label('CPU')->inlineLabel()->inline() - ->live() - ->afterStateUpdated(function (Set $set) { - $set('cpu', 0); - $set('cpu_overallocate', 0); - }) - ->formatStateUsing(fn (Get $get) => $get('cpu') == 0) - ->options([ - true => 'Unlimited', - false => 'Limited', - ]) - ->colors([ - true => 'primary', - false => 'warning', - ]) - ->columnSpan(2), + ->label('CPU') + ->inlineLabel() + ->inline() + ->live() + ->afterStateUpdated(function (Set $set) { + $set('cpu', 0); + $set('cpu_overallocate', 0); + }) + ->formatStateUsing(fn (Get $get) => $get('cpu') == 0) + ->options([ + true => 'Unlimited', + false => 'Limited', + ]) + ->colors([ + true => 'primary', + false => 'warning', + ]) + ->columnSpan(2), TextInput::make('cpu') - ->dehydratedWhenHidden() - ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('CPU Limit')->inlineLabel() - ->suffix('%') - ->required() - ->columnSpan(2) - ->numeric() - ->minValue(0), + ->dehydratedWhenHidden() + ->hidden(fn (Get $get) => $get('unlimited_cpu')) + ->label('CPU Limit') + ->inlineLabel() + ->suffix('%') + ->required() + ->columnSpan(2) + ->numeric() + ->minValue(0), TextInput::make('cpu_overallocate') - ->dehydratedWhenHidden() - ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('Overallocate')->inlineLabel() - ->hintIcon('tabler-question-mark') - ->hintIconTooltip('The % allowable to go over the set limit.') - ->columnSpan(2) - ->required() - ->numeric() - ->minValue(-1) - ->maxValue(100) - ->suffix('%'), + ->dehydratedWhenHidden() + ->hidden(fn (Get $get) => $get('unlimited_cpu')) + ->label('Overallocate') + ->inlineLabel() + ->hintIcon('tabler-question-mark') + ->hintIconTooltip('The % allowable to go over the set limit.') + ->columnSpan(2) + ->required() + ->numeric() + ->minValue(-1) + ->maxValue(100) + ->suffix('%'), ]), ]), Tab::make('Configuration File') @@ -486,55 +502,61 @@ public function form(Forms\Form $form): Forms\Form ->columns() ->schema([ FormActions::make([ - FormActions\Action::make('autoDeploy') - ->label('Auto Deploy Command') - ->color('primary') - ->modalHeading('Auto Deploy Command') - ->icon('tabler-rocket') - ->modalSubmitAction(false) - ->modalCancelAction(false) - ->modalFooterActionsAlignment(Alignment::Center) - ->form([ - ToggleButtons::make('docker') - ->label('Type') - ->live() - ->helperText('Choose between Standalone and Docker install.') - ->inline() - ->default(false) - ->afterStateUpdated(fn (bool $state, NodeAutoDeployService $service, Node $node, Set $set) => $set('generatedToken', $service->handle(request(), $node, $state))) - ->options([ - false => 'Standalone', - true => 'Docker', - ]) - ->colors([ - false => 'primary', - true => 'success', - ]) - ->columnSpan(1), - Textarea::make('generatedToken') - ->label('To auto-configure your node run the following command:') - ->readOnly() - ->autosize() - ->hintAction(fn (string $state) => CopyAction::make()->copyable($state)) - ->formatStateUsing(fn (NodeAutoDeployService $service, Node $node, Set $set, Get $get) => $set('generatedToken', $service->handle(request(), $node, $get('docker')))), - ]) - ->mountUsing(function (Forms\Form $form) { - Notification::make()->success()->title('Autodeploy Generated')->send(); - $form->fill(); - }), + FormActions\Action::make('autoDeploy') + ->label('Auto Deploy Command') + ->color('primary') + ->modalHeading('Auto Deploy Command') + ->icon('tabler-rocket') + ->modalSubmitAction(false) + ->modalCancelAction(false) + ->modalFooterActionsAlignment(Alignment::Center) + ->form([ + ToggleButtons::make('docker') + ->label('Type') + ->live() + ->helperText('Choose between Standalone and Docker install.') + ->inline() + ->default(false) + ->afterStateUpdated(fn (bool $state, NodeAutoDeployService $service, Node $node, Set $set) => $set('generatedToken', $service->handle(request(), $node, $state))) + ->options([ + false => 'Standalone', + true => 'Docker', + ]) + ->colors([ + false => 'primary', + true => 'success', + ]) + ->columnSpan(1), + Textarea::make('generatedToken') + ->label('To auto-configure your node run the following command:') + ->readOnly() + ->autosize() + ->hintAction(fn (string $state) => CopyAction::make()->copyable($state)) + ->formatStateUsing(fn (NodeAutoDeployService $service, Node $node, Set $set, Get $get) => $set('generatedToken', $service->handle(request(), $node, $get('docker')))), + ]) + ->mountUsing(function (Forms\Form $form) { + Notification::make() + ->success() + ->title('Autodeploy Generated') + ->send(); + $form->fill(); + }), ])->fullWidth(), FormActions::make([ FormActions\Action::make('resetKey') - ->label('Reset Daemon Token') - ->color('danger') - ->requiresConfirmation() - ->modalHeading('Reset Daemon Token?') - ->modalDescription('Resetting the daemon token will void any request coming from the old token. This token is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this token regularly for security.') - ->action(function (NodeUpdateService $nodeUpdateService, Node $node) { - $nodeUpdateService->handle($node, [], true); - Notification::make()->success()->title('Daemon Key Reset')->send(); - $this->fillForm(); - }), + ->label('Reset Daemon Token') + ->color('danger') + ->requiresConfirmation() + ->modalHeading('Reset Daemon Token?') + ->modalDescription('Resetting the daemon token will void any request coming from the old token. This token is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this token regularly for security.') + ->action(function (NodeUpdateService $nodeUpdateService, Node $node) { + $nodeUpdateService->handle($node, [], true); + Notification::make() + ->success() + ->title('Daemon Key Reset') + ->send(); + $this->fillForm(); + }), ])->fullWidth(), ]), ]), diff --git a/app/Filament/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Resources/ServerResource/Pages/CreateServer.php index 621aac85984..eef8ac8b825 100644 --- a/app/Filament/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Resources/ServerResource/Pages/CreateServer.php @@ -116,7 +116,8 @@ public function form(Form $form): Form TextInput::make('password') ->hintIcon('tabler-question-mark') ->hintIconTooltip('Providing a user password is optional. New user email will prompt users to create a password the first time they login.') - ->password(), + ->password() + ->revealable(), ]) ->createOptionUsing(function ($data) { resolve(UserCreationService::class)->handle($data); @@ -520,7 +521,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_mem') - ->label('Memory')->inlineLabel()->inline() + ->label('Memory') + ->inlineLabel() + ->inline() ->default(true) ->afterStateUpdated(fn (Set $set) => $set('memory', 0)) ->live() @@ -537,7 +540,8 @@ public function form(Form $form): Form TextInput::make('memory') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_mem')) - ->label('Memory Limit')->inlineLabel() + ->label('Memory Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->default(0) ->required() @@ -551,7 +555,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_disk') - ->label('Disk Space')->inlineLabel()->inline() + ->label('Disk Space') + ->inlineLabel() + ->inline() ->default(true) ->live() ->afterStateUpdated(fn (Set $set) => $set('disk', 0)) @@ -568,7 +574,8 @@ public function form(Form $form): Form TextInput::make('disk') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Disk Space Limit')->inlineLabel() + ->label('Disk Space Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->default(0) ->required() @@ -582,7 +589,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_cpu') - ->label('CPU')->inlineLabel()->inline() + ->label('CPU') + ->inlineLabel() + ->inline() ->default(true) ->afterStateUpdated(fn (Set $set) => $set('cpu', 0)) ->live() @@ -599,7 +608,8 @@ public function form(Form $form): Form TextInput::make('cpu') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('CPU Limit')->inlineLabel() + ->label('CPU Limit') + ->inlineLabel() ->suffix('%') ->default(0) ->required() @@ -668,7 +678,8 @@ public function form(Form $form): Form ->schema([ ToggleButtons::make('oom_killer') ->label('OOM Killer') - ->inlineLabel()->inline() + ->inlineLabel() + ->inline() ->default(false) ->columnSpan(2) ->options([ diff --git a/app/Filament/Resources/ServerResource/Pages/EditServer.php b/app/Filament/Resources/ServerResource/Pages/EditServer.php index 0fdb603fa76..48c3bc1fef9 100644 --- a/app/Filament/Resources/ServerResource/Pages/EditServer.php +++ b/app/Filament/Resources/ServerResource/Pages/EditServer.php @@ -179,7 +179,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_mem') - ->label('Memory')->inlineLabel()->inline() + ->label('Memory') + ->inlineLabel() + ->inline() ->afterStateUpdated(fn (Set $set) => $set('memory', 0)) ->formatStateUsing(fn (Get $get) => $get('memory') == 0) ->live() @@ -196,7 +198,8 @@ public function form(Form $form): Form TextInput::make('memory') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_mem')) - ->label('Memory Limit')->inlineLabel() + ->label('Memory Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->required() ->columnSpan(2) @@ -209,7 +212,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_disk') - ->label('Disk Space')->inlineLabel()->inline() + ->label('Disk Space') + ->inlineLabel() + ->inline() ->live() ->afterStateUpdated(fn (Set $set) => $set('disk', 0)) ->formatStateUsing(fn (Get $get) => $get('disk') == 0) @@ -226,7 +231,8 @@ public function form(Form $form): Form TextInput::make('disk') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_disk')) - ->label('Disk Space Limit')->inlineLabel() + ->label('Disk Space Limit') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->required() ->columnSpan(2) @@ -239,7 +245,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('unlimited_cpu') - ->label('CPU')->inlineLabel()->inline() + ->label('CPU') + ->inlineLabel() + ->inline() ->afterStateUpdated(fn (Set $set) => $set('cpu', 0)) ->formatStateUsing(fn (Get $get) => $get('cpu') == 0) ->live() @@ -256,7 +264,8 @@ public function form(Form $form): Form TextInput::make('cpu') ->dehydratedWhenHidden() ->hidden(fn (Get $get) => $get('unlimited_cpu')) - ->label('CPU Limit')->inlineLabel() + ->label('CPU Limit') + ->inlineLabel() ->suffix('%') ->required() ->columnSpan(2) @@ -270,7 +279,9 @@ public function form(Form $form): Form ->schema([ ToggleButtons::make('swap_support') ->live() - ->label('Enable Swap Memory')->inlineLabel()->inline() + ->label('Enable Swap Memory') + ->inlineLabel() + ->inline() ->columnSpan(2) ->afterStateUpdated(function ($state, Set $set) { $value = match ($state) { @@ -307,7 +318,8 @@ public function form(Form $form): Form 'disabled', 'unlimited', true => true, default => false, }) - ->label('Swap Memory')->inlineLabel() + ->label('Swap Memory') + ->inlineLabel() ->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB') ->minValue(-1) ->columnSpan(2) @@ -324,7 +336,9 @@ public function form(Form $form): Form ->columnSpanFull() ->schema([ ToggleButtons::make('oom_killer') - ->label('OOM Killer')->inlineLabel()->inline() + ->label('OOM Killer') + ->inlineLabel() + ->inline() ->columnSpan(2) ->options([ false => 'Disabled', @@ -439,7 +453,8 @@ public function form(Form $form): Form ->required(), ToggleButtons::make('skip_scripts') - ->label('Run Egg Install Script?')->inline() + ->label('Run Egg Install Script?') + ->inline() ->columnSpan([ 'default' => 6, 'sm' => 1, @@ -508,7 +523,9 @@ public function form(Form $form): Form return $data; }) - ->reorderable(false)->addable(false)->deletable(false) + ->reorderable(false) + ->addable(false) + ->deletable(false) ->schema(function () { $text = TextInput::make('variable_value') @@ -584,6 +601,8 @@ public function form(Form $form): Form ->formatStateUsing(fn ($record) => $record->username) ->columnSpan(2), TextInput::make('password') + ->password() + ->revealable() ->disabled() ->hintAction( Action::make('rotate') @@ -650,7 +669,10 @@ public function form(Form $form): Form ->hidden(fn (Server $server) => $server->isSuspended()) ->action(function (SuspensionService $suspensionService, Server $server) { $suspensionService->toggle($server, 'suspend'); - Notification::make()->success()->title('Server Suspended!')->send(); + Notification::make() + ->success() + ->title('Server Suspended!') + ->send(); $this->refreshFormData(['status', 'docker']); }), @@ -660,7 +682,10 @@ public function form(Form $form): Form ->hidden(fn (Server $server) => !$server->isSuspended()) ->action(function (SuspensionService $suspensionService, Server $server) { $suspensionService->toggle($server, 'unsuspend'); - Notification::make()->success()->title('Server Unsuspended!')->send(); + Notification::make() + ->success() + ->title('Server Unsuspended!') + ->send(); $this->refreshFormData(['status', 'docker']); }), diff --git a/app/Filament/Resources/ServerResource/Pages/ListServers.php b/app/Filament/Resources/ServerResource/Pages/ListServers.php index 326499898a8..76862737801 100644 --- a/app/Filament/Resources/ServerResource/Pages/ListServers.php +++ b/app/Filament/Resources/ServerResource/Pages/ListServers.php @@ -24,9 +24,12 @@ public function table(Table $table): Table ->searchable(false) ->defaultGroup('node.name') ->groups([ - Group::make('node.name')->getDescriptionFromRecordUsing(fn (Server $server): string => str($server->node->description)->limit(150)), - Group::make('user.username')->getDescriptionFromRecordUsing(fn (Server $server): string => $server->user->email), - Group::make('egg.name')->getDescriptionFromRecordUsing(fn (Server $server): string => str($server->egg->description)->limit(150)), + Group::make('node.name') + ->getDescriptionFromRecordUsing(fn (Server $server): string => str($server->node->description)->limit(150)), + Group::make('user.username') + ->getDescriptionFromRecordUsing(fn (Server $server): string => $server->user->email), + Group::make('egg.name') + ->getDescriptionFromRecordUsing(fn (Server $server): string => str($server->egg->description)->limit(150)), ]) ->columns([ TextColumn::make('condition') diff --git a/app/Filament/Resources/UserResource/Pages/EditProfile.php b/app/Filament/Resources/UserResource/Pages/EditProfile.php index f5c5f5828df..b213446972b 100644 --- a/app/Filament/Resources/UserResource/Pages/EditProfile.php +++ b/app/Filament/Resources/UserResource/Pages/EditProfile.php @@ -188,63 +188,72 @@ protected function getForms(): array ->requiredWith('2facode') ->currentPassword() ->password() + ->revealable() ->helperText('Enter your current password to verify.'), ]; }), Tab::make('API Keys') ->icon('tabler-key') ->schema([ - Grid::make('asdf')->columns(5)->schema([ - Section::make('Create API Key')->columnSpan(3)->schema([ - TextInput::make('description') - ->live(), - TagsInput::make('allowed_ips') - ->live() - ->splitKeys([',', ' ', 'Tab']) - ->placeholder('Example: 127.0.0.1 or 192.168.1.1') - ->label('Whitelisted IP\'s') - ->helperText('Press enter to add a new IP address or leave blank to allow any IP address') - ->columnSpanFull(), - ])->headerActions([ - Action::make('Create') - ->disabled(fn (Get $get) => $get('description') === null) - ->successRedirectUrl(route('filament.admin.auth.profile', ['tab' => '-api-keys-tab'])) - ->action(function (Get $get, Action $action, User $user) { - $token = $user->createToken( - $get('description'), - $get('allowed_ips'), - ); - Activity::event('user:api-key.create') - ->subject($token->accessToken) - ->property('identifier', $token->accessToken->identifier) - ->log(); - $action->success(); - }), - ]), - Section::make('Keys')->columnSpan(2)->schema([ - Repeater::make('keys') - ->label('') - ->relationship('apiKeys') - ->addable(false) - ->itemLabel(fn ($state) => $state['identifier']) - ->deleteAction(function (Action $action) { - $action->requiresConfirmation()->action(function (array $arguments, Repeater $component) { - $items = $component->getState(); - $key = $items[$arguments['item']]; - ApiKey::find($key['id'] ?? null)?->delete(); + Grid::make() + ->columns(5) + ->schema([ + Section::make('Create API Key') + ->columnSpan(3) + ->schema([ + TextInput::make('description') + ->live(), + TagsInput::make('allowed_ips') + ->live() + ->splitKeys([',', ' ', 'Tab']) + ->placeholder('Example: 127.0.0.1 or 192.168.1.1') + ->label('Whitelisted IP\'s') + ->helperText('Press enter to add a new IP address or leave blank to allow any IP address') + ->columnSpanFull(), + ])->headerActions([ + Action::make('Create') + ->disabled(fn (Get $get) => $get('description') === null) + ->successRedirectUrl(route('filament.admin.auth.profile', ['tab' => '-api-keys-tab'])) + ->action(function (Get $get, Action $action, User $user) { + $token = $user->createToken( + $get('description'), + $get('allowed_ips'), + ); + Activity::event('user:api-key.create') + ->subject($token->accessToken) + ->property('identifier', $token->accessToken->identifier) + ->log(); + $action->success(); + }), + ]), + Section::make('Keys') + ->columnSpan(2) + ->schema([ + Repeater::make('keys') + ->label('') + ->relationship('apiKeys') + ->addable(false) + ->itemLabel(fn ($state) => $state['identifier']) + ->deleteAction(function (Action $action) { + $action + ->requiresConfirmation() + ->action(function (array $arguments, Repeater $component) { + $items = $component->getState(); + $key = $items[$arguments['item']]; + ApiKey::find($key['id'] ?? null)?->delete(); - unset($items[$arguments['item']]); + unset($items[$arguments['item']]); - $component->state($items); + $component->state($items); - $component->callAfterStateUpdated(); - }); - }) - ->schema(fn () => [ - Placeholder::make('adf')->label(fn (ApiKey $key) => $key->memo), + $component->callAfterStateUpdated(); + }); + }) + ->schema(fn () => [ + Placeholder::make('adf')->label(fn (ApiKey $key) => $key->memo), + ]), ]), ]), - ]), ]), Tab::make('SSH Keys') ->icon('tabler-lock-code') @@ -261,7 +270,9 @@ protected function getForms(): array $query->orderBy('timestamp', 'desc'); }) ->schema([ - Placeholder::make('activity!')->label('')->content(fn (ActivityLog $log) => new HtmlString($log->htmlable())), + Placeholder::make('activity!') + ->label('') + ->content(fn (ActivityLog $log) => new HtmlString($log->htmlable())), ]), ]), ]), diff --git a/app/Filament/Resources/UserResource/Pages/EditUser.php b/app/Filament/Resources/UserResource/Pages/EditUser.php index 777f20d730f..09e8a4737f5 100644 --- a/app/Filament/Resources/UserResource/Pages/EditUser.php +++ b/app/Filament/Resources/UserResource/Pages/EditUser.php @@ -23,13 +23,19 @@ public function form(Form $form): Form return $form ->schema([ Section::make()->schema([ - TextInput::make('username')->required()->maxLength(255), - TextInput::make('email')->email()->required()->maxLength(255), + TextInput::make('username') + ->required() + ->maxLength(255), + TextInput::make('email') + ->email() + ->required() + ->maxLength(255), TextInput::make('password') ->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) ->dehydrated(fn (?string $state): bool => filled($state)) ->required(fn (string $operation): bool => $operation === 'create') - ->password(), + ->password() + ->revealable(), Select::make('language') ->required() ->hidden() diff --git a/app/Filament/Resources/UserResource/Pages/ListUsers.php b/app/Filament/Resources/UserResource/Pages/ListUsers.php index 2f6bdbac465..2ce3384e5dc 100644 --- a/app/Filament/Resources/UserResource/Pages/ListUsers.php +++ b/app/Filament/Resources/UserResource/Pages/ListUsers.php @@ -50,7 +50,8 @@ public function table(Table $table): Table ->label('2FA') ->visibleFrom('lg') ->icon(fn (User $user) => $user->use_totp ? 'tabler-lock' : 'tabler-lock-open-off') - ->boolean()->sortable(), + ->boolean() + ->sortable(), TextColumn::make('roles_count') ->counts('roles') ->icon('tabler-users-group') @@ -99,7 +100,8 @@ protected function getHeaderActions(): array TextInput::make('password') ->hintIcon('tabler-question-mark') ->hintIconTooltip('Providing a user password is optional. New user email will prompt users to create a password the first time they login.') - ->password(), + ->password() + ->revealable(), CheckboxList::make('roles') ->disableOptionWhen(fn (string $value): bool => $value == Role::getRootAdmin()->id) ->relationship('roles', 'name')