Merge pull request #89 from pelican-dev/issue/fix-mobile

Improve Mobile Experience
This commit is contained in:
Lance Pioch 2024-04-18 16:14:27 -04:00 committed by GitHub
commit 0949362da5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 190 additions and 78 deletions

View File

@ -72,33 +72,44 @@ class ApiKeyResource extends Resource
->required() ->required()
->default(ApiKey::TYPE_APPLICATION), ->default(ApiKey::TYPE_APPLICATION),
Forms\Components\Fieldset::make('Permissions')->schema( Forms\Components\Fieldset::make('Permissions')
collect(ApiKey::RESOURCES)->map(fn ($resource) => Forms\Components\ToggleButtons::make("r_$resource") ->columns([
->label(str($resource)->replace('_', ' ')->title()) 'default' => 1,
->options([ 'sm' => 1,
0 => 'None', 'md' => 2,
1 => 'Read', ])
// 2 => 'Write', ->schema(
3 => 'Read & Write', collect(ApiKey::RESOURCES)->map(fn ($resource) => Forms\Components\ToggleButtons::make("r_$resource")
]) ->label(str($resource)->replace('_', ' ')->title())
->icons([ ->options([
0 => 'tabler-book-off', 0 => 'None',
1 => 'tabler-book', 1 => 'Read',
2 => 'tabler-writing', // 2 => 'Write',
3 => 'tabler-writing', 3 => 'Read & Write',
]) ])
->colors([ ->icons([
0 => 'success', 0 => 'tabler-book-off',
1 => 'warning', 1 => 'tabler-book',
2 => 'danger', 2 => 'tabler-writing',
3 => 'danger', 3 => 'tabler-writing',
]) ])
->inline() ->colors([
->required() 0 => 'success',
->disabledOn('edit') 1 => 'warning',
->default(0), 2 => 'danger',
)->all(), 3 => 'danger',
), ])
->inline()
->required()
->disabledOn('edit')
->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
])
->default(0),
)->all(),
),
Forms\Components\TagsInput::make('allowed_ips') Forms\Components\TagsInput::make('allowed_ips')
->placeholder('Example: 127.0.0.1 or 192.168.1.1') ->placeholder('Example: 127.0.0.1 or 192.168.1.1')

View File

@ -133,7 +133,6 @@ class EggResource extends Resource
public static function table(Table $table): Table public static function table(Table $table): Table
{ {
return $table return $table
->searchable(false)
->defaultPaginationPageOption(25) ->defaultPaginationPageOption(25)
->columns([ ->columns([
Tables\Columns\TextColumn::make('id') Tables\Columns\TextColumn::make('id')
@ -142,13 +141,12 @@ class EggResource extends Resource
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('name') Tables\Columns\TextColumn::make('name')
->icon('tabler-egg') ->icon('tabler-egg')
->description(fn ($record): string => $record->description)
->wrap()
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('author') Tables\Columns\TextColumn::make('author')
->hidden() ->hidden()
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('description')
->words(50)
->wrap(),
Tables\Columns\TextColumn::make('servers_count') Tables\Columns\TextColumn::make('servers_count')
->counts('servers') ->counts('servers')
->icon('tabler-server') ->icon('tabler-server')

View File

@ -75,7 +75,7 @@ class MountResource extends Resource
Forms\Components\Textarea::make('description') Forms\Components\Textarea::make('description')
->helperText('A longer description for this mount.') ->helperText('A longer description for this mount.')
->columnSpanFull(), ->columnSpanFull(),
])->columnSpan(2)->columns([ ])->columnSpan(1)->columns([
'default' => 1, 'default' => 1,
'lg' => 2, 'lg' => 2,
]), ]),
@ -91,10 +91,11 @@ class MountResource extends Resource
]), ]),
])->columns([ ])->columns([
'default' => 1, 'default' => 1,
'lg' => 2,
]), ]),
])->columns([ ])->columns([
'default' => 1, 'default' => 1,
'lg' => 3, 'lg' => 2,
]); ]);
} }

View File

