Just some houseKeeping (#593)

* Just some houseKeeping

* ... pint
This commit is contained in:
Charles 2024-10-01 04:37:21 -04:00 committed by GitHub
parent 12a189f585
commit e78f7bc054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 251 additions and 234 deletions

View File

@ -15,9 +15,9 @@ use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Set;
use Filament\Resources\Pages\CreateRecord;
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
use Filament\Forms;
use Filament\Forms\Form;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
@ -155,7 +155,7 @@ class CreateEgg extends CreateRecord
->debounce(750)
->maxLength(255)
->columnSpanFull()
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
->afterStateUpdated(fn (Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
)
->required(),
Textarea::make('description')->columnSpanFull(),

View File

@ -10,7 +10,6 @@ use App\Services\Eggs\Sharing\EggExporterService;
use App\Services\Eggs\Sharing\EggImporterService;
use Exception;
use Filament\Actions;
use Filament\Forms;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
@ -26,6 +25,7 @@ use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Form;
use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
@ -165,7 +165,7 @@ class EditEgg extends EditRecord
->debounce(750)
->maxLength(255)
->columnSpanFull()
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
->afterStateUpdated(fn (Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
)
->required(),
Textarea::make('description')->columnSpanFull(),
@ -212,21 +212,17 @@ class EditEgg extends EditRecord
Tab::make('Install Script')
->columns(3)
->schema([
Select::make('copy_script_from')
->placeholder('None')
->relationship('scriptFrom', 'name', ignoreRecord: true),
TextInput::make('script_container')
->required()
->maxLength(255)
->default('alpine:3.4'),
TextInput::make('script_entry')
->required()
->maxLength(255)
->default('ash'),
MonacoEditor::make('script_install')
->label('Install Script')
->columnSpanFull()

View File

@ -12,7 +12,24 @@ use App\Services\Servers\RandomWordService;
use App\Services\Servers\ServerCreationService;
use App\Services\Users\UserCreationService;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\CheckboxList;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\KeyValue;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Components\Wizard\Step;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@ -35,7 +52,7 @@ class CreateServer extends CreateRecord
return $form
->schema([
Wizard::make([
Wizard\Step::make('Information')
Step::make('Information')
->label('Information')
->icon('tabler-info-circle')
->completedIcon('tabler-check')
@ -46,12 +63,12 @@ class CreateServer extends CreateRecord
'lg' => 6,
])
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->prefixIcon('tabler-server')
->label('Name')
->suffixAction(Forms\Components\Actions\Action::make('random')
->icon('tabler-dice-' . random_int(1, 6))
->action(function (Forms\Set $set, Forms\Get $get) {
->action(function (Set $set, Get $get) {
$egg = Egg::find($get('egg_id'));
$prefix = $egg ? str($egg->name)->lower()->kebab() . '-' : '';
@ -68,7 +85,7 @@ class CreateServer extends CreateRecord
->required()
->maxLength(255),
Forms\Components\Select::make('owner_id')
Select::make('owner_id')
->preload()
->prefixIcon('tabler-user')
->default(auth()->user()->id)
@ -83,18 +100,18 @@ class CreateServer extends CreateRecord
->searchable(['username', 'email'])
->getOptionLabelFromRecordUsing(fn (User $user) => "$user->email | $user->username " . ($user->isRootAdmin() ? '(admin)' : ''))
->createOptionForm([
Forms\Components\TextInput::make('username')
TextInput::make('username')
->alphaNum()
->required()
->maxLength(255),
Forms\Components\TextInput::make('email')
TextInput::make('email')
->email()
->required()
->unique()
->maxLength(255),
Forms\Components\TextInput::make('password')
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(),
@ -105,7 +122,7 @@ class CreateServer extends CreateRecord
})
->required(),
Forms\Components\Select::make('node_id')
Select::make('node_id')
->disabledOn('edit')
->prefixIcon('tabler-server-2')
->default(fn () => ($this->node = Node::query()->latest()->first())?->id)
@ -119,13 +136,13 @@ class CreateServer extends CreateRecord
->relationship('node', 'name')
->searchable()
->preload()
->afterStateUpdated(function (Forms\Set $set, $state) {
->afterStateUpdated(function (Set $set, $state) {
$set('allocation_id', null);
$this->node = Node::find($state);
})
->required(),
Forms\Components\Select::make('allocation_id')
Select::make('allocation_id')
->preload()
->live()
->prefixIcon('tabler-network')
@ -136,9 +153,9 @@ class CreateServer extends CreateRecord
'md' => 2,
'lg' => 3,
])
->disabled(fn (Forms\Get $get) => $get('node_id') === null)
->disabled(fn (Get $get) => $get('node_id') === null)
->searchable(['ip', 'port', 'ip_alias'])
->afterStateUpdated(function (Forms\Set $set) {
->afterStateUpdated(function (Set $set) {
$set('allocation_additional', null);
$set('allocation_additional.needstobeastringhere.extra_allocations', null);
})
@ -146,7 +163,7 @@ class CreateServer extends CreateRecord
fn (Allocation $allocation) => "$allocation->ip:$allocation->port" .
($allocation->ip_alias ? " ($allocation->ip_alias)" : '')
)
->placeholder(function (Forms\Get $get) {
->placeholder(function (Get $get) {
$node = Node::find($get('node_id'));
if ($node?->allocations) {
@ -158,12 +175,12 @@ class CreateServer extends CreateRecord
->relationship(
'allocation',
'ip',
fn (Builder $query, Forms\Get $get) => $query
fn (Builder $query, Get $get) => $query
->where('node_id', $get('node_id'))
->whereNull('server_id'),
)
->createOptionForm(fn (Forms\Get $get) => [
Forms\Components\TextInput::make('allocation_ip')
->createOptionForm(fn (Get $get) => [
TextInput::make('allocation_ip')
->datalist(Node::find($get('node_id'))?->ipAddresses() ?? [])
->label('IP Address')
->inlineLabel()
@ -171,7 +188,7 @@ class CreateServer extends CreateRecord
->helperText("Usually your machine's public IP unless you are port forwarding.")
// ->selectablePlaceholder(false)
->required(),
Forms\Components\TextInput::make('allocation_alias')
TextInput::make('allocation_alias')
->label('Alias')
->inlineLabel()
->default(null)
@ -181,7 +198,7 @@ class CreateServer extends CreateRecord
])
->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.
@ -191,7 +208,7 @@ class CreateServer extends CreateRecord
->label('Ports')
->inlineLabel()
->live()
->afterStateUpdated(function ($state, Forms\Set $set) {
->afterStateUpdated(function ($state, Set $set) {
$ports = collect();
$update = false;
foreach ($state as $portEntry) {
@ -243,14 +260,14 @@ class CreateServer extends CreateRecord
->splitKeys(['Tab', ' ', ','])
->required(),
])
->createOptionUsing(function (array $data, Forms\Get $get): int {
->createOptionUsing(function (array $data, Get $get): int {
return collect(
resolve(AssignmentService::class)->handle(Node::find($get('node_id')), $data)
)->first();
})
->required(),
Forms\Components\Repeater::make('allocation_additional')
Repeater::make('allocation_additional')
->label('Additional Allocations')
->columnSpan([
'default' => 2,
@ -259,18 +276,18 @@ class CreateServer extends CreateRecord
'lg' => 3,
])
->addActionLabel('Add Allocation')
->disabled(fn (Forms\Get $get) => $get('allocation_id') === null)
->disabled(fn (Get $get) => $get('allocation_id') === null)
// ->addable() TODO disable when all allocations are taken
// ->addable() TODO disable until first additional allocation is selected
->simple(
Forms\Components\Select::make('extra_allocations')
Select::make('extra_allocations')
->live()
->preload()
->disableOptionsWhenSelectedInSiblingRepeaterItems()
->prefixIcon('tabler-network')
->label('Additional Allocations')
->columnSpan(2)
->disabled(fn (Forms\Get $get) => $get('../../node_id') === null)
->disabled(fn (Get $get) => $get('../../node_id') === null)
->searchable(['ip', 'port', 'ip_alias'])
->getOptionLabelFromRecordUsing(
fn (Allocation $allocation) => "$allocation->ip:$allocation->port" .
@ -281,14 +298,14 @@ class CreateServer extends CreateRecord
->relationship(
'allocations',
'ip',
fn (Builder $query, Forms\Get $get, Forms\Components\Select $component, $state) => $query
fn (Builder $query, Get $get, Select $component, $state) => $query
->where('node_id', $get('../../node_id'))
->whereNot('id', $get('../../allocation_id'))
->whereNull('server_id'),
),
),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->placeholder('Description')
->rows(3)
->columnSpan([
@ -300,7 +317,7 @@ class CreateServer extends CreateRecord
->label('Description'),
]),
Wizard\Step::make('Egg Configuration')
Step::make('Egg Configuration')
->label('Egg Configuration')
->icon('tabler-egg')
->completedIcon('tabler-check')
@ -311,7 +328,7 @@ class CreateServer extends CreateRecord
'lg' => 6,
])
->schema([
Forms\Components\Select::make('egg_id')
Select::make('egg_id')
->prefixIcon('tabler-egg')
->relationship('egg', 'name')
->columnSpan([
@ -323,7 +340,7 @@ class CreateServer extends CreateRecord
->searchable()
->preload()
->live()
->afterStateUpdated(function ($state, Forms\Set $set, Forms\Get $get, $old) {
->afterStateUpdated(function ($state, Set $set, Get $get, $old) {
$egg = Egg::query()->find($state);
$set('startup', $egg->startup ?? '');
$set('image', '');
@ -351,7 +368,7 @@ class CreateServer extends CreateRecord
})
->required(),
Forms\Components\ToggleButtons::make('skip_scripts')
ToggleButtons::make('skip_scripts')
->label('Run Egg Install Script?')
->default(false)
->columnSpan([
@ -375,7 +392,7 @@ class CreateServer extends CreateRecord
->inline()
->required(),
Forms\Components\ToggleButtons::make('start_on_completion')
ToggleButtons::make('start_on_completion')
->label('Start Server After Install?')
->default(true)
->required()
@ -399,10 +416,10 @@ class CreateServer extends CreateRecord
])
->inline(),
Forms\Components\Textarea::make('startup')
Textarea::make('startup')
->hintIcon('tabler-code')
->label('Startup Command')
->hidden(fn (Forms\Get $get) => $get('egg_id') === null)
->hidden(fn (Get $get) => $get('egg_id') === null)
->required()
->live()
->rows(function ($state) {
@ -418,24 +435,24 @@ class CreateServer extends CreateRecord
'lg' => 6,
]),
Forms\Components\Hidden::make('environment')->default([]),
Hidden::make('environment')->default([]),
Forms\Components\Section::make('Variables')
Section::make('Variables')
->icon('tabler-eggs')
->iconColor('primary')
->hidden(fn (Forms\Get $get) => $get('egg_id') === null)
->hidden(fn (Get $get) => $get('egg_id') === null)
->collapsible()
->columnSpanFull()
->schema([
Forms\Components\Placeholder::make('Select an egg first to show its variables!')
->hidden(fn (Forms\Get $get) => $get('egg_id')),
Placeholder::make('Select an egg first to show its variables!')
->hidden(fn (Get $get) => $get('egg_id')),
Forms\Components\Placeholder::make('The selected egg has no variables!')
->hidden(fn (Forms\Get $get) => !$get('egg_id') ||
Placeholder::make('The selected egg has no variables!')
->hidden(fn (Get $get) => !$get('egg_id') ||
Egg::query()->find($get('egg_id'))?->variables()?->count()
),
Forms\Components\Repeater::make('server_variables')
Repeater::make('server_variables')
->label('')
->relationship('serverVariables')
->saveRelationshipsBeforeChildrenUsing(null)
@ -448,11 +465,11 @@ class CreateServer extends CreateRecord
->hidden(fn ($state) => empty($state))
->schema(function () {
$text = Forms\Components\TextInput::make('variable_value')
$text = TextInput::make('variable_value')
->hidden($this->shouldHideComponent(...))
->required(fn (Forms\Get $get) => in_array('required', $get('rules')))
->required(fn (Get $get) => in_array('required', $get('rules')))
->rules(
fn (Forms\Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
fn (Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
$validator = Validator::make(['validatorkey' => $value], [
'validatorkey' => $get('rules'),
]);
@ -465,7 +482,7 @@ class CreateServer extends CreateRecord
},
);
$select = Forms\Components\Select::make('variable_value')
$select = Select::make('variable_value')
->hidden($this->shouldHideComponent(...))
->options($this->getSelectOptionsFromRules(...))
->selectablePlaceholder(false);
@ -476,11 +493,11 @@ class CreateServer extends CreateRecord
$component = $component
->live(onBlur: true)
->hintIcon('tabler-code')
->label(fn (Forms\Get $get) => $get('name'))
->hintIconTooltip(fn (Forms\Get $get) => implode('|', $get('rules')))
->prefix(fn (Forms\Get $get) => '{{' . $get('env_variable') . '}}')
->helperText(fn (Forms\Get $get) => empty($get('description')) ? '—' : $get('description'))
->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
->label(fn (Get $get) => $get('name'))
->hintIconTooltip(fn (Get $get) => implode('|', $get('rules')))
->prefix(fn (Get $get) => '{{' . $get('env_variable') . '}}')
->helperText(fn (Get $get) => empty($get('description')) ? '—' : $get('description'))
->afterStateUpdated(function (Set $set, Get $get, $state) {
$environment = $get($envPath = '../../environment');
$environment[$get('env_variable')] = $state;
$set($envPath, $environment);
@ -492,12 +509,12 @@ class CreateServer extends CreateRecord
->columnSpan(2),
]),
]),
Wizard\Step::make('Environment Configuration')
Step::make('Environment Configuration')
->label('Environment Configuration')
->icon('tabler-brand-docker')
->completedIcon('tabler-check')
->schema([
Forms\Components\Fieldset::make('Resource Limits')
Fieldset::make('Resource Limits')
->columnSpan(6)
->columns([
'default' => 1,
@ -506,14 +523,14 @@ class CreateServer extends CreateRecord
'lg' => 3,
])
->schema([
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_mem')
ToggleButtons::make('unlimited_mem')
->label('Memory')->inlineLabel()->inline()
->default(true)
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
->afterStateUpdated(fn (Set $set) => $set('memory', 0))
->live()
->options([
true => 'Unlimited',
@ -525,9 +542,9 @@ class CreateServer extends CreateRecord
])
->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')
->default(0)
@ -537,15 +554,15 @@ class CreateServer extends CreateRecord
->minValue(0),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_disk')
ToggleButtons::make('unlimited_disk')
->label('Disk Space')->inlineLabel()->inline()
->default(true)
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
->afterStateUpdated(fn (Set $set) => $set('disk', 0))
->options([
true => 'Unlimited',
false => 'Limited',
@ -556,9 +573,9 @@ class CreateServer extends CreateRecord
])
->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 Space Limit')->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->default(0)
@ -568,14 +585,14 @@ class CreateServer extends CreateRecord
->minValue(0),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_cpu')
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->default(true)
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->live()
->options([
true => 'Unlimited',
@ -587,9 +604,9 @@ class CreateServer extends CreateRecord
])
->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('%')
->default(0)
@ -600,18 +617,18 @@ class CreateServer extends CreateRecord
->helperText('100% equals one CPU core.'),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('swap_support')
ToggleButtons::make('swap_support')
->live()
->label('Enable Swap Memory')
->inlineLabel()
->inline()
->columnSpan(2)
->default('disabled')
->afterStateUpdated(function ($state, Forms\Set $set) {
->afterStateUpdated(function ($state, Set $set) {
$value = match ($state) {
'unlimited' => -1,
'disabled' => 0,
@ -632,9 +649,9 @@ class CreateServer extends CreateRecord
'disabled' => 'danger',
]),
Forms\Components\TextInput::make('swap')
TextInput::make('swap')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
->hidden(fn (Get $get) => match ($get('swap_support')) {
'disabled', 'unlimited' => true,
default => false,
})
@ -648,16 +665,16 @@ class CreateServer extends CreateRecord
->integer(),
]),
Forms\Components\Hidden::make('io')
Hidden::make('io')
->helperText('The IO performance relative to other running containers')
->label('Block IO Proportion')
->default(500),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('oom_killer')
ToggleButtons::make('oom_killer')
->label('OOM Killer')
->inlineLabel()->inline()
->default(false)
@ -671,12 +688,12 @@ class CreateServer extends CreateRecord
true => 'danger',
]),
Forms\Components\TextInput::make('oom_disabled_hidden')
TextInput::make('oom_disabled_hidden')
->hidden(),
]),
]),
Forms\Components\Fieldset::make('Feature Limits')
Fieldset::make('Feature Limits')
->inlineLabel()
->columnSpan(6)
->columns([
@ -686,21 +703,21 @@ class CreateServer extends CreateRecord
'lg' => 3,
])
->schema([
Forms\Components\TextInput::make('allocation_limit')
TextInput::make('allocation_limit')
->label('Allocations')
->suffixIcon('tabler-network')
->required()
->numeric()
->minValue(0)
->default(0),
Forms\Components\TextInput::make('database_limit')
TextInput::make('database_limit')
->label('Databases')
->suffixIcon('tabler-database')
->required()
->numeric()
->minValue(0)
->default(0),
Forms\Components\TextInput::make('backup_limit')
TextInput::make('backup_limit')
->label('Backups')
->suffixIcon('tabler-copy-check')
->required()
@ -708,7 +725,7 @@ class CreateServer extends CreateRecord
->minValue(0)
->default(0),
]),
Forms\Components\Fieldset::make('Docker Settings')
Fieldset::make('Docker Settings')
->columns([
'default' => 1,
'sm' => 2,
@ -717,10 +734,10 @@ class CreateServer extends CreateRecord
])
->columnSpan(6)
->schema([
Forms\Components\Select::make('select_image')
Select::make('select_image')
->label('Image Name')
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
->options(function ($state, Forms\Get $get, Forms\Set $set) {
->afterStateUpdated(fn (Set $set, $state) => $set('image', $state))
->options(function ($state, Get $get, Set $set) {
$egg = Egg::query()->find($get('egg_id'));
$images = $egg->docker_images ?? [];
@ -741,10 +758,10 @@ class CreateServer extends CreateRecord
'lg' => 2,
]),
Forms\Components\TextInput::make('image')
TextInput::make('image')
->label('Image')
->debounce(500)
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
->afterStateUpdated(function ($state, Get $get, Set $set) {
$egg = Egg::query()->find($get('egg_id'));
$images = $egg->docker_images ?? [];
@ -762,13 +779,13 @@ class CreateServer extends CreateRecord
'lg' => 2,
]),
Forms\Components\KeyValue::make('docker_labels')
KeyValue::make('docker_labels')
->label('Container Labels')
->keyLabel('Title')
->valueLabel('Description')
->columnSpanFull(),
Forms\Components\CheckboxList::make('mounts')
CheckboxList::make('mounts')
->live()
->relationship('mounts')
->options(fn () => $this->node?->mounts->mapWithKeys(fn ($mount) => [$mount->id => $mount->name]) ?? [])
@ -812,24 +829,24 @@ class CreateServer extends CreateRecord
return $service->handle($data);
}
private function shouldHideComponent(Forms\Get $get, Forms\Components\Component $component): bool
private function shouldHideComponent(Get $get, Component $component): bool
{
$containsRuleIn = collect($get('rules'))->reduce(
fn ($result, $value) => $result === true && !str($value)->startsWith('in:'), true
);
if ($component instanceof Forms\Components\Select) {
if ($component instanceof Select) {
return $containsRuleIn;
}
if ($component instanceof Forms\Components\TextInput) {
if ($component instanceof TextInput) {
return !$containsRuleIn;
}
throw new \Exception('Component type not supported: ' . $component::class);
}
private function getSelectOptionsFromRules(Forms\Get $get): array
private function getSelectOptionsFromRules(Get $get): array
{
$inRule = collect($get('rules'))->reduce(
fn ($result, $value) => str($value)->startsWith('in:') ? $value : $result, ''

View File

@ -6,7 +6,15 @@ use App\Models\Database;
use App\Services\Databases\DatabaseManagementService;
use App\Services\Databases\DatabasePasswordService;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\CheckboxList;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Get;
use Filament\Forms\Set;
use LogicException;
@ -50,15 +58,15 @@ class EditServer extends EditRecord
])
->columnSpanFull()
->tabs([
Tabs\Tab::make('Information')
Tab::make('Information')
->icon('tabler-info-circle')
->schema([
Forms\Components\TextInput::make('name')
TextInput::make('name')
->prefixIcon('tabler-server')
->label('Display Name')
->suffixAction(Forms\Components\Actions\Action::make('random')
->suffixAction(Action::make('random')
->icon('tabler-dice-' . random_int(1, 6))
->action(function (Forms\Set $set, Forms\Get $get) {
->action(function (Set $set, Get $get) {
$egg = Egg::find($get('egg_id'));
$prefix = $egg ? str($egg->name)->lower()->kebab() . '-' : '';
@ -75,7 +83,7 @@ class EditServer extends EditRecord
->required()
->maxLength(255),
Forms\Components\Select::make('owner_id')
Select::make('owner_id')
->prefixIcon('tabler-user')
->label('Owner')
->columnSpan([
@ -89,7 +97,7 @@ class EditServer extends EditRecord
->preload()
->required(),
Forms\Components\ToggleButtons::make('condition')
ToggleButtons::make('condition')
->label('Server Status')
->formatStateUsing(fn (Server $server) => $server->condition)
->options(fn ($state) => collect(array_merge(ContainerStatus::cases(), ServerState::cases()))
@ -109,11 +117,11 @@ class EditServer extends EditRecord
'lg' => 1,
]),
Forms\Components\Textarea::make('description')
Textarea::make('description')
->label('Description')
->columnSpanFull(),
Forms\Components\TextInput::make('uuid')
TextInput::make('uuid')
->hintAction(CopyAction::make())
->columnSpan([
'default' => 2,
@ -123,7 +131,7 @@ class EditServer extends EditRecord
])
->readOnly()
->dehydrated(false),
Forms\Components\TextInput::make('uuid_short')
TextInput::make('uuid_short')
->label('Short UUID')
->hintAction(CopyAction::make())
->columnSpan([
@ -134,7 +142,7 @@ class EditServer extends EditRecord
])
->readOnly()
->dehydrated(false),
Forms\Components\TextInput::make('external_id')
TextInput::make('external_id')
->label('External ID')
->columnSpan([
'default' => 2,
@ -143,7 +151,7 @@ class EditServer extends EditRecord
'lg' => 3,
])
->maxLength(255),
Forms\Components\Select::make('node_id')
Select::make('node_id')
->label('Node')
->relationship('node', 'name')
->columnSpan([
@ -154,10 +162,10 @@ class EditServer extends EditRecord
])
->disabled(),
]),
Tabs\Tab::make('Environment')
Tab::make('Environment')
->icon('tabler-brand-docker')
->schema([
Forms\Components\Fieldset::make('Resource Limits')
Fieldset::make('Resource Limits')
->columns([
'default' => 1,
'sm' => 2,
@ -165,14 +173,14 @@ class EditServer extends EditRecord
'lg' => 3,
])
->schema([
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_mem')
ToggleButtons::make('unlimited_mem')
->label('Memory')->inlineLabel()->inline()
->afterStateUpdated(fn (Forms\Set $set) => $set('memory', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('memory') == 0)
->afterStateUpdated(fn (Set $set) => $set('memory', 0))
->formatStateUsing(fn (Get $get) => $get('memory') == 0)
->live()
->options([
true => 'Unlimited',
@ -184,9 +192,9 @@ class EditServer extends EditRecord
])
->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')
->required()
@ -195,15 +203,15 @@ class EditServer extends EditRecord
->minValue(0),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_disk')
ToggleButtons::make('unlimited_disk')
->label('Disk Space')->inlineLabel()->inline()
->live()
->afterStateUpdated(fn (Forms\Set $set) => $set('disk', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('disk') == 0)
->afterStateUpdated(fn (Set $set) => $set('disk', 0))
->formatStateUsing(fn (Get $get) => $get('disk') == 0)
->options([
true => 'Unlimited',
false => 'Limited',
@ -214,9 +222,9 @@ class EditServer extends EditRecord
])
->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 Space Limit')->inlineLabel()
->suffix(config('panel.use_binary_prefix') ? 'MiB' : 'MB')
->required()
@ -225,14 +233,14 @@ class EditServer extends EditRecord
->minValue(0),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('unlimited_cpu')
ToggleButtons::make('unlimited_cpu')
->label('CPU')->inlineLabel()->inline()
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
->afterStateUpdated(fn (Set $set) => $set('cpu', 0))
->formatStateUsing(fn (Get $get) => $get('cpu') == 0)
->live()
->options([
true => 'Unlimited',
@ -244,9 +252,9 @@ class EditServer extends EditRecord
])
->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()
@ -255,15 +263,15 @@ class EditServer extends EditRecord
->minValue(0),
]),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('swap_support')
ToggleButtons::make('swap_support')
->live()
->label('Enable Swap Memory')->inlineLabel()->inline()
->columnSpan(2)
->afterStateUpdated(function ($state, Forms\Set $set) {
->afterStateUpdated(function ($state, Set $set) {
$value = match ($state) {
'unlimited' => -1,
'disabled' => 0,
@ -273,7 +281,7 @@ class EditServer extends EditRecord
$set('swap', $value);
})
->formatStateUsing(function (Forms\Get $get) {
->formatStateUsing(function (Get $get) {
return match (true) {
$get('swap') > 0 => 'limited',
$get('swap') == 0 => 'disabled',
@ -292,9 +300,9 @@ class EditServer extends EditRecord
'disabled' => 'danger',
]),
Forms\Components\TextInput::make('swap')
TextInput::make('swap')
->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => match ($get('swap_support')) {
->hidden(fn (Get $get) => match ($get('swap_support')) {
'disabled', 'unlimited', true => true,
default => false,
})
@ -310,11 +318,11 @@ class EditServer extends EditRecord
->helperText('The IO performance relative to other running containers')
->label('Block IO Proportion'),
Forms\Components\Grid::make()
Grid::make()
->columns(4)
->columnSpanFull()
->schema([
Forms\Components\ToggleButtons::make('oom_killer')
ToggleButtons::make('oom_killer')
->label('OOM Killer')->inlineLabel()->inline()
->columnSpan(2)
->options([
@ -326,12 +334,12 @@ class EditServer extends EditRecord
true => 'danger',
]),
Forms\Components\TextInput::make('oom_disabled_hidden')
TextInput::make('oom_disabled_hidden')
->hidden(),
]),
]),
Forms\Components\Fieldset::make('Feature Limits')
Fieldset::make('Feature Limits')
->inlineLabel()
->columns([
'default' => 1,
@ -340,23 +348,23 @@ class EditServer extends EditRecord
'lg' => 3,
])
->schema([
Forms\Components\TextInput::make('allocation_limit')
TextInput::make('allocation_limit')
->suffixIcon('tabler-network')
->required()
->minValue(0)
->numeric(),
Forms\Components\TextInput::make('database_limit')
TextInput::make('database_limit')
->suffixIcon('tabler-database')
->required()
->minValue(0)
->numeric(),
Forms\Components\TextInput::make('backup_limit')
TextInput::make('backup_limit')
->suffixIcon('tabler-copy-check')
->required()
->minValue(0)
->numeric(),
]),
Forms\Components\Fieldset::make('Docker Settings')
Fieldset::make('Docker Settings')
->columns([
'default' => 1,
'sm' => 2,
@ -364,10 +372,10 @@ class EditServer extends EditRecord
'lg' => 3,
])
->schema([
Forms\Components\Select::make('select_image')
Select::make('select_image')
->label('Image Name')
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('image', $state))
->options(function ($state, Forms\Get $get, Forms\Set $set) {
->afterStateUpdated(fn (Set $set, $state) => $set('image', $state))
->options(function ($state, Get $get, Set $set) {
$egg = Egg::query()->find($get('egg_id'));
$images = $egg->docker_images ?? [];
@ -383,10 +391,10 @@ class EditServer extends EditRecord
->selectablePlaceholder(false)
->columnSpan(1),
Forms\Components\TextInput::make('image')
TextInput::make('image')
->label('Image')
->debounce(500)
->afterStateUpdated(function ($state, Forms\Get $get, Forms\Set $set) {
->afterStateUpdated(function ($state, Get $get, Set $set) {
$egg = Egg::query()->find($get('egg_id'));
$images = $egg->docker_images ?? [];
@ -406,7 +414,7 @@ class EditServer extends EditRecord
->columnSpanFull(),
]),
]),
Tabs\Tab::make('Egg')
Tab::make('Egg')
->icon('tabler-egg')
->columns([
'default' => 1,
@ -415,7 +423,7 @@ class EditServer extends EditRecord
'lg' => 5,
])
->schema([
Forms\Components\Select::make('egg_id')
Select::make('egg_id')
->disabledOn('edit')
->prefixIcon('tabler-egg')
->columnSpan([
@ -429,7 +437,7 @@ class EditServer extends EditRecord
->preload()
->required(),
Forms\Components\ToggleButtons::make('skip_scripts')
ToggleButtons::make('skip_scripts')
->label('Run Egg Install Script?')->inline()
->columnSpan([
'default' => 6,
@ -451,7 +459,7 @@ class EditServer extends EditRecord
])
->required(),
Forms\Components\Textarea::make('startup')
Textarea::make('startup')
->label('Startup Command')
->required()
->columnSpan(6)
@ -462,18 +470,18 @@ class EditServer extends EditRecord
);
}),
Forms\Components\Textarea::make('defaultStartup')
Textarea::make('defaultStartup')
->hintAction(CopyAction::make())
->label('Default Startup Command')
->disabled()
->formatStateUsing(function ($state, Get $get, Set $set) {
->formatStateUsing(function ($state, Get $get) {
$egg = Egg::query()->find($get('egg_id'));
return $egg->startup;
})
->columnSpan(6),
Forms\Components\Repeater::make('server_variables')
Repeater::make('server_variables')
->relationship('serverVariables', function (Builder $query) {
/** @var Server $server */
$server = $this->getRecord();
@ -502,7 +510,7 @@ class EditServer extends EditRecord
->reorderable(false)->addable(false)->deletable(false)
->schema(function () {
$text = Forms\Components\TextInput::make('variable_value')
$text = TextInput::make('variable_value')
->hidden($this->shouldHideComponent(...))
->required(fn (ServerVariable $serverVariable) => $serverVariable->variable->getRequiredAttribute())
->rules([
@ -519,7 +527,7 @@ class EditServer extends EditRecord
},
]);
$select = Forms\Components\Select::make('variable_value')
$select = Select::make('variable_value')
->hidden($this->shouldHideComponent(...))
->options($this->getSelectOptionsFromRules(...))
->selectablePlaceholder(false);
@ -540,10 +548,10 @@ class EditServer extends EditRecord
})
->columnSpan(6),
]),
Tabs\Tab::make('Mounts')
Tab::make('Mounts')
->icon('tabler-layers-linked')
->schema([
Forms\Components\CheckboxList::make('mounts')
CheckboxList::make('mounts')
->relationship('mounts')
->options(fn (Server $server) => $server->node->mounts->mapWithKeys(fn ($mount) => [$mount->id => $mount->name]))
->descriptions(fn (Server $server) => $server->node->mounts->mapWithKeys(fn ($mount) => [$mount->id => "$mount->source -> $mount->target"]))
@ -551,7 +559,7 @@ class EditServer extends EditRecord
->helperText(fn (Server $server) => $server->node->mounts->isNotEmpty() ? '' : 'No Mounts exist for this Node')
->columnSpanFull(),
]),
Tabs\Tab::make('Databases')
Tab::make('Databases')
->icon('tabler-database')
->schema([
Repeater::make('databases')
@ -559,7 +567,7 @@ class EditServer extends EditRecord
->helperText(fn (Server $server) => $server->databases->isNotEmpty() ? '' : 'No Databases exist for this Server')
->columns(2)
->schema([
Forms\Components\TextInput::make('database')
TextInput::make('database')
->columnSpan(2)
->label('Database Name')
->disabled()
@ -570,11 +578,11 @@ class EditServer extends EditRecord
->icon('tabler-trash')
->action(fn (DatabaseManagementService $databaseManagementService, $record) => $databaseManagementService->delete($record))
),
Forms\Components\TextInput::make('username')
TextInput::make('username')
->disabled()
->formatStateUsing(fn ($record) => $record->username)
->columnSpan(2),
Forms\Components\TextInput::make('password')
TextInput::make('password')
->disabled()
->hintAction(
Action::make('rotate')
@ -584,30 +592,30 @@ class EditServer extends EditRecord
)
->formatStateUsing(fn (Database $database) => $database->password)
->columnSpan(2),
Forms\Components\TextInput::make('remote')
TextInput::make('remote')
->disabled()
->formatStateUsing(fn ($record) => $record->remote)
->columnSpan(1)
->label('Connections From'),
Forms\Components\TextInput::make('max_connections')
TextInput::make('max_connections')
->disabled()
->formatStateUsing(fn ($record) => $record->max_connections)
->columnSpan(1),
Forms\Components\TextInput::make('JDBC')
TextInput::make('JDBC')
->disabled()
->label('JDBC Connection String')
->columnSpan(2)
->formatStateUsing(fn (Forms\Get $get, $record) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($record->password) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database')),
->formatStateUsing(fn (Get $get, $record) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($record->password) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database')),
])
->relationship('databases')
->deletable(false)
->addable(false)
->columnSpan(4),
])->columns(4),
Tabs\Tab::make('Actions')
Tab::make('Actions')
->icon('tabler-settings')
->schema([
Forms\Components\Fieldset::make('Server Actions')
Fieldset::make('Server Actions')
->columns([
'default' => 1,
'sm' => 2,
@ -615,11 +623,11 @@ class EditServer extends EditRecord
'lg' => 6,
])
->schema([
Forms\Components\Grid::make()
Grid::make()
->columnSpan(3)
->schema([
Forms\Components\Actions::make([
Forms\Components\Actions\Action::make('toggleInstall')
Action::make('toggleInstall')
->label('Toggle Install Status')
->disabled(fn (Server $server) => $server->isSuspended())
->action(function (ServersController $serversController, Server $server) {
@ -628,14 +636,14 @@ class EditServer extends EditRecord
$this->refreshFormData(['status', 'docker']);
}),
])->fullWidth(),
Forms\Components\ToggleButtons::make('')
ToggleButtons::make('')
->hint('If you need to change the install status from uninstalled to installed, or vice versa, you may do so with this button.'),
]),
Forms\Components\Grid::make()
Grid::make()
->columnSpan(3)
->schema([
Forms\Components\Actions::make([
Forms\Components\Actions\Action::make('toggleSuspend')
Action::make('toggleSuspend')
->label('Suspend')
->color('warning')
->hidden(fn (Server $server) => $server->isSuspended())
@ -645,7 +653,7 @@ class EditServer extends EditRecord
$this->refreshFormData(['status', 'docker']);
}),
Forms\Components\Actions\Action::make('toggleUnsuspend')
Action::make('toggleUnsuspend')
->label('Unsuspend')
->color('success')
->hidden(fn (Server $server) => !$server->isSuspended())
@ -656,37 +664,37 @@ class EditServer extends EditRecord
$this->refreshFormData(['status', 'docker']);
}),
])->fullWidth(),
Forms\Components\ToggleButtons::make('')
ToggleButtons::make('')
->hidden(fn (Server $server) => $server->isSuspended())
->hint('This will suspend the server, stop any running processes, and immediately block the user from being able to access their files or otherwise manage the server through the panel or API.'),
Forms\Components\ToggleButtons::make('')
ToggleButtons::make('')
->hidden(fn (Server $server) => !$server->isSuspended())
->hint('This will unsuspend the server and restore normal user access.'),
]),
Forms\Components\Grid::make()
Grid::make()
->columnSpan(3)
->schema([
Forms\Components\Actions::make([
Forms\Components\Actions\Action::make('transfer')
Action::make('transfer')
->label('Transfer Soon™')
->action(fn (TransferServerService $transfer, Server $server) => $transfer->handle($server, []))
->disabled() //TODO!
->form([ //TODO!
Forms\Components\Select::make('newNode')
Select::make('newNode')
->label('New Node')
->required()
->options([
true => 'on',
false => 'off',
]),
Forms\Components\Select::make('newMainAllocation')
Select::make('newMainAllocation')
->label('New Main Allocation')
->required()
->options([
true => 'on',
false => 'off',
]),
Forms\Components\Select::make('newAdditionalAllocation')
Select::make('newAdditionalAllocation')
->label('New Additional Allocations')
->options([
true => 'on',
@ -695,14 +703,14 @@ class EditServer extends EditRecord
])
->modalHeading('Transfer'),
])->fullWidth(),
Forms\Components\ToggleButtons::make('')
ToggleButtons::make('')
->hint('Transfer this server to another node connected to this panel. Warning! This feature has not been fully tested and may have bugs.'),
]),
Forms\Components\Grid::make()
Grid::make()
->columnSpan(3)
->schema([
Forms\Components\Actions::make([
Forms\Components\Actions\Action::make('reinstall')
Action::make('reinstall')
->label('Reinstall')
->color('danger')
->requiresConfirmation()
@ -711,7 +719,7 @@ class EditServer extends EditRecord
->disabled(fn (Server $server) => $server->isSuspended())
->action(fn (ServersController $serversController, Server $server) => $serversController->reinstallServer($server)),
])->fullWidth(),
Forms\Components\ToggleButtons::make('')
ToggleButtons::make('')
->hint('This will reinstall the server with the assigned egg install script.'),
]),
]),
@ -725,9 +733,9 @@ class EditServer extends EditRecord
return $form
->columns()
->schema([
Forms\Components\Select::make('toNode')
Select::make('toNode')
->label('New Node'),
Forms\Components\TextInput::make('newAllocation')
TextInput::make('newAllocation')
->label('Allocation'),
]);
@ -780,11 +788,11 @@ class EditServer extends EditRecord
{
$containsRuleIn = array_first($serverVariable->variable->rules, fn ($value) => str($value)->startsWith('in:'), false);
if ($component instanceof Forms\Components\Select) {
if ($component instanceof Select) {
return !$containsRuleIn;
}
if ($component instanceof Forms\Components\TextInput) {
if ($component instanceof TextInput) {
return $containsRuleIn;
}

View File

@ -7,10 +7,13 @@ use App\Models\Server;
use App\Models\User;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
use Filament\Tables;
class ListServers extends ListRecords
{
@ -27,47 +30,47 @@ class ListServers extends ListRecords
Group::make('egg.name')->getDescriptionFromRecordUsing(fn (Server $server): string => str($server->egg->description)->limit(150)),
])
->columns([
Tables\Columns\TextColumn::make('condition')
TextColumn::make('condition')
->default('unknown')
->badge()
->icon(fn (Server $server) => $server->conditionIcon())
->color(fn (Server $server) => $server->conditionColor()),
Tables\Columns\TextColumn::make('uuid')
TextColumn::make('uuid')
->hidden()
->label('UUID')
->searchable(),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-brand-docker')
->searchable()
->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]))
->hidden(fn (Table $table) => $table->getGrouping()?->getId() === 'node.name')
->sortable()
->searchable(),
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->egg]))
->hidden(fn (Table $table) => $table->getGrouping()?->getId() === 'egg.name')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('user.username')
TextColumn::make('user.username')
->icon('tabler-user')
->label('Owner')
->url(fn (Server $server): string => route('filament.admin.resources.users.edit', ['record' => $server->user]))
->hidden(fn (Table $table) => $table->getGrouping()?->getId() === 'user.username')
->sortable()
->searchable(),
Tables\Columns\SelectColumn::make('allocation_id')
SelectColumn::make('allocation_id')
->label('Primary Allocation')
->options(fn (Server $server) => $server->allocations->mapWithKeys(
fn ($allocation) => [$allocation->id => $allocation->address])
)
->selectablePlaceholder(false)
->sortable(),
Tables\Columns\TextColumn::make('image')->hidden(),
Tables\Columns\TextColumn::make('backups_count')
TextColumn::make('image')->hidden(),
TextColumn::make('backups_count')
->counts('backups')
->label('Backups')
->icon('tabler-file-download')
@ -75,7 +78,7 @@ class ListServers extends ListRecords
->sortable(),
])
->actions([
Tables\Actions\Action::make('View')
Action::make('View')
->icon('tabler-terminal')
->url(fn (Server $server) => "/server/$server->uuid_short")
->visible(function (Server $server) {
@ -84,7 +87,7 @@ class ListServers extends ListRecords
return $user->isRootAdmin() || $user->id === $server->owner_id;
}),
Tables\Actions\EditAction::make(),
EditAction::make(),
])
->emptyStateIcon('tabler-brand-docker')
->searchable()

View File

@ -11,6 +11,12 @@ use Filament\Forms\Set;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\AssociateAction;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\TextInputColumn;
use Filament\Tables\Table;
use Illuminate\Support\HtmlString;
@ -41,10 +47,10 @@ class AllocationsRelationManager extends RelationManager
// ->groups
->inverseRelationship('server')
->columns([
Tables\Columns\TextColumn::make('ip')->label('IP'),
Tables\Columns\TextColumn::make('port')->label('Port'),
Tables\Columns\TextInputColumn::make('ip_alias')->label('Alias'),
Tables\Columns\IconColumn::make('primary')
TextColumn::make('ip')->label('IP'),
TextColumn::make('port')->label('Port'),
TextInputColumn::make('ip_alias')->label('Alias'),
IconColumn::make('primary')
->icon(fn ($state) => match ($state) {
true => 'tabler-star-filled',
default => 'tabler-star',
@ -61,12 +67,12 @@ class AllocationsRelationManager extends RelationManager
//
])
->actions([
Tables\Actions\Action::make('make-primary')
Action::make('make-primary')
->action(fn (Allocation $allocation) => $this->getOwnerRecord()->update(['allocation_id' => $allocation->id]))
->label(fn (Allocation $allocation) => $allocation->id === $this->getOwnerRecord()->allocation_id ? '' : 'Make Primary'),
])
->headerActions([
Tables\Actions\CreateAction::make()->label('Create Allocation')
CreateAction::make()->label('Create Allocation')
->createAnother(false)
->form(fn () => [
TextInput::make('allocation_ip')
@ -144,7 +150,7 @@ class AllocationsRelationManager extends RelationManager
->required(),
])
->action(fn (array $data) => resolve(AssignmentService::class)->handle($this->getOwnerRecord()->node, $data, $this->getOwnerRecord())),
Tables\Actions\AssociateAction::make()
AssociateAction::make()
->multiple()
->associateAnother(false)
->preloadRecordSelect()

View File

@ -57,7 +57,6 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->maxLength(255)
->unique(ignoreRecord: true)
->autofocus(),
TextInput::make('email')
->prefixIcon('tabler-mail')
->label(trans('strings.email'))
@ -65,7 +64,6 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->required()
->maxLength(255)
->unique(ignoreRecord: true),
TextInput::make('password')
->label(trans('strings.password'))
->password()
@ -77,7 +75,6 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->live(debounce: 500)
->same('passwordConfirmation'),
TextInput::make('passwordConfirmation')
->label(trans('strings.password_confirmation'))
->password()
@ -86,13 +83,11 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->required()
->visible(fn (Get $get): bool => filled($get('password')))
->dehydrated(false),
Select::make('timezone')
->required()
->prefixIcon('tabler-clock-pin')
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
->searchable(),
Select::make('language')
->label(trans('strings.language'))
->required()
@ -111,7 +106,6 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
Tab::make('2FA')
->icon('tabler-shield-lock')
->schema(function () {
if ($this->getUser()->use_totp) {
return [
Placeholder::make('2fa-already-enabled')
@ -196,16 +190,13 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->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'])
@ -222,12 +213,10 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
$get('description'),
$get('allowed_ips'),
);
Activity::event('user:api-key.create')
->subject($token->accessToken)
->property('identifier', $token->accessToken->identifier)
->log();
$action->success();
}),
]),
@ -256,13 +245,11 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
]),
]),
]),
Tab::make('SSH Keys')
->icon('tabler-lock-code')
->schema([
Placeholder::make('Coming soon!'),
]),
Tab::make('Activity')
->icon('tabler-history')
->schema([

View File

@ -6,7 +6,8 @@ use App\Enums\ServerState;
use App\Models\Server;
use App\Models\User;
use App\Services\Servers\SuspensionService;
use Filament\Tables;
use Filament\Tables\Columns\SelectColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Tables\Actions;
use Filament\Resources\RelationManagers\RelationManager;
@ -36,7 +37,6 @@ class ServersRelationManager extends RelationManager
resolve(SuspensionService::class)->toggle($server);
}
}),
Actions\Action::make('toggleUnsuspend')
->hidden(fn () => $user->servers()->where('status', ServerState::Suspended)->count() === 0)
->label('Unsuspend All Servers')
@ -48,37 +48,37 @@ class ServersRelationManager extends RelationManager
}),
])
->columns([
Tables\Columns\TextColumn::make('uuid')
TextColumn::make('uuid')
->hidden()
->label('UUID')
->searchable(),
Tables\Columns\TextColumn::make('name')
TextColumn::make('name')
->icon('tabler-brand-docker')
->label(trans('strings.name'))
->url(fn (Server $server): string => route('filament.admin.resources.servers.edit', ['record' => $server]))
->searchable()
->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]))
->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->egg]))
->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('image')->hidden(),
Tables\Columns\TextColumn::make('databases_count')
TextColumn::make('image')->hidden(),
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')