Reduce Reuse (#443)

* Reduce Reuse

Reduce the repetitiveness of \Form\Component\Blah along with all the others...

* PHPStan Fix
This commit is contained in:
Charles 2024-06-29 17:38:18 -04:00 committed by GitHub
parent 75d35e6ee8
commit 82c0568129
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 427 additions and 350 deletions

View File

@ -4,9 +4,13 @@ namespace App\Filament\Resources\ApiKeyResource\Pages;
use App\Filament\Resources\ApiKeyResource;
use App\Models\ApiKey;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Form;
use Filament\Resources\Pages\CreateRecord;
use Filament\Forms;
class CreateApiKey extends CreateRecord
{
@ -18,26 +22,26 @@ class CreateApiKey extends CreateRecord
{
return $form
->schema([
Forms\Components\Hidden::make('identifier')->default(ApiKey::generateTokenIdentifier(ApiKey::TYPE_APPLICATION)),
Forms\Components\Hidden::make('token')->default(str_random(ApiKey::KEY_LENGTH)),
Hidden::make('identifier')->default(ApiKey::generateTokenIdentifier(ApiKey::TYPE_APPLICATION)),
Hidden::make('token')->default(str_random(ApiKey::KEY_LENGTH)),
Forms\Components\Hidden::make('user_id')
Hidden::make('user_id')
->default(auth()->user()->id)
->required(),
Forms\Components\Hidden::make('key_type')
Hidden::make('key_type')
->inlineLabel()
->default(ApiKey::TYPE_APPLICATION)
->required(),
Forms\Components\Fieldset::make('Permissions')
Fieldset::make('Permissions')
->columns([
'default' => 1,
'sm' => 1,
'md' => 2,
])
->schema(
collect(ApiKey::RESOURCES)->map(fn ($resource) => Forms\Components\ToggleButtons::make("r_$resource")
collect(ApiKey::RESOURCES)->map(fn ($resource) => ToggleButtons::make("r_$resource")
->label(str($resource)->replace('_', ' ')->title())->inline()
->options([
0 => 'None',
@ -67,13 +71,13 @@ class CreateApiKey extends CreateRecord
)->all(),
),
Forms\Components\TagsInput::make('allowed_ips')
TagsInput::make('allowed_ips')
->placeholder('Example: 127.0.0.1 or 192.168.1.1')
->label('Whitelisted IPv4 Addresses')
->helperText('Press enter to add a new IP address or leave blank to allow any IP address')
->columnSpanFull(),
Forms\Components\Textarea::make('memo')
Textarea::make('memo')
->required()
->label('Description')
->helperText('

View File

@ -6,8 +6,9 @@ use App\Filament\Resources\ApiKeyResource;
use App\Models\ApiKey;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables;
class ListApiKeys extends ListRecords
{
@ -19,37 +20,37 @@ class ListApiKeys extends ListRecords
->searchable(false)
->modifyQueryUsing(fn ($query) => $query->where('key_type', ApiKey::TYPE_APPLICATION))
->columns([
Tables\Columns\TextColumn::make('key')
TextColumn::make('key')
->copyable()
->icon('tabler-clipboard-text')
->state(fn (ApiKey $key) => $key->identifier . $key->token),
Tables\Columns\TextColumn::make('memo')
TextColumn::make('memo')
->label('Description')
->wrap()
->limit(50),
Tables\Columns\TextColumn::make('identifier')
TextColumn::make('identifier')
->hidden()
->searchable(),
Tables\Columns\TextColumn::make('last_used_at')
TextColumn::make('last_used_at')
->label('Last Used')
->placeholder('Not Used')
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
TextColumn::make('created_at')
->label('Created')
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('user.username')
TextColumn::make('user.username')
->label('Created By')
->url(fn (ApiKey $apiKey): string => route('filament.admin.resources.users.edit', ['record' => $apiKey->user])),
])
->actions([
Tables\Actions\DeleteAction::make(),
DeleteAction::make(),
]);
}

View File

@ -4,6 +4,8 @@ namespace App\Filament\Resources\DatabaseHostResource\Pages;
use App\Filament\Resources\DatabaseHostResource;
use App\Services\Databases\Hosts\HostCreationService;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Pages\CreateRecord;
use Filament\Forms;
use Filament\Forms\Components\Section;
@ -34,14 +36,14 @@ class CreateDatabaseHost extends CreateRecord
'lg' => 4,
])
->schema([
Forms\Components\TextInput::make('host')
TextInput::make('host')
->columnSpan(2)
->helperText('The IP address or Domain name that should be used when attempting to connect to this MySQL host from this Panel to create new databases.')
->required()
->live(onBlur: true)
->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state))
->maxLength(255),
Forms\Components\TextInput::make('port')
TextInput::make('port')
->columnSpan(1)
->helperText('The port that MySQL is running on for this host.')
->required()
@ -49,26 +51,26 @@ class CreateDatabaseHost extends CreateRecord
->default(3306)
->minValue(0)
->maxValue(65535),
Forms\Components\TextInput::make('max_databases')
TextInput::make('max_databases')
->label('Max databases')
->helpertext('Blank is unlimited.')
->numeric(),
Forms\Components\TextInput::make('name')
TextInput::make('name')
->label('Display Name')
->helperText('A short identifier used to distinguish this location from others. Must be between 1 and 60 characters, for example, us.nyc.lvl3.')
->required()
->maxLength(60),
Forms\Components\TextInput::make('username')
TextInput::make('username')
->helperText('The username of an account that has enough permissions to create new users and databases on the system.')
->required()
->maxLength(255),
Forms\Components\TextInput::make('password')
TextInput::make('password')
->helperText('The password for the database user.')
->password()
->revealable()
->maxLength(255)
->required(),
Forms\Components\Select::make('node_id')
Select::make('node_id')
->searchable()
->preload()
->helperText('This setting only defaults to this database host when adding a database to a server on the selected node.')

View File

@ -3,9 +3,12 @@
namespace App\Filament\Resources\DatabaseHostResource\Pages;
use App\Filament\Resources\DatabaseHostResource;
use App\Filament\Resources\DatabaseHostResource\RelationManagers\DatabasesRelationManager;
use App\Models\DatabaseHost;
use App\Services\Databases\Hosts\HostUpdateService;
use Filament\Actions;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Pages\EditRecord;
use Filament\Forms;
use Filament\Forms\Components\Section;
@ -30,40 +33,40 @@ class EditDatabaseHost extends EditRecord
'lg' => 4,
])
->schema([
Forms\Components\TextInput::make('host')
TextInput::make('host')
->columnSpan(2)
->helperText('The IP address or Domain name that should be used when attempting to connect to this MySQL host from this Panel to create new databases.')
->required()
->live(onBlur: true)
->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state))
->maxLength(255),
Forms\Components\TextInput::make('port')
TextInput::make('port')
->columnSpan(1)
->helperText('The port that MySQL is running on for this host.')
->required()
->numeric()
->minValue(0)
->maxValue(65535),
Forms\Components\TextInput::make('max_databases')
TextInput::make('max_databases')
->label('Max databases')
->helpertext('Blank is unlimited.')
->numeric(),
Forms\Components\TextInput::make('name')
TextInput::make('name')
->label('Display Name')
->helperText('A short identifier used to distinguish this location from others. Must be between 1 and 60 characters, for example, us.nyc.lvl3.')
->required()
->maxLength(60),
Forms\Components\TextInput::make('username')
TextInput::make('username')
->helperText('The username of an account that has enough permissions to create new users and databases on the system.')
->required()
->maxLength(255),
Forms\Components\TextInput::make('password')
TextInput::make('password')
->helperText('The password for the database user.')
->password()
->revealable()
->maxLength(255)
->required(),
Forms\Components\Select::make('node_id')
Select::make('node_id')
->searchable()
->preload()
->helperText('This setting only defaults to this database host when adding a database to a server on the selected node.')
@ -91,7 +94,7 @@ class EditDatabaseHost extends EditRecord
public function getRelationManagers(): array
{
return [
DatabaseHostResource\RelationManagers\DatabasesRelationManager::class,
DatabasesRelationManager::class,
];
}

View File

@ -5,7 +5,10 @@ namespace App\Filament\Resources\DatabaseHostResource\Pages;
use App\Filament\Resources\DatabaseHostResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class ListDatabaseHosts extends ListRecords
@ -19,30 +22,27 @@ class ListDatabaseHosts extends ListRecords
return $table
->searchable(false)
->columns([
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->searchable(),
Tables\Columns\TextColumn::make('host')
TextColumn::make('host')
->searchable(),
Tables\Columns\TextColumn::make('port')
TextColumn::make('port')
->sortable(),
Tables\Columns\TextColumn::make('username')
TextColumn::make('username')
->searchable(),
Tables\Columns\TextColumn::make('max_databases')
TextColumn::make('max_databases')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('node.name')
TextColumn::make('node.name')
->numeric()
->sortable(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}

View File

@ -4,11 +4,14 @@ namespace App\Filament\Resources\DatabaseHostResource\RelationManagers;
use App\Models\Database;
use App\Services\Databases\DatabasePasswordService;
use Filament\Forms;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class DatabasesRelationManager extends RelationManager
@ -19,9 +22,9 @@ class DatabasesRelationManager extends RelationManager
{
return $form
->schema([
Forms\Components\TextInput::make('database')->columnSpanFull(),
Forms\Components\TextInput::make('username'),
Forms\Components\TextInput::make('password')
TextInput::make('database')->columnSpanFull(),
TextInput::make('username'),
TextInput::make('password')
->hintAction(
Action::make('rotate')
->icon('tabler-refresh')
@ -29,12 +32,12 @@ class DatabasesRelationManager extends RelationManager
->action(fn (DatabasePasswordService $service, Database $database, $set, $get) => $this->rotatePassword($service, $database, $set, $get))
)
->formatStateUsing(fn (Database $database) => $database->password),
Forms\Components\TextInput::make('remote')->label('Connections From'),
Forms\Components\TextInput::make('max_connections'),
Forms\Components\TextInput::make('JDBC')
TextInput::make('remote')->label('Connections From'),
TextInput::make('max_connections'),
TextInput::make('JDBC')
->label('JDBC Connection String')
->columnSpanFull()
->formatStateUsing(fn (Forms\Get $get, Database $database) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($database->password) . '@' . $database->host->host . ':' . $database->host->port . '/' . $get('database')),
->formatStateUsing(fn (Get $get, Database $database) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($database->password) . '@' . $database->host->host . ':' . $database->host->port . '/' . $get('database')),
]);
}
public function table(Table $table): Table
@ -42,18 +45,18 @@ class DatabasesRelationManager extends RelationManager
return $table
->recordTitleAttribute('servers')
->columns([
Tables\Columns\TextColumn::make('database')->icon('tabler-database'),
Tables\Columns\TextColumn::make('username')->icon('tabler-user'),
Tables\Columns\TextColumn::make('remote'),
Tables\Columns\TextColumn::make('server.name')
TextColumn::make('database')->icon('tabler-database'),
TextColumn::make('username')->icon('tabler-user'),
TextColumn::make('remote'),
TextColumn::make('server.name')
->icon('tabler-brand-docker')
->url(fn (Database $database) => route('filament.admin.resources.servers.edit', ['record' => $database->server_id])),
Tables\Columns\TextColumn::make('max_connections'),
Tables\Columns\TextColumn::make('created_at')->dateTime(),
TextColumn::make('max_connections'),
TextColumn::make('created_at')->dateTime(),
])
->actions([
Tables\Actions\DeleteAction::make(),
Tables\Actions\ViewAction::make()->color('primary'),
DeleteAction::make(),
ViewAction::make()->color('primary'),
]);
}

View File

@ -3,9 +3,10 @@
namespace App\Filament\Resources\DatabaseResource\Pages;
use App\Filament\Resources\DatabaseResource;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Pages\CreateRecord;
use Filament\Forms;
class CreateDatabase extends CreateRecord
{
@ -15,29 +16,29 @@ class CreateDatabase extends CreateRecord
{
return $form
->schema([
Forms\Components\Select::make('server_id')
Select::make('server_id')
->relationship('server', 'name')
->searchable()
->preload()
->required(),
Forms\Components\TextInput::make('database_host_id')
TextInput::make('database_host_id')
->required()
->numeric(),
Forms\Components\TextInput::make('database')
TextInput::make('database')
->required()
->maxLength(255),
Forms\Components\TextInput::make('remote')
TextInput::make('remote')
->required()
->maxLength(255)
->default('%'),
Forms\Components\TextInput::make('username')
TextInput::make('username')
->required()
->maxLength(255),
Forms\Components\TextInput::make('password')
TextInput::make('password')
->password()
->revealable()
->required(),
Forms\Components\TextInput::make('max_connections')
TextInput::make('max_connections')
->numeric()
->minValue(0)
->default(0),

View File

@ -4,9 +4,10 @@ namespace App\Filament\Resources\DatabaseResource\Pages;
use App\Filament\Resources\DatabaseResource;
use Filament\Actions;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Pages\EditRecord;
use Filament\Forms;
class EditDatabase extends EditRecord
{
@ -16,29 +17,29 @@ class EditDatabase extends EditRecord
{
return $form
->schema([
Forms\Components\Select::make('server_id')
Select::make('server_id')
->relationship('server', 'name')
->searchable()
->preload()
->required(),
Forms\Components\TextInput::make('database_host_id')
TextInput::make('database_host_id')
->required()
->numeric(),
Forms\Components\TextInput::make('database')
TextInput::make('database')
->required()
->maxLength(255),
Forms\Components\TextInput::make('remote')
TextInput::make('remote')
->required()
->maxLength(255)
->default('%'),
Forms\Components\TextInput::make('username')
TextInput::make('username')
->required()
->maxLength(255),
Forms\Components\TextInput::make('password')
TextInput::make('password')
->password()
->revealable()
->required(),
Forms\Components\TextInput::make('max_connections')
TextInput::make('max_connections')
->numeric()
->minValue(0)
->default(0),

View File

@ -4,9 +4,12 @@ namespace App\Filament\Resources\DatabaseResource\Pages;
use App\Filament\Resources\DatabaseResource;
use Filament\Actions;
use Filament\Tables\Actions\EditAction;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables;
class ListDatabases extends ListRecords
{
@ -16,39 +19,36 @@ class ListDatabases extends ListRecords
{
return $table
->columns([
Tables\Columns\TextColumn::make('server.name')
TextColumn::make('server.name')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('database_host_id')
TextColumn::make('database_host_id')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('database')
TextColumn::make('database')
->searchable(),
Tables\Columns\TextColumn::make('username')
TextColumn::make('username')
->searchable(),
Tables\Columns\TextColumn::make('remote')
TextColumn::make('remote')
->searchable(),
Tables\Columns\TextColumn::make('max_connections')
TextColumn::make('max_connections')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}

View File

@ -3,6 +3,18 @@
namespace App\Filament\Resources\EggResource\Pages;
use App\Filament\Resources\EggResource;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Resources\Pages\CreateRecord;
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
use Filament\Forms;
@ -19,26 +31,26 @@ class CreateEgg extends CreateRecord
{
return $form
->schema([
Forms\Components\Tabs::make()->tabs([
Forms\Components\Tabs\Tab::make('Configuration')
Tabs::make()->tabs([
Tab::make('Configuration')
->columns(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 4])
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->required()
->maxLength(255)
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->helperText('A simple, human-readable name to use as an identifier for this Egg.'),
Forms\Components\TextInput::make('author')
TextInput::make('author')
->maxLength(255)
->required()
->email()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->helperText('The author of this version of the Egg.'),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->rows(3)
->columnSpanFull()
->helperText('A description of this Egg that will be displayed throughout the Panel as needed.'),
Forms\Components\Textarea::make('startup')
Textarea::make('startup')
->rows(3)
->columnSpanFull()
->required()
@ -46,26 +58,26 @@ class CreateEgg extends CreateRecord
'java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}',
]))
->helperText('The default startup command that should be used for new servers using this Egg.'),
Forms\Components\TagsInput::make('features')
TagsInput::make('features')
->placeholder('Add Feature')
->helperText('')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\Toggle::make('force_outgoing_ip')
Toggle::make('force_outgoing_ip')
->hintIcon('tabler-question-mark')
->hintIconTooltip("Forces all outgoing network traffic to have its Source IP NATed to the IP of the server's primary allocation IP.
Required for certain games to work properly when the Node has multiple public IP addresses.
Enabling this option will disable internal networking for any servers using this egg, causing them to be unable to internally access other servers on the same node."),
Forms\Components\Hidden::make('script_is_privileged')
Hidden::make('script_is_privileged')
->default(1),
Forms\Components\TagsInput::make('tags')
TagsInput::make('tags')
->placeholder('Add Tags')
->helperText('')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\TextInput::make('update_url')
TextInput::make('update_url')
->disabled()
->helperText('Not implemented.')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\KeyValue::make('docker_images')
KeyValue::make('docker_images')
->live()
->columnSpanFull()
->required()
@ -77,37 +89,37 @@ class CreateEgg extends CreateRecord
->helperText('The docker images available to servers using this egg.'),
]),
Forms\Components\Tabs\Tab::make('Process Management')
Tab::make('Process Management')
->columns()
->schema([
Forms\Components\Hidden::make('config_from')
Hidden::make('config_from')
->default(null)
->label('Copy Settings From')
// ->placeholder('None')
// ->relationship('configFrom', 'name', ignoreRecord: true)
->helperText('If you would like to default to settings from another Egg select it from the menu above.'),
Forms\Components\TextInput::make('config_stop')
TextInput::make('config_stop')
->required()
->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.'),
Forms\Components\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.'),
Forms\Components\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.'),
Forms\Components\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.'),
]),
Forms\Components\Tabs\Tab::make('Egg Variables')
Tab::make('Egg Variables')
->columnSpanFull()
->schema([
Forms\Components\Repeater::make('variables')
Repeater::make('variables')
->label('')
->addActionLabel('Add New Egg Variable')
->grid()
@ -137,7 +149,7 @@ class CreateEgg extends CreateRecord
return $data;
})
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->live()
->debounce(750)
->maxLength(255)
@ -145,8 +157,8 @@ class CreateEgg extends CreateRecord
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
)
->required(),
Forms\Components\Textarea::make('description')->columnSpanFull(),
Forms\Components\TextInput::make('env_variable')
Textarea::make('description')->columnSpanFull(),
TextInput::make('env_variable')
->label('Environment Variable')
->maxLength(255)
->prefix('{{')
@ -154,29 +166,29 @@ class CreateEgg extends CreateRecord
->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}")
->required(),
Forms\Components\TextInput::make('default_value')->maxLength(255),
Forms\Components\Fieldset::make('User Permissions')
TextInput::make('default_value')->maxLength(255),
Fieldset::make('User Permissions')
->schema([
Forms\Components\Checkbox::make('user_viewable')->label('Viewable'),
Forms\Components\Checkbox::make('user_editable')->label('Editable'),
Checkbox::make('user_viewable')->label('Viewable'),
Checkbox::make('user_editable')->label('Editable'),
]),
Forms\Components\Textarea::make('rules')->columnSpanFull(),
Textarea::make('rules')->columnSpanFull(),
]),
]),
Forms\Components\Tabs\Tab::make('Install Script')
Tab::make('Install Script')
->columns(3)
->schema([
Forms\Components\Hidden::make('copy_script_from'),
Hidden::make('copy_script_from'),
//->placeholder('None')
//->relationship('scriptFrom', 'name', ignoreRecord: true),
Forms\Components\TextInput::make('script_container')
TextInput::make('script_container')
->required()
->maxLength(255)
->default('alpine:3.4'),
Forms\Components\Select::make('script_entry')
Select::make('script_entry')
->selectablePlaceholder(false)
->default('bash')
->options(['bash', 'ash', '/bin/bash'])

View File

@ -3,11 +3,25 @@
namespace App\Filament\Resources\EggResource\Pages;
use App\Filament\Resources\EggResource;
use App\Filament\Resources\EggResource\RelationManagers\ServersRelationManager;
use App\Models\Egg;
use App\Services\Eggs\Sharing\EggImporterService;
use Exception;
use Filament\Actions;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
@ -23,64 +37,64 @@ class EditEgg extends EditRecord
{
return $form
->schema([
Forms\Components\Tabs::make()->tabs([
Forms\Components\Tabs\Tab::make('Configuration')
Tabs::make()->tabs([
Tab::make('Configuration')
->columns(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 4])
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->required()
->maxLength(255)
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 1])
->helperText('A simple, human-readable name to use as an identifier for this Egg.'),
Forms\Components\TextInput::make('uuid')
TextInput::make('uuid')
->label('Egg UUID')
->disabled()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 2])
->helperText('This is the globally unique identifier for this Egg which Wings uses as an identifier.'),
Forms\Components\TextInput::make('id')
TextInput::make('id')
->label('Egg ID')
->disabled(),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->rows(3)
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->helperText('A description of this Egg that will be displayed throughout the Panel as needed.'),
Forms\Components\TextInput::make('author')
TextInput::make('author')
->required()
->maxLength(255)
->email()
->disabled()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->helperText('The author of this version of the Egg. Uploading a new Egg configuration from a different author will change this.'),
Forms\Components\Textarea::make('startup')
Textarea::make('startup')
->rows(2)
->columnSpanFull()
->required()
->helperText('The default startup command that should be used for new servers using this Egg.'),
Forms\Components\TagsInput::make('file_denylist')
TagsInput::make('file_denylist')
->hidden() // latest wings breaks it.
->placeholder('denied-file.txt')
->helperText('A list of files that the end user is not allowed to edit.')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\TagsInput::make('features')
TagsInput::make('features')
->placeholder('Add Feature')
->helperText('')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\Toggle::make('force_outgoing_ip')
Toggle::make('force_outgoing_ip')
->hintIcon('tabler-question-mark')
->hintIconTooltip("Forces all outgoing network traffic to have its Source IP NATed to the IP of the server's primary allocation IP.
Required for certain games to work properly when the Node has multiple public IP addresses.
Enabling this option will disable internal networking for any servers using this egg, causing them to be unable to internally access other servers on the same node."),
Forms\Components\Hidden::make('script_is_privileged')
Hidden::make('script_is_privileged')
->helperText('The docker images available to servers using this egg.'),
Forms\Components\TagsInput::make('tags')
TagsInput::make('tags')
->placeholder('Add Tags')
->helperText('')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\TextInput::make('update_url')
TextInput::make('update_url')
->disabled()
->helperText('Not implemented.')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]),
Forms\Components\KeyValue::make('docker_images')
KeyValue::make('docker_images')
->live()
->columnSpanFull()
->required()
@ -90,32 +104,32 @@ class EditEgg extends EditRecord
->helperText('The docker images available to servers using this egg.'),
]),
Forms\Components\Tabs\Tab::make('Process Management')
Tab::make('Process Management')
->columns()
->schema([
Forms\Components\Select::make('config_from')
Select::make('config_from')
->label('Copy Settings From')
->placeholder('None')
->relationship('configFrom', 'name', ignoreRecord: true)
->helperText('If you would like to default to settings from another Egg select it from the menu above.'),
Forms\Components\TextInput::make('config_stop')
TextInput::make('config_stop')
->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.'),
Forms\Components\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.'),
Forms\Components\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.'),
Forms\Components\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.'),
]),
Forms\Components\Tabs\Tab::make('Egg Variables')
Tab::make('Egg Variables')
->columnSpanFull()
->schema([
Forms\Components\Repeater::make('variables')
Repeater::make('variables')
->label('')
->grid()
->relationship('variables')
@ -144,7 +158,7 @@ class EditEgg extends EditRecord
return $data;
})
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->live()
->debounce(750)
->maxLength(255)
@ -152,8 +166,8 @@ class EditEgg extends EditRecord
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
)
->required(),
Forms\Components\Textarea::make('description')->columnSpanFull(),
Forms\Components\TextInput::make('env_variable')
Textarea::make('description')->columnSpanFull(),
TextInput::make('env_variable')
->label('Environment Variable')
->maxLength(255)
->prefix('{{')
@ -161,29 +175,29 @@ class EditEgg extends EditRecord
->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}")
->required(),
Forms\Components\TextInput::make('default_value')->maxLength(255),
Forms\Components\Fieldset::make('User Permissions')
TextInput::make('default_value')->maxLength(255),
Fieldset::make('User Permissions')
->schema([
Forms\Components\Checkbox::make('user_viewable')->label('Viewable'),
Forms\Components\Checkbox::make('user_editable')->label('Editable'),
Checkbox::make('user_viewable')->label('Viewable'),
Checkbox::make('user_editable')->label('Editable'),
]),
Forms\Components\TextInput::make('rules')->columnSpanFull(),
TextInput::make('rules')->columnSpanFull(),
]),
]),
Forms\Components\Tabs\Tab::make('Install Script')
Tab::make('Install Script')
->columns(3)
->schema([
Forms\Components\Select::make('copy_script_from')
Select::make('copy_script_from')
->placeholder('None')
->relationship('scriptFrom', 'name', ignoreRecord: true),
Forms\Components\TextInput::make('script_container')
TextInput::make('script_container')
->required()
->maxLength(255)
->default('alpine:3.4'),
Forms\Components\TextInput::make('script_entry')
TextInput::make('script_entry')
->required()
->maxLength(255)
->default('ash'),
@ -217,23 +231,23 @@ class EditEgg extends EditRecord
Actions\Action::make('importEgg')
->label('Import')
->form([
Forms\Components\Placeholder::make('warning')
Placeholder::make('warning')
->label('This will overwrite the current egg to the one you upload.'),
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('From File')
Tab::make('From File')
->icon('tabler-file-upload')
->schema([
Forms\Components\FileUpload::make('egg')
FileUpload::make('egg')
->label('Egg')
->hint('eg. minecraft.json')
->acceptedFileTypes(['application/json'])
->storeFiles(false),
]),
Tabs\Tab::make('From URL')
Tab::make('From URL')
->icon('tabler-world-upload')
->schema([
Forms\Components\TextInput::make('url')
TextInput::make('url')
->label('URL')
->hint('Link to the egg file (eg. minecraft.json)')
->url(),
@ -302,7 +316,7 @@ class EditEgg extends EditRecord
public function getRelationManagers(): array
{
return [
EggResource\RelationManagers\ServersRelationManager::class,
ServersRelationManager::class,
];
}
}

View File

@ -8,10 +8,16 @@ use App\Services\Eggs\Sharing\EggExporterService;
use App\Services\Eggs\Sharing\EggImporterService;
use Exception;
use Filament\Actions;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Filament\Tables;
@ -27,22 +33,22 @@ class ListEggs extends ListRecords
->defaultPaginationPageOption(25)
->checkIfRecordIsSelectableUsing(fn (Egg $egg) => $egg->servers_count <= 0)
->columns([
Tables\Columns\TextColumn::make('id')
TextColumn::make('id')
->label('Id')
->hidden(),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-egg')
->description(fn ($record): ?string => (strlen($record->description) > 120) ? substr($record->description, 0, 120).'...' : $record->description)
->wrap()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('servers_count')
TextColumn::make('servers_count')
->counts('servers')
->icon('tabler-server')
->label('Servers'),
])
->actions([
Tables\Actions\EditAction::make(),
EditAction::make(),
Tables\Actions\Action::make('export')
->icon('tabler-download')
->label('Export')
@ -52,8 +58,8 @@ class ListEggs extends ListRecords
}, 'egg-' . $egg->getKebabName() . '.json')),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
@ -67,20 +73,20 @@ class ListEggs extends ListRecords
->form([
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('From File')
Tab::make('From File')
->icon('tabler-file-upload')
->schema([
Forms\Components\FileUpload::make('egg')
FileUpload::make('egg')
->label('Egg')
->hint('This should be the json file ( egg-minecraft.json )')
->acceptedFileTypes(['application/json'])
->storeFiles(false)
->multiple(),
]),
Tabs\Tab::make('From URL')
Tab::make('From URL')
->icon('tabler-world-upload')
->schema([
Forms\Components\TextInput::make('url')
TextInput::make('url')
->label('URL')
->hint('This URL should point to a single json file')
->url(),

View File

@ -4,7 +4,8 @@ namespace App\Filament\Resources\EggResource\RelationManagers;
use App\Models\Server;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class ServersRelationManager extends RelationManager
@ -18,21 +19,21 @@ class ServersRelationManager extends RelationManager
->emptyStateDescription('No Servers')->emptyStateHeading('No servers are assigned this egg.')
->searchable(false)
->columns([
Tables\Columns\TextColumn::make('user.username')
TextColumn::make('user.username')
->label('Owner')
->icon('tabler-user')
->url(fn (Server $server): string => route('filament.admin.resources.users.edit', ['record' => $server->user]))
->sortable(),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-brand-docker')
->url(fn (Server $server): string => route('filament.admin.resources.servers.edit', ['record' => $server]))
->sortable(),
Tables\Columns\TextColumn::make('node.name')
TextColumn::make('node.name')
->icon('tabler-server-2')
->url(fn (Server $server): string => route('filament.admin.resources.nodes.edit', ['record' => $server->node])),
Tables\Columns\TextColumn::make('image')
TextColumn::make('image')
->label('Docker Image'),
Tables\Columns\SelectColumn::make('allocation.id')
SelectColumn::make('allocation.id')
->label('Primary Allocation')
->options(fn (Server $server) => [$server->allocation->id => $server->allocation->address])
->selectablePlaceholder(false)

View File

@ -4,11 +4,14 @@ namespace App\Filament\Resources\MountResource\Pages;
use App\Filament\Resources\MountResource;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Form;
use Filament\Resources\Pages\CreateRecord;
use Filament\Forms;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
@ -23,11 +26,11 @@ class CreateMount extends CreateRecord
return $form
->schema([
Section::make()->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->required()
->helperText('Unique name used to separate this mount from another.')
->maxLength(64),
Forms\Components\ToggleButtons::make('read_only')
ToggleButtons::make('read_only')
->label('Read only?')
->helperText('Is the mount read only inside the container?')
->options([
@ -45,15 +48,15 @@ class CreateMount extends CreateRecord
->inline()
->default(false)
->required(),
Forms\Components\TextInput::make('source')
TextInput::make('source')
->required()
->helperText('File path on the host system to mount to a container.')
->maxLength(255),
Forms\Components\TextInput::make('target')
TextInput::make('target')
->required()
->helperText('Where the mount will be accessible inside a container.')
->maxLength(255),
Forms\Components\ToggleButtons::make('user_mountable')
ToggleButtons::make('user_mountable')
->hidden()
->label('User mountable?')
->options([
@ -71,10 +74,10 @@ class CreateMount extends CreateRecord
->default(false)
->inline()
->required(),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->helperText('A longer description for this mount.')
->columnSpanFull(),
Forms\Components\Hidden::make('user_mountable')->default(1),
Hidden::make('user_mountable')->default(1),
])->columnSpan(1)->columns([
'default' => 1,
'lg' => 2,

View File

@ -4,8 +4,10 @@ namespace App\Filament\Resources\MountResource\Pages;
use App\Filament\Resources\MountResource;
use Filament\Actions;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Resources\Pages\EditRecord;
use Filament\Forms;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
@ -20,11 +22,11 @@ class EditMount extends EditRecord
return $form
->schema([
Section::make()->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->required()
->helperText('Unique name used to separate this mount from another.')
->maxLength(64),
Forms\Components\ToggleButtons::make('read_only')
ToggleButtons::make('read_only')
->label('Read only?')
->helperText('Is the mount read only inside the container?')
->options([
@ -42,15 +44,15 @@ class EditMount extends EditRecord
->inline()
->default(false)
->required(),
Forms\Components\TextInput::make('source')
TextInput::make('source')
->required()
->helperText('File path on the host system to mount to a container.')
->maxLength(255),
Forms\Components\TextInput::make('target')
TextInput::make('target')
->required()
->helperText('Where the mount will be accessible inside a container.')
->maxLength(255),
Forms\Components\ToggleButtons::make('user_mountable')
ToggleButtons::make('user_mountable')
->hidden()
->label('User mountable?')
->options([
@ -68,7 +70,7 @@ class EditMount extends EditRecord
->default(false)
->inline()
->required(),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->helperText('A longer description for this mount.')
->columnSpanFull(),
])->columnSpan(1)->columns([

View File

@ -6,9 +6,13 @@ use App\Filament\Resources\MountResource;
use App\Models\Mount;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables;
class ListMounts extends ListRecords
{
@ -18,31 +22,28 @@ class ListMounts extends ListRecords
return $table
->searchable(false)
->columns([
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->searchable(),
Tables\Columns\TextColumn::make('source')
TextColumn::make('source')
->searchable(),
Tables\Columns\TextColumn::make('target')
TextColumn::make('target')
->searchable(),
Tables\Columns\IconColumn::make('read_only')
IconColumn::make('read_only')
->icon(fn (bool $state) => $state ? 'tabler-circle-check-filled' : 'tabler-circle-x-filled')
->color(fn (bool $state) => $state ? 'success' : 'danger')
->sortable(),
Tables\Columns\IconColumn::make('user_mountable')
IconColumn::make('user_mountable')
->hidden()
->icon(fn (bool $state) => $state ? 'tabler-circle-check-filled' : 'tabler-circle-x-filled')
->color(fn (bool $state) => $state ? 'success' : 'danger')
->sortable(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
])
->emptyStateIcon('tabler-layers-linked')

View File

@ -3,7 +3,8 @@
namespace App\Filament\Resources;
use App\Filament\Resources\NodeResource\Pages;
use App\Filament\Resources\NodeResource\RelationManagers;
use App\Filament\Resources\NodeResource\RelationManagers\AllocationsRelationManager;
use App\Filament\Resources\NodeResource\RelationManagers\NodesRelationManager;
use App\Models\Node;
use Filament\Resources\Resource;
@ -23,8 +24,8 @@ class NodeResource extends Resource
public static function getRelations(): array
{
return [
RelationManagers\AllocationsRelationManager::class,
RelationManagers\NodesRelationManager::class,
AllocationsRelationManager::class,
NodesRelationManager::class,
];
}

View File

@ -4,8 +4,15 @@ namespace App\Filament\Resources\NodeResource\Pages;
use App\Filament\Resources\NodeResource;
use Filament\Forms;
use Filament\Forms\Components\Actions\Action;
use Filament\Actions\Action;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Components\Wizard;
use Filament\Forms\Components\Wizard\Step;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;
@ -23,7 +30,7 @@ class CreateNode extends CreateRecord
return $form
->schema([
Wizard::make([
Wizard\Step::make('basic')
Step::make('basic')
->label('Basic Settings')
->icon('tabler-server')
->columnSpanFull()
@ -34,7 +41,7 @@ class CreateNode extends CreateRecord
'lg' => 4,
])
->schema([
Forms\Components\TextInput::make('fqdn')
TextInput::make('fqdn')
->columnSpan(2)
->required()
->autofocus()
@ -67,7 +74,7 @@ class CreateNode extends CreateRecord
return '';
})
->afterStateUpdated(function (Forms\Set $set, ?string $state) {
->afterStateUpdated(function (Set $set, ?string $state) {
$set('dns', null);
$set('ip', null);
@ -95,17 +102,17 @@ class CreateNode extends CreateRecord
})
->maxLength(255),
Forms\Components\TextInput::make('ip')
TextInput::make('ip')
->disabled()
->hidden(),
Forms\Components\ToggleButtons::make('dns')
ToggleButtons::make('dns')
->label('DNS Record Check')
->helperText('This lets you know if your DNS record correctly points to an IP Address.')
->disabled()
->inline()
->default(null)
->hint(fn (Forms\Get $get) => $get('ip'))
->hint(fn (Get $get) => $get('ip'))
->hintColor('success')
->options([
true => 'Valid',
@ -122,7 +129,7 @@ class CreateNode extends CreateRecord
'lg' => 1,
]),
Forms\Components\TextInput::make('daemon_listen')
TextInput::make('daemon_listen')
->columnSpan([
'default' => 1,
'sm' => 1,
@ -137,7 +144,7 @@ class CreateNode extends CreateRecord
->required()
->integer(),
Forms\Components\TextInput::make('name')
TextInput::make('name')
->label('Display Name')
->columnSpan([
'default' => 1,
@ -150,7 +157,7 @@ class CreateNode extends CreateRecord
->helperText('This name is for display only and can be changed later.')
->maxLength(100),
Forms\Components\ToggleButtons::make('scheme')
ToggleButtons::make('scheme')
->label('Communicate over SSL')
->columnSpan([
'default' => 1,
@ -159,7 +166,7 @@ class CreateNode extends CreateRecord
'lg' => 1,
])
->inline()
->helperText(function (Forms\Get $get) {
->helperText(function (Get $get) {
if (request()->isSecure()) {
return new HtmlString('Your Panel is using a secure SSL connection,<br>so your Daemon must too.');
}
@ -185,7 +192,7 @@ class CreateNode extends CreateRecord
])
->default(fn () => request()->isSecure() ? 'https' : 'http'),
]),
Wizard\Step::make('advanced')
Step::make('advanced')
->label('Advanced Settings')
->icon('tabler-server-cog')
->columnSpanFull()
@ -196,7 +203,7 @@ class CreateNode extends CreateRecord
'lg' => 4,
])
->schema([
Forms\Components\ToggleButtons::make('maintenance_mode')
ToggleButtons::make('maintenance_mode')
->label('Maintenance Mode')->inline()
->columnSpan(1)
->default(false)
@ -210,7 +217,7 @@ class CreateNode extends CreateRecord
true => 'danger',
false => 'success',
]),
Forms\Components\ToggleButtons::make('public')
ToggleButtons::make('public')
->default(true)
->columnSpan(1)
->label('Automatic Allocation')->inline()
@ -222,15 +229,14 @@ class CreateNode extends CreateRecord
true => 'success',
false => 'danger',
]),
Forms\Components\TagsInput::make('tags')
TagsInput::make('tags')
->label('Tags')
->disabled()
->placeholder('Not Implemented')
->hintIcon('tabler-question-mark')
->hintIconTooltip('Not Implemented')
->columnSpan(2),
Forms\Components\TextInput::make('upload_size')
TextInput::make('upload_size')
->label('Upload Limit')
->helperText('Enter the maximum size of files that can be uploaded through the web-based file manager.')
->columnSpan(1)
@ -239,7 +245,7 @@ class CreateNode extends CreateRecord
->minValue(1)
->maxValue(1024)
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'),
Forms\Components\TextInput::make('daemon_sftp')
TextInput::make('daemon_sftp')
->columnSpan(1)
->label('SFTP Port')
->minValue(1)
@ -247,19 +253,19 @@ class CreateNode extends CreateRecord
->default(2022)
->required()
->integer(),
Forms\Components\TextInput::make('daemon_sftp_alias')
TextInput::make('daemon_sftp_alias')
->columnSpan(2)
->label('SFTP Alias')
->helperText('Display alias for the SFTP address. Leave empty to use the Node FQDN.'),
Forms\Components\Grid::make()
Grid::make()
->columns(6)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_mem')
ToggleButtons::make('unlimited_mem')
->label('Memory')->inlineLabel()->inline()
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('memory_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('memory') == 0)
->afterStateUpdated(fn (Set $set) => $set('memory', 0))
->afterStateUpdated(fn (Set $set) => $set('memory_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('memory') == 0)
->live()
->options([
true => 'Unlimited',
@ -270,9 +276,9 @@ class CreateNode extends CreateRecord
false => 'warning',
])
->columnSpan(2),
Forms\Components\TextInput::make('memory')
TextInput::make('memory')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
->hidden(fn (Get $get) => $get('unlimited_mem'))
->label('Memory Limit')->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->columnSpan(2)
@ -280,10 +286,10 @@ class CreateNode extends CreateRecord
->minValue(0)
->default(0)
->required(),
Forms\Components\TextInput::make('memory_overallocate')
TextInput::make('memory_overallocate')
->dehydratedWhenHidden()
->label('Overallocate')->inlineLabel()
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
->hidden(fn (Get $get) => $get('unlimited_mem'))
->hintIcon('tabler-question-mark')
->hintIconTooltip('The % allowable to go over the set limit.')
->columnSpan(2)
@ -294,16 +300,16 @@ class CreateNode extends CreateRecord
->suffix('%')
->required(),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(6)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_disk')
ToggleButtons::make('unlimited_disk')
->label('Disk')->inlineLabel()->inline()
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('disk_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('disk') == 0)
->afterStateUpdated(fn (Set $set) => $set('disk', 0))
->afterStateUpdated(fn (Set $set) => $set('disk_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('disk') == 0)
->options([
true => 'Unlimited',
false => 'Limited',
@ -313,9 +319,9 @@ class CreateNode extends CreateRecord
false => 'warning',
])
->columnSpan(2),
Forms\Components\TextInput::make('disk')
TextInput::make('disk')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
->hidden(fn (Get $get) => $get('unlimited_disk'))
->label('Disk Limit')->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->columnSpan(2)
@ -323,9 +329,9 @@ class CreateNode extends CreateRecord
->minValue(0)
->default(0)
->required(),
Forms\Components\TextInput::make('disk_overallocate')
TextInput::make('disk_overallocate')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
->hidden(fn (Get $get) => $get('unlimited_disk'))
->label('Overallocate')->inlineLabel()
->hintIcon('tabler-question-mark')
->hintIconTooltip('The % allowable to go over the set limit.')
@ -337,16 +343,16 @@ class CreateNode extends CreateRecord
->suffix('%')
->required(),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(6)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_cpu')
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->afterStateUpdated(fn (Set $set) => $set('cpu_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('cpu') == 0)
->options([
true => 'Unlimited',
false => 'Limited',
@ -356,9 +362,9 @@ class CreateNode extends CreateRecord
false => 'warning',
])
->columnSpan(2),
Forms\Components\TextInput::make('cpu')
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->columnSpan(2)
@ -366,9 +372,9 @@ class CreateNode extends CreateRecord
->default(0)
->minValue(0)
->required(),
Forms\Components\TextInput::make('cpu_overallocate')
TextInput::make('cpu_overallocate')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('Overallocate')->inlineLabel()
->hintIcon('tabler-question-mark')
->hintIconTooltip('The % allowable to go over the set limit.')

View File

@ -9,7 +9,16 @@ use App\Models\Node;
use App\Services\Nodes\NodeUpdateService;
use Filament\Actions;
use Filament\Forms;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\HtmlString;
@ -32,10 +41,10 @@ class EditNode extends EditRecord
->persistTabInQueryString()
->columnSpanFull()
->tabs([
Tabs\Tab::make('Basic Settings')
Tab::make('Basic Settings')
->icon('tabler-server')
->schema([
Forms\Components\TextInput::make('fqdn')
TextInput::make('fqdn')
->columnSpan(2)
->required()
->autofocus()
@ -68,7 +77,7 @@ class EditNode extends EditRecord
return '';
})
->afterStateUpdated(function (Forms\Set $set, ?string $state) {
->afterStateUpdated(function (Set $set, ?string $state) {
$set('dns', null);
$set('ip', null);
@ -96,17 +105,17 @@ class EditNode extends EditRecord
})
->maxLength(255),
Forms\Components\TextInput::make('ip')
TextInput::make('ip')
->disabled()
->hidden(),
Forms\Components\ToggleButtons::make('dns')
ToggleButtons::make('dns')
->label('DNS Record Check')
->helperText('This lets you know if your DNS record correctly points to an IP Address.')
->disabled()
->inline()
->default(null)
->hint(fn (Forms\Get $get) => $get('ip'))
->hint(fn (Get $get) => $get('ip'))
->hintColor('success')
->options([
true => 'Valid',
@ -123,7 +132,7 @@ class EditNode extends EditRecord
'lg' => 1,
]),
Forms\Components\TextInput::make('daemon_listen')
TextInput::make('daemon_listen')
->columnSpan([
'default' => 1,
'sm' => 1,
@ -138,7 +147,7 @@ class EditNode extends EditRecord
->required()
->integer(),
Forms\Components\TextInput::make('name')
TextInput::make('name')
->label('Display Name')
->columnSpan([
'default' => 1,
@ -151,7 +160,7 @@ class EditNode extends EditRecord
->helperText('This name is for display only and can be changed later.')
->maxLength(100),
Forms\Components\ToggleButtons::make('scheme')
ToggleButtons::make('scheme')
->label('Communicate over SSL')
->columnSpan([
'default' => 1,
@ -160,7 +169,7 @@ class EditNode extends EditRecord
'lg' => 1,
])
->inline()
->helperText(function (Forms\Get $get) {
->helperText(function (Get $get) {
if (request()->isSecure()) {
return new HtmlString('Your Panel is using a secure SSL connection,<br>so your Daemon must too.');
}
@ -185,27 +194,27 @@ class EditNode extends EditRecord
'https' => 'tabler-lock',
])
->default(fn () => request()->isSecure() ? 'https' : 'http'), ]),
Tabs\Tab::make('Advanced Settings')
Tab::make('Advanced Settings')
->columns(['default' => 1, 'sm' => 1, 'md' => 4, 'lg' => 6])
->icon('tabler-server-cog')
->schema([
Forms\Components\TextInput::make('id')
TextInput::make('id')
->label('Node ID')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 1])
->disabled(),
Forms\Components\TextInput::make('uuid')
TextInput::make('uuid')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->label('Node UUID')
->hintAction(CopyAction::make())
->disabled(),
Forms\Components\TagsInput::make('tags')
TagsInput::make('tags')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->label('Tags')
->disabled()
->placeholder('Not Implemented')
->hintIcon('tabler-question-mark')
->hintIconTooltip('Not Implemented'),
Forms\Components\TextInput::make('upload_size')
TextInput::make('upload_size')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 1])
->label('Upload Limit')
->hintIcon('tabler-question-mark')
@ -214,7 +223,7 @@ class EditNode extends EditRecord
->minValue(1)
->maxValue(1024)
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB'),
Forms\Components\TextInput::make('daemon_sftp')
TextInput::make('daemon_sftp')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3])
->label('SFTP Port')
->minValue(1)
@ -222,11 +231,11 @@ class EditNode extends EditRecord
->default(2022)
->required()
->integer(),
Forms\Components\TextInput::make('daemon_sftp_alias')
TextInput::make('daemon_sftp_alias')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3])
->label('SFTP Alias')
->helperText('Display alias for the SFTP address. Leave empty to use the Node FQDN.'),
Forms\Components\ToggleButtons::make('public')
ToggleButtons::make('public')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3])
->label('Automatic Allocation')->inline()
->options([
@ -237,7 +246,7 @@ class EditNode extends EditRecord
true => 'success',
false => 'danger',
]),
Forms\Components\ToggleButtons::make('maintenance_mode')
ToggleButtons::make('maintenance_mode')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3])
->label('Maintenance Mode')->inline()
->hinticon('tabler-question-mark')
@ -250,15 +259,15 @@ class EditNode extends EditRecord
false => 'success',
true => 'danger',
]),
Forms\Components\Grid::make()
Grid::make()
->columns(['default' => 1, 'sm' => 1, 'md' => 3, 'lg' => 6])
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_mem')
ToggleButtons::make('unlimited_mem')
->label('Memory')->inlineLabel()->inline()
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('memory_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('memory') == 0)
->afterStateUpdated(fn (Set $set) => $set('memory', 0))
->afterStateUpdated(fn (Set $set) => $set('memory_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('memory') == 0)
->live()
->options([
true => 'Unlimited',
@ -269,20 +278,20 @@ class EditNode extends EditRecord
false => 'warning',
])
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 2]),
Forms\Components\TextInput::make('memory')
TextInput::make('memory')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
->hidden(fn (Get $get) => $get('unlimited_mem'))
->label('Memory Limit')->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->required()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 2])
->numeric()
->minValue(0),
Forms\Components\TextInput::make('memory_overallocate')
TextInput::make('memory_overallocate')
->dehydratedWhenHidden()
->label('Overallocate')->inlineLabel()
->required()
->hidden(fn (Forms\Get $get) => $get('unlimited_mem'))
->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])
@ -291,15 +300,15 @@ class EditNode extends EditRecord
->maxValue(100)
->suffix('%'),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(['default' => 1, 'sm' => 1, 'md' => 3, 'lg' => 6])
->schema([
Forms\Components\ToggleButtons::make('unlimited_disk')
ToggleButtons::make('unlimited_disk')
->label('Disk')->inlineLabel()->inline()
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('disk_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('disk') == 0)
->afterStateUpdated(fn (Set $set) => $set('disk', 0))
->afterStateUpdated(fn (Set $set) => $set('disk_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('disk') == 0)
->options([
true => 'Unlimited',
false => 'Limited',
@ -309,18 +318,18 @@ class EditNode extends EditRecord
false => 'warning',
])
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 2]),
Forms\Components\TextInput::make('disk')
TextInput::make('disk')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
->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),
Forms\Components\TextInput::make('disk_overallocate')
TextInput::make('disk_overallocate')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
->hidden(fn (Get $get) => $get('unlimited_disk'))
->label('Overallocate')->inlineLabel()
->hintIcon('tabler-question-mark')
->hintIconTooltip('The % allowable to go over the set limit.')
@ -331,16 +340,16 @@ class EditNode extends EditRecord
->maxValue(100)
->suffix('%'),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(6)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_cpu')
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu_overallocate', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->afterStateUpdated(fn (Set $set) => $set('cpu_overallocate', 0))
->formatStateUsing(fn (Get $get) => $get('cpu') == 0)
->options([
true => 'Unlimited',
false => 'Limited',
@ -350,18 +359,18 @@ class EditNode extends EditRecord
false => 'warning',
])
->columnSpan(2),
Forms\Components\TextInput::make('cpu')
TextInput::make('cpu')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('CPU Limit')->inlineLabel()
->suffix('%')
->required()
->columnSpan(2)
->numeric()
->minValue(0),
Forms\Components\TextInput::make('cpu_overallocate')
TextInput::make('cpu_overallocate')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
->hidden(fn (Get $get) => $get('unlimited_cpu'))
->label('Overallocate')->inlineLabel()
->hintIcon('tabler-question-mark')
->hintIconTooltip('The % allowable to go over the set limit.')
@ -373,15 +382,15 @@ class EditNode extends EditRecord
->suffix('%'),
]),
]),
Tabs\Tab::make('Configuration File')
Tab::make('Configuration File')
->icon('tabler-code')
->schema([
Forms\Components\Placeholder::make('instructions')
Placeholder::make('instructions')
->columnSpanFull()
->content(new HtmlString('
Save this file to your <span title="usually /etc/pelican/">daemon\'s root directory</span>, named <code>config.yml</code>
')),
Forms\Components\Textarea::make('config')
Textarea::make('config')
->label('/etc/pelican/config.yml')
->disabled()
->rows(19)

View File

@ -6,9 +6,13 @@ use App\Filament\Resources\NodeResource;
use App\Models\Node;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables;
class ListNodes extends ListRecords
{
@ -20,70 +24,67 @@ class ListNodes extends ListRecords
->searchable(false)
->checkIfRecordIsSelectableUsing(fn (Node $node) => $node->servers_count <= 0)
->columns([
Tables\Columns\TextColumn::make('uuid')
TextColumn::make('uuid')
->label('UUID')
->searchable()
->hidden(),
Tables\Columns\IconColumn::make('health')
IconColumn::make('health')
->alignCenter()
->state(fn (Node $node) => $node)
->view('livewire.columns.version-column'),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-server-2')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('fqdn')
TextColumn::make('fqdn')
->visibleFrom('md')
->label('Address')
->icon('tabler-network')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('memory')
TextColumn::make('memory')
->visibleFrom('sm')
->icon('tabler-device-desktop-analytics')
->numeric()
->suffix(config('panel.use_binary_prefix') ? ' GiB' : ' GB')
->formatStateUsing(fn ($state) => number_format($state / (config('panel.use_binary_prefix') ? 1024 : 1000), 2))
->sortable(),
Tables\Columns\TextColumn::make('disk')
TextColumn::make('disk')
->visibleFrom('sm')
->icon('tabler-file')
->numeric()
->suffix(config('panel.use_binary_prefix') ? ' GiB' : ' GB')
->formatStateUsing(fn ($state) => number_format($state / (config('panel.use_binary_prefix') ? 1024 : 1000), 2))
->sortable(),
Tables\Columns\TextColumn::make('cpu')
TextColumn::make('cpu')
->visibleFrom('sm')
->icon('tabler-file')
->numeric()
->suffix(' %')
->sortable(),
Tables\Columns\IconColumn::make('scheme')
IconColumn::make('scheme')
->visibleFrom('xl')
->label('SSL')
->trueIcon('tabler-lock')
->falseIcon('tabler-lock-open-off')
->state(fn (Node $node) => $node->scheme === 'https'),
Tables\Columns\IconColumn::make('public')
IconColumn::make('public')
->visibleFrom('lg')
->trueIcon('tabler-eye-check')
->falseIcon('tabler-eye-cancel'),
Tables\Columns\TextColumn::make('servers_count')
TextColumn::make('servers_count')
->visibleFrom('sm')
->counts('servers')
->label('Servers')
->sortable()
->icon('tabler-brand-docker'),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
])
->emptyStateIcon('tabler-server-2')

View File

@ -5,10 +5,16 @@ namespace App\Filament\Resources\NodeResource\RelationManagers;
use App\Models\Allocation;
use App\Models\Node;
use App\Services\Allocations\AssignmentService;
use Filament\Forms;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Set;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\TextInputColumn;
use Filament\Tables\Table;
use Illuminate\Support\HtmlString;
@ -25,7 +31,7 @@ class AllocationsRelationManager extends RelationManager
{
return $form
->schema([
Forms\Components\TextInput::make('ip')
TextInput::make('ip')
->required()
->maxLength(255),
]);
@ -43,19 +49,19 @@ class AllocationsRelationManager extends RelationManager
->checkIfRecordIsSelectableUsing(fn (Allocation $allocation) => $allocation->server_id === null)
->searchable()
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('port')
TextColumn::make('id'),
TextColumn::make('port')
->searchable()
->label('Port'),
Tables\Columns\TextColumn::make('server.name')
TextColumn::make('server.name')
->label('Server')
->icon('tabler-brand-docker')
->searchable()
->url(fn (Allocation $allocation): string => $allocation->server ? route('filament.admin.resources.servers.edit', ['record' => $allocation->server]) : ''),
Tables\Columns\TextInputColumn::make('ip_alias')
TextInputColumn::make('ip_alias')
->searchable()
->label('Alias'),
Tables\Columns\TextInputColumn::make('ip')
TextInputColumn::make('ip')
->searchable()
->label('IP'),
])
@ -68,20 +74,20 @@ class AllocationsRelationManager extends RelationManager
->headerActions([
Tables\Actions\Action::make('create new allocation')->label('Create Allocations')
->form(fn () => [
Forms\Components\TextInput::make('allocation_ip')
TextInput::make('allocation_ip')
->datalist($this->getOwnerRecord()->ipAddresses())
->label('IP Address')
->inlineLabel()
->ipv4()
->helperText("Usually your machine's public IP unless you are port forwarding.")
->required(),
Forms\Components\TextInput::make('allocation_alias')
TextInput::make('allocation_alias')
->label('Alias')
->inlineLabel()
->default(null)
->helperText('Optional display name to help you remember what these are.')
->required(false),
Forms\Components\TagsInput::make('allocation_ports')
TagsInput::make('allocation_ports')
->placeholder('Examples: 27015, 27017-27019')
->helperText(new HtmlString('
These are the ports that users can connect to this Server through.
@ -91,7 +97,7 @@ class AllocationsRelationManager extends RelationManager
->label('Ports')
->inlineLabel()
->live()
->afterStateUpdated(function ($state, Forms\Set $set) {
->afterStateUpdated(function ($state, Set $set) {
$ports = collect();
$update = false;
foreach ($state as $portEntry) {
@ -145,9 +151,8 @@ class AllocationsRelationManager extends RelationManager
->action(fn (array $data) => resolve(AssignmentService::class)->handle($this->getOwnerRecord(), $data)),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
// Tables\Actions\DissociateBulkAction::make(),
Tables\Actions\DeleteBulkAction::make(),
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}

View File

@ -3,7 +3,8 @@
namespace App\Filament\Resources\NodeResource\RelationManagers;
use App\Models\Server;
use Filament\Tables;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Resources\RelationManagers\RelationManager;
@ -18,34 +19,34 @@ class NodesRelationManager extends RelationManager
return $table
->searchable(false)
->columns([
Tables\Columns\TextColumn::make('user.username')
TextColumn::make('user.username')
->label('Owner')
->icon('tabler-user')
->url(fn (Server $server): string => route('filament.admin.resources.users.edit', ['record' => $server->user]))
->searchable(),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-brand-docker')
->url(fn (Server $server): string => route('filament.admin.resources.servers.edit', ['record' => $server]))
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('egg.name')
TextColumn::make('egg.name')
->icon('tabler-egg')
->url(fn (Server $server): string => route('filament.admin.resources.eggs.edit', ['record' => $server->user]))
->sortable(),
Tables\Columns\SelectColumn::make('allocation.id')
SelectColumn::make('allocation.id')
->label('Primary Allocation')
->options(fn (Server $server) => [$server->allocation->id => $server->allocation->address])
->selectablePlaceholder(false)
->sortable(),
Tables\Columns\TextColumn::make('memory')->icon('tabler-device-desktop-analytics'),
Tables\Columns\TextColumn::make('cpu')->icon('tabler-cpu'),
Tables\Columns\TextColumn::make('databases_count')
TextColumn::make('memory')->icon('tabler-device-desktop-analytics'),
TextColumn::make('cpu')->icon('tabler-cpu'),
TextColumn::make('databases_count')
->counts('databases')
->label('Databases')
->icon('tabler-database')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('backups_count')
TextColumn::make('backups_count')
->counts('backups')
->label('Backups')
->icon('tabler-file-download')

View File

@ -3,7 +3,7 @@
namespace App\Filament\Resources;
use App\Filament\Resources\UserResource\Pages;
use App\Filament\Resources\UserResource\RelationManagers;
use App\Filament\Resources\UserResource\RelationManagers\ServersRelationManager;
use App\Models\User;
use Filament\Resources\Resource;
@ -23,7 +23,7 @@ class UserResource extends Resource
public static function getRelations(): array
{
return [
RelationManagers\ServersRelationManager::class,
ServersRelationManager::class,
];
}