@ -96,31 +96,37 @@ class NodeResource extends Resource
->sortable() ->sortable()
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('fqdn') Tables\Columns\TextColumn::make('fqdn')
->visibleFrom('md')
->label('Address') ->label('Address')
->icon('tabler-network') ->icon('tabler-network')
->sortable() ->sortable()
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('memory') Tables\Columns\TextColumn::make('memory')
->visibleFrom('sm')
->icon('tabler-device-desktop-analytics') ->icon('tabler-device-desktop-analytics')
->numeric() ->numeric()
->suffix(' GB') ->suffix(' GB')
->formatStateUsing(fn ($state) => number_format($state / 1000, 2)) ->formatStateUsing(fn ($state) => number_format($state / 1000, 2))
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('disk') Tables\Columns\TextColumn::make('disk')
->visibleFrom('sm')
->icon('tabler-file') ->icon('tabler-file')
->numeric() ->numeric()
->suffix(' GB') ->suffix(' GB')
->formatStateUsing(fn ($state) => number_format($state / 1000, 2)) ->formatStateUsing(fn ($state) => number_format($state / 1000, 2))
->sortable(), ->sortable(),
Tables\Columns\IconColumn::make('scheme') Tables\Columns\IconColumn::make('scheme')
->visibleFrom('xl')
->label('SSL') ->label('SSL')
->trueIcon('tabler-lock') ->trueIcon('tabler-lock')
->falseIcon('tabler-lock-open-off') ->falseIcon('tabler-lock-open-off')
->state(fn (Node $node) => $node->scheme === 'https'), ->state(fn (Node $node) => $node->scheme === 'https'),
Tables\Columns\IconColumn::make('public') Tables\Columns\IconColumn::make('public')
->visibleFrom('lg')
->trueIcon('tabler-eye-check') ->trueIcon('tabler-eye-check')
->falseIcon('tabler-eye-cancel'), ->falseIcon('tabler-eye-cancel'),
Tables\Columns\TextColumn::make('servers_count') Tables\Columns\TextColumn::make('servers_count')
->visibleFrom('sm')
->counts('servers') ->counts('servers')
->label('Servers') ->label('Servers')
->sortable() ->sortable()

View File

