diff --git a/app/Filament/Forms/SelectEndpoint.php b/app/Filament/Forms/SelectEndpoint.php new file mode 100644 index 000000000..5a3eb4fe7 --- /dev/null +++ b/app/Filament/Forms/SelectEndpoint.php @@ -0,0 +1,10 @@ +columns(4) ->schema([ Forms\Components\TagsInput::make('ports') - ->columnSpanFull() + ->columnSpan(2) ->hintIcon('tabler-question-mark') ->hintIconTooltip('Ports are limited from 1025 to 65535') ->placeholder('Example: 25565, 8080, 1337-1340') ->splitKeys(['Tab', ' ', ',']) ->helperText(new HtmlString(' - These are the ports that users can connect to this Server through. - You would typically port forward these on your home network. - ')) + These are the ports that users can connect to this Server through. + You would typically port forward these on your home network. + ')) ->label('Ports') ->afterStateUpdated(self::ports(...)) ->live(), - Forms\Components\Repeater::make('ip') - ->columnSpan(2) - ->defaultItems(5) - ->label('IP Assignments') - ->live() - ->addable(false) - ->deletable(false) - ->reorderable(false) - ->hintIcon('tabler-question-mark') - ->hintIconTooltip('These are the IPs available on the selected Node.') - ->simple( - Forms\Components\Select::make('port') - ->live() - ->placeholder('Select an IP') -// ->afterStateUpdated() - ->options(fn () => $this->node?->ipAddresses()) - ->required(), - ), - Forms\Components\Repeater::make('assignments') ->columnSpan(2) ->defaultItems(fn () => count($this->eggDefaultPorts)) @@ -372,11 +354,13 @@ class CreateServer extends CreateRecord ->deletable(false) ->reorderable(false) ->simple( - Forms\Components\Select::make('port') + SelectEndpoint::make('port') + ->columnSpanFull() + ->label('') ->live() ->placeholder('Select a Port') ->disabled(fn (Forms\Get $get) => empty($get('../../ports')) || empty($get('../../assignments'))) - ->prefix(function (Forms\Components\Component $component) { + ->suffix(function (Forms\Components\Component $component) { $key = str($component->getStatePath())->beforeLast('.')->afterLast('.')->toString(); return $key; diff --git a/resources/views/components/filament/wrapper.blade.php b/resources/views/components/filament/wrapper.blade.php new file mode 100644 index 000000000..6f4fc6ebe --- /dev/null +++ b/resources/views/components/filament/wrapper.blade.php @@ -0,0 +1,223 @@ +@props([ + 'alpineDisabled' => null, + 'alpineValid' => null, + 'disabled' => false, + 'inlinePrefix' => false, + 'inlineSuffix' => false, + 'prefix' => null, + 'prefixActions' => [], + 'prefixIcon' => null, + 'prefixIconColor' => 'gray', + 'prefixIconAlias' => null, + 'suffix' => null, + 'suffixActions' => [], + 'suffixIcon' => null, + 'suffixIconColor' => 'gray', + 'suffixIconAlias' => null, + 'valid' => true, +]) + +@php + $prefixActions = array_filter( + $prefixActions, + fn (\Filament\Forms\Components\Actions\Action $prefixAction): bool => $prefixAction->isVisible(), + ); + + $suffixActions = array_filter( + $suffixActions, + fn (\Filament\Forms\Components\Actions\Action $suffixAction): bool => $suffixAction->isVisible(), + ); + + $hasPrefix = count($prefixActions) || $prefixIcon || filled($prefix); + $hasSuffix = count($suffixActions) || $suffixIcon || filled($suffix); + + $hasAlpineDisabledClasses = filled($alpineDisabled); + $hasAlpineValidClasses = filled($alpineValid); + $hasAlpineClasses = $hasAlpineDisabledClasses || $hasAlpineValidClasses; + + $enabledWrapperClasses = 'bg-white dark:bg-white/5 [&:not(:has(.fi-ac-action:focus))]:focus-within:ring-2'; + $disabledWrapperClasses = 'fi-disabled bg-gray-50 dark:bg-transparent'; + $validWrapperClasses = 'ring-gray-950/10'; + $invalidWrapperClasses = 'fi-invalid ring-danger-600 dark:ring-danger-500'; + $enabledValidWrapperClasses = 'dark:ring-white/20 [&:not(:has(.fi-ac-action:focus))]:focus-within:ring-primary-600 dark:[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-primary-500'; + $enabledInvalidWrapperClasses = '[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-danger-600 dark:[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-danger-500'; + $disabledValidWrapperClasses = 'dark:ring-white/10'; + + $actionsClasses = 'flex items-center gap-3'; + $labelClasses = 'fi-input-wrp-label whitespace-nowrap text-sm text-gray-500 dark:text-gray-400'; + + $getIconClasses = fn (string | array $color = 'gray'): string => \Illuminate\Support\Arr::toCssClasses([ + 'fi-input-wrp-icon h-5 w-5', + match ($color) { + 'gray' => 'text-gray-400 dark:text-gray-500', + default => 'text-custom-500', + }, + ]); + + $getIconStyles = fn (string | array $color = 'gray'): string => \Illuminate\Support\Arr::toCssStyles([ + \Filament\Support\get_color_css_variables( + $color, + shades: [500], + alias: 'input-wrapper.icon', + ) => $color !== 'gray', + ]); + + $wireTarget = $attributes->whereStartsWith(['wire:target'])->first(); + + $hasLoadingIndicator = filled($wireTarget); + + if ($hasLoadingIndicator) { + $loadingIndicatorTarget = html_entity_decode($wireTarget, ENT_QUOTES); + } +@endphp + +