--- description: Enhanced form components with built-in authorization system globs: resources/views/**/*.blade.php, app/View/Components/Forms/*.php alwaysApply: true --- # Enhanced Form Components with Authorization ## Overview Coolify's form components now feature **built-in authorization** that automatically handles permission-based UI control, dramatically reducing code duplication and improving security consistency. ## Enhanced Components All form components now support the `canGate` authorization system: - **[Input.php](mdc:app/View/Components/Forms/Input.php)** - Text, password, and other input fields - **[Select.php](mdc:app/View/Components/Forms/Select.php)** - Dropdown selection components - **[Textarea.php](mdc:app/View/Components/Forms/Textarea.php)** - Multi-line text areas - **[Checkbox.php](mdc:app/View/Components/Forms/Checkbox.php)** - Boolean toggle components - **[Button.php](mdc:app/View/Components/Forms/Button.php)** - Action buttons ## Authorization Parameters ### Core Parameters ```php public ?string $canGate = null; // Gate name: 'update', 'view', 'deploy', 'delete' public mixed $canResource = null; // Resource model instance to check against public bool $autoDisable = true; // Automatically disable if no permission ``` ### How It Works ```php // Automatic authorization logic in each component if ($this->canGate && $this->canResource && $this->autoDisable) { $hasPermission = Gate::allows($this->canGate, $this->canResource); if (! $hasPermission) { $this->disabled = true; // For Checkbox: also sets $this->instantSave = false; } } ``` ## Usage Patterns ### ✅ Recommended: Single Line Pattern **Before (Verbose, 6+ lines per element):** ```html @can('update', $application) Save @else @endcan ``` **After (Clean, 1 line per element):** ```html Save ``` **Result: 90% code reduction!** ### Component-Specific Examples #### Input Fields ```html ``` #### Select Dropdowns ```html @foreach($servers as $server) @endforeach ``` #### Checkboxes with InstantSave ```html ``` #### Textareas ```html ``` #### Buttons ```html Save Configuration Deploy Application Delete Application ``` ## Advanced Usage ### Custom Authorization Logic ```html ``` ### Multiple Permission Checks ```html ``` ### Conditional Resources ```html {{ $isEditing ? 'Save Changes' : 'View Details' }} ``` ## Supported Gates ### Resource-Level Gates - `view` - Read access to resource details - `update` - Modify resource configuration and settings - `deploy` - Deploy, restart, or manage resource state - `delete` - Remove or destroy resource - `clone` - Duplicate resource to another location ### Global Gates - `createAnyResource` - Create new resources of any type - `manageTeam` - Team administration permissions - `accessServer` - Server-level access permissions ## Supported Resources ### Primary Resources - `$application` - Application instances and configurations - `$service` - Docker Compose services and components - `$database` - Database instances (PostgreSQL, MySQL, etc.) - `$server` - Physical or virtual server instances ### Container Resources - `$project` - Project containers and environments - `$environment` - Environment-specific configurations - `$team` - Team and organization contexts ### Infrastructure Resources - `$privateKey` - SSH private keys and certificates - `$source` - Git sources and repositories - `$destination` - Deployment destinations and targets ## Component Behavior ### Input Components (Input, Select, Textarea) When authorization fails: - **disabled = true** - Field becomes non-editable - **Visual styling** - Opacity reduction and disabled cursor - **Form submission** - Values are ignored in forms - **User feedback** - Clear visual indication of restricted access ### Checkbox Components When authorization fails: - **disabled = true** - Checkbox becomes non-clickable - **instantSave = false** - Automatic saving is disabled - **State preservation** - Current value is maintained but read-only - **Visual styling** - Disabled appearance with reduced opacity ### Button Components When authorization fails: - **disabled = true** - Button becomes non-clickable - **Event blocking** - Click handlers are ignored - **Visual styling** - Disabled appearance and cursor - **Loading states** - Loading indicators are disabled ## Migration Guide ### Converting Existing Forms **Old Pattern:** ```html
@can('update', $application) ... Save @else ... @endcan ``` **New Pattern:** ```html
... Save ``` ### Gradual Migration Strategy 1. **Start with new forms** - Use the new pattern for all new components 2. **Convert high-traffic areas** - Migrate frequently used forms first 3. **Batch convert similar forms** - Group similar authorization patterns 4. **Test thoroughly** - Verify authorization behavior matches expectations 5. **Remove old patterns** - Clean up legacy @can/@else blocks ## Testing Patterns ### Component Authorization Tests ```php // Test authorization integration in components test('input component respects authorization', function () { $user = User::factory()->member()->create(); $application = Application::factory()->create(); // Member should see disabled input $component = Livewire::actingAs($user) ->test(TestComponent::class, [ 'canGate' => 'update', 'canResource' => $application ]); expect($component->get('disabled'))->toBeTrue(); }); test('checkbox disables instantSave for unauthorized users', function () { $user = User::factory()->member()->create(); $application = Application::factory()->create(); $component = Livewire::actingAs($user) ->test(CheckboxComponent::class, [ 'instantSave' => true, 'canGate' => 'update', 'canResource' => $application ]); expect($component->get('disabled'))->toBeTrue(); expect($component->get('instantSave'))->toBeFalse(); }); ``` ### Integration Tests ```php // Test full form authorization behavior test('application form respects member permissions', function () { $member = User::factory()->member()->create(); $application = Application::factory()->create(); $this->actingAs($member) ->get(route('application.edit', $application)) ->assertSee('disabled') ->assertDontSee('Save Configuration'); }); ``` ## Best Practices ### Consistent Gate Usage - Use `update` for configuration changes - Use `deploy` for operational actions - Use `view` for read-only access - Use `delete` for destructive actions ### Resource Context - Always pass the specific resource being acted upon - Use team context for creation permissions - Consider nested resource relationships ### Error Handling - Provide clear feedback for disabled components - Use helper text to explain permission requirements - Consider tooltips for disabled buttons ### Performance - Authorization checks are cached per request - Use eager loading for resource relationships - Consider query optimization for complex permissions ## Common Patterns ### Application Configuration Forms ```html ... Save ``` ### Service Configuration Forms ```html Save @can('update', $service) @endcan ``` ### Server Management Forms ```html ... Delete Server ``` ### Resource Creation Forms ```html ... Create Application ```