@ -18,13 +18,18 @@ class CreateNode extends CreateRecord
public function form(Forms\Form $form): Forms\Form public function form(Forms\Form $form): Forms\Form
{ {
return $form return $form
->columns(4) ->columns([
'default' => 2,
'sm' => 3,
'md' => 3,
'lg' => 4,
])
->schema([ ->schema([
Forms\Components\TextInput::make('fqdn') Forms\Components\TextInput::make('fqdn')
->columnSpan(2) ->columnSpan(2)
->required() ->required()
->autofocus() ->autofocus()
->live(debounce: 500) ->live(debounce: 1500)
->rule('prohibited', fn ($state) => is_ip($state) && request()->isSecure()) ->rule('prohibited', fn ($state) => is_ip($state) && request()->isSecure())
->label(fn ($state) => is_ip($state) ? 'IP Address' : 'Domain Name') ->label(fn ($state) => is_ip($state) ? 'IP Address' : 'Domain Name')
->placeholder(fn ($state) => is_ip($state) ? '192.168.1.1' : 'node.example.com') ->placeholder(fn ($state) => is_ip($state) ? '192.168.1.1' : 'node.example.com')
@ -100,10 +105,21 @@ class CreateNode extends CreateRecord
->colors([ ->colors([
true => 'success', true => 'success',
false => 'danger', false => 'danger',
])
->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 1,
]), ]),
Forms\Components\TextInput::make('daemonListen') Forms\Components\TextInput::make('daemonListen')
->columnSpan(1) ->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 1,
])
->label('Port') ->label('Port')
->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.') ->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.')
->minValue(0) ->minValue(0)
@ -114,7 +130,12 @@ class CreateNode extends CreateRecord
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->label('Display Name') ->label('Display Name')
->columnSpan(2) ->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 2,
])
->required() ->required()
->regex('/[a-zA-Z0-9_\.\- ]+/') ->regex('/[a-zA-Z0-9_\.\- ]+/')
->helperText('This name is for display only and can be changed later.') ->helperText('This name is for display only and can be changed later.')
@ -122,7 +143,12 @@ class CreateNode extends CreateRecord
Forms\Components\ToggleButtons::make('scheme') Forms\Components\ToggleButtons::make('scheme')
->label('Communicate over SSL') ->label('Communicate over SSL')
->columnSpan(2) ->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 1,
'lg' => 1,
])
->required() ->required()
->inline() ->inline()
->helperText(function (Forms\Get $get) { ->helperText(function (Forms\Get $get) {
@ -153,7 +179,12 @@ class CreateNode extends CreateRecord
Forms\Components\Textarea::make('description') Forms\Components\Textarea::make('description')
->hidden() ->hidden()
->columnSpanFull() ->columnSpan([
'default' => 1,
'sm' => 1,
'md' => 2,
'lg' => 4,
])
->rows(5), ->rows(5),
Forms\Components\Hidden::make('skipValidation')->default(true), Forms\Components\Hidden::make('skipValidation')->default(true),

View File

@ -19,7 +19,12 @@ class EditNode extends EditRecord
{ {
return $form->schema([ return $form->schema([
Tabs::make('Tabs') Tabs::make('Tabs')
->columns(4) ->columns([
'default' => 2,
'sm' => 3,
'md' => 3,
'lg' => 4,
])
->persistTabInQueryString() ->persistTabInQueryString()
->columnSpanFull() ->columnSpanFull()
->tabs([ ->tabs([
@ -45,11 +50,11 @@ class EditNode extends EditRecord
]), ]),
Tabs\Tab::make('Allocations') Tabs\Tab::make('Allocations')
->icon('tabler-plug-connected') ->icon('tabler-plug-connected')
->columns(5) ->columns(4)
->schema([ ->schema([
Forms\Components\Repeater::make('allocations') Forms\Components\Repeater::make('allocations')
->orderColumn('server_id') ->orderColumn('server_id')
->columnSpan(3) ->columnSpan(1)
->columns(4) ->columns(4)
->relationship() ->relationship()
->addActionLabel('Create New Allocation') ->addActionLabel('Create New Allocation')

View File

@ -18,7 +18,6 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class ServerResource extends Resource class ServerResource extends Resource
{ {
@ -31,7 +30,12 @@ class ServerResource extends Resource
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->columns(6) ->columns([
'default' => 2,
'sm' => 2,
'md' => 4,
'lg' => 6,
])
->schema([ ->schema([
Forms\Components\ToggleButtons::make('docker') Forms\Components\ToggleButtons::make('docker')
->label('Container Status') ->label('Container Status')
@ -110,7 +114,12 @@ class ServerResource extends Resource
$set('name', $prefix . fake()->domainWord); $set('name', $prefix . fake()->domainWord);
})) }))
->columnSpan(4) ->columnSpan([
'default' => 2,
'sm' => 4,
'md' => 2,
'lg' => 3,
])
->required() ->required()
->maxLength(191), ->maxLength(191),
@ -118,7 +127,12 @@ class ServerResource extends Resource
->prefixIcon('tabler-user') ->prefixIcon('tabler-user')
->default(auth()->user()->id) ->default(auth()->user()->id)
->label('Owner') ->label('Owner')
->columnSpan(2) ->columnSpan([
'default' => 2,
'sm' => 4,
'md' => 2,
'lg' => 3,
])
->relationship('user', 'username') ->relationship('user', 'username')
->searchable() ->searchable()
->preload() ->preload()
@ -264,7 +278,12 @@ class ServerResource extends Resource
Forms\Components\Select::make('egg_id') Forms\Components\Select::make('egg_id')
->disabledOn('edit') ->disabledOn('edit')
->prefixIcon('tabler-egg') ->prefixIcon('tabler-egg')
->columnSpan(2) ->columnSpan([
'default' => 2,
'sm' => 2,
'md' => 2,
'lg' => 6,
])
->relationship('egg', 'name') ->relationship('egg', 'name')
->searchable() ->searchable()
->preload() ->preload()
@ -309,31 +328,6 @@ class ServerResource extends Resource
->inline() ->inline()
->required(), ->required(),
Forms\Components\Select::make('image')
->hidden(fn (Forms\Get $get) => $get('custom_image'))
->disabled(fn (Forms\Get $get) => $get('custom_image'))
->label('Docker Image')
->prefixIcon('tabler-brand-docker')
->options(function (Forms\Get $get, Forms\Set $set) {
$images = Egg::find($get('egg_id'))->docker_images ?? [];
$set('image', collect($images)->first());
return $images;
})
->disabled(fn (Forms\Components\Select $component) => empty($component->getOptions()))
->selectablePlaceholder(false)
->columnSpan(2)
->required(),
Forms\Components\TextInput::make('image')
->hidden(fn (Forms\Get $get) => !$get('custom_image'))
->disabled(fn (Forms\Get $get) => !$get('custom_image'))
->label('Docker Image')
->placeholder('Enter a custom Image')
->columnSpan(2)
->required(),
Forms\Components\ToggleButtons::make('custom_image') Forms\Components\ToggleButtons::make('custom_image')
->live() ->live()
->label('Custom Image?') ->label('Custom Image?')
@ -352,6 +346,41 @@ class ServerResource extends Resource
]) ])
->inline(), ->inline(),
Forms\Components\TextInput::make('image')
->hidden(fn (Forms\Get $get) => !$get('custom_image'))
->disabled(fn (Forms\Get $get) => !$get('custom_image'))
->label('Docker Image')
->placeholder('Enter a custom Image')
->columnSpan([
'default' => 2,
'sm' => 2,
'md' => 2,
'lg' => 4,
])
->required(),
Forms\Components\Select::make('image')
->hidden(fn (Forms\Get $get) => $get('custom_image'))
->disabled(fn (Forms\Get $get) => $get('custom_image'))
->label('Docker Image')
->prefixIcon('tabler-brand-docker')
->options(function (Forms\Get $get, Forms\Set $set) {
$images = Egg::find($get('egg_id'))->docker_images ?? [];
$set('image', collect($images)->first());
return $images;
})
->disabled(fn (Forms\Components\Select $component) => empty($component->getOptions()))
->selectablePlaceholder(false)
->columnSpan([
'default' => 2,
'sm' => 2,
'md' => 2,
'lg' => 4,
])
->required(),
Forms\Components\Fieldset::make('Application Feature Limits') Forms\Components\Fieldset::make('Application Feature Limits')
->inlineLabel() ->inlineLabel()
->hiddenOn('create') ->hiddenOn('create')
@ -379,13 +408,18 @@ class ServerResource extends Resource
->label('Startup Command') ->label('Startup Command')
->required() ->required()
->live() ->live()
->columnSpan([
'default' => 2,
'sm' => 4,
'md' => 4,
'lg' => 6,
])
->rows(function ($state) { ->rows(function ($state) {
return str($state)->explode("\n")->reduce( return str($state)->explode("\n")->reduce(
fn (int $carry, $line) => $carry + floor(strlen($line) / 125), fn (int $carry, $line) => $carry + floor(strlen($line) / 125),
0 0
); );
}) }),
->columnSpanFull(),
Forms\Components\Hidden::make('environment')->default([]), Forms\Components\Hidden::make('environment')->default([]),
@ -396,6 +430,12 @@ class ServerResource extends Resource
->iconColor('primary') ->iconColor('primary')
->collapsible() ->collapsible()
->collapsed() ->collapsed()
->columnSpan(([
'default' => 2,
'sm' => 4,
'md' => 4,
'lg' => 6,
]))
->schema([ ->schema([
Forms\Components\Placeholder::make('Select an egg first to show its variables!') Forms\Components\Placeholder::make('Select an egg first to show its variables!')
->hidden(fn (Forms\Get $get) => !empty($get('server_variables'))), ->hidden(fn (Forms\Get $get) => !empty($get('server_variables'))),
@ -424,14 +464,16 @@ class ServerResource extends Resource
}, },
]) ])
->label(fn (Forms\Get $get) => $get('name')) ->label(fn (Forms\Get $get) => $get('name'))
->hint(fn (Forms\Get $get) => $get('rules')) //->hint('Rule')
->hintIcon('tabler-code')
->hintIconTooltip(fn (Forms\Get $get) => $get('rules'))
->prefix(fn (Forms\Get $get) => '{{' . $get('env_variable') . '}}') ->prefix(fn (Forms\Get $get) => '{{' . $get('env_variable') . '}}')
->helperText(fn (Forms\Get $get) => empty($get('description')) ? '—' : $get('description')) ->helperText(fn (Forms\Get $get) => empty($get('description')) ? '—' : $get('description'))
->maxLength(191), ->maxLength(191),
Forms\Components\Hidden::make('variable_id')->default(0), Forms\Components\Hidden::make('variable_id')->default(0),
]) ])
->columnSpanFull(), ->columnSpan(2),
]), ]),
Forms\Components\Section::make('Resource Management') Forms\Components\Section::make('Resource Management')
@ -439,7 +481,13 @@ class ServerResource extends Resource
->collapsed() ->collapsed()
->icon('tabler-server-cog') ->icon('tabler-server-cog')
->iconColor('primary') ->iconColor('primary')
->columns(3) ->columns(2)
->columnSpan(([
'default' => 2,
'sm' => 4,
'md' => 4,
'lg' => 6,
]))
->schema([ ->schema([
Forms\Components\TextInput::make('memory') Forms\Components\TextInput::make('memory')
->default(0) ->default(0)

View File

@ -84,6 +84,7 @@ class UserResource extends Resource
->searchable(false) ->searchable(false)
->columns([ ->columns([
Tables\Columns\ImageColumn::make('picture') Tables\Columns\ImageColumn::make('picture')
->visibleFrom('lg')
->label('') ->label('')
->extraImgAttributes(['class' => 'rounded-full']) ->extraImgAttributes(['class' => 'rounded-full'])
->defaultImageUrl(fn (User $user) => 'https://gravatar.com/avatar/' . md5(strtolower($user->email))), ->defaultImageUrl(fn (User $user) => 'https://gravatar.com/avatar/' . md5(strtolower($user->email))),
@ -100,12 +101,14 @@ class UserResource extends Resource
->searchable() ->searchable()
->icon('tabler-mail'), ->icon('tabler-mail'),
Tables\Columns\IconColumn::make('root_admin') Tables\Columns\IconColumn::make('root_admin')
->visibleFrom('md')
->label('Admin') ->label('Admin')
->boolean() ->boolean()
->trueIcon('tabler-star') ->trueIcon('tabler-star')
->falseIcon('tabler-star-off') ->falseIcon('tabler-star-off')
->sortable(), ->sortable(),
Tables\Columns\IconColumn::make('use_totp')->label('2FA') Tables\Columns\IconColumn::make('use_totp')->label('2FA')
->visibleFrom('lg')
->icon(fn (User $user) => $user->use_totp ? 'tabler-lock' : 'tabler-lock-open-off') ->icon(fn (User $user) => $user->use_totp ? 'tabler-lock' : 'tabler-lock-open-off')
->boolean()->sortable(), ->boolean()->sortable(),
Tables\Columns\TextColumn::make('servers_count') Tables\Columns\TextColumn::make('servers_count')
@ -113,6 +116,7 @@ class UserResource extends Resource
->icon('tabler-server') ->icon('tabler-server')
->label('Servers'), ->label('Servers'),
Tables\Columns\TextColumn::make('subusers_count') Tables\Columns\TextColumn::make('subusers_count')
->visibleFrom('sm')
->counts('subusers') ->counts('subusers')
->icon('tabler-users') ->icon('tabler-users')
// ->formatStateUsing(fn (string $state, $record): string => (string) ($record->servers_count + $record->subusers_count)) // ->formatStateUsing(fn (string $state, $record): string => (string) ($record->servers_count + $record->subusers_count))

View File

@ -8,6 +8,7 @@ use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater; use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\Tabs; use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Tabs\Tab; use Filament\Forms\Components\Tabs\Tab;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Forms\Get; use Filament\Forms\Get;
@ -73,6 +74,13 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->icon('tabler-key') ->icon('tabler-key')
->schema([ ->schema([
Placeholder::make('Coming soon!'), Placeholder::make('Coming soon!'),
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()
->hidden()
->default(null),
]), ]),
Tab::make('SSH Keys') Tab::make('SSH Keys')