- Add ownedAndOnlySShKeys() method to filter out git-related keys
- Update Boarding component to use new filtering method
- Enhance datalist component with better multi-select and single-select handling
- Fix Alpine.js reactivity and improve UI interactions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The wire:dirty.class was being applied to all form inputs, even those without
wire:model bindings (like readonly fields). This caused the dirty state indicator
to appear on readonly fields when other fields in the form were modified.
Fixed by only applying wire:dirty.class when wire:model binding is present:
- input.blade.php: Moved wire:dirty.class inside @if($modelBinding !== 'null')
- textarea.blade.php: Applied same fix for all textarea variations
- select.blade.php: Applied same fix for select elements
This ensures only fields with actual Livewire bindings show dirty state indicators.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Resolved merge conflicts between Livewire model binding refactoring and UI/CSS updates from next branch. Key integrations:
- Preserved unique HTML ID generation for form components
- Maintained wire:model bindings using $modelBinding
- Integrated new wire:dirty.class styles (border-l-warning pattern)
- Kept both syncData(true) and validateDockerComposeForInjection in StackForm
- Merged security tests and helper improvements from next
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Problem:**
Monaco editor was receiving unique HTML IDs (e.g., "customLabels-a09a7773")
and using them in @entangle(), causing errors:
"Livewire property ['customLabels-a09a7773'] cannot be found"
**Root Cause:**
Monaco editor template uses @entangle($id) to bind to Livewire properties.
After our unique ID fix, $id contained the unique HTML ID with suffix,
not the original property name.
**Solution:**
Pass $modelBinding (original property name) instead of $htmlId to Monaco
editor component. This ensures @entangle() uses the correct property name
while HTML elements still get unique IDs.
**Result:**
✅ Monaco editor @entangle works correctly
✅ HTML IDs remain unique
✅ No Livewire property errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Resolve browser console warnings about non-unique HTML IDs when multiple
Livewire components with similar form fields appear on the same page.
**Problem:**
Multiple forms using generic IDs like `id="description"` or `id="name"`
caused duplicate ID warnings and potential accessibility/JavaScript issues.
**Solution:**
- Separate `wire:model` binding name from HTML `id` attribute
- Auto-prefix HTML IDs with Livewire component ID for uniqueness
- Preserve existing `wire:model` behavior with property names
**Implementation:**
- Added `$modelBinding` property for wire:model (e.g., "description")
- Added `$htmlId` property for unique HTML ID (e.g., "lw-xyz123-description")
- Updated render() method to generate unique IDs automatically
- Updated all blade templates to use new properties
**Components Updated:**
- Input (text, password, etc.)
- Textarea (including Monaco editor)
- Select
- Checkbox
- Datalist (single & multiple selection)
**Result:**
✅ All HTML IDs now unique across page
✅ No console warnings
✅ wire:model bindings work correctly
✅ Validation error messages display correctly
✅ Backward compatible - no changes needed in existing components
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the terminal server/container selection with a new searchable datalist component:
**Terminal View Changes:**
- Replaced `x-forms.select` with `x-forms.datalist` for server/container selection
- Added search functionality for filtering servers and containers
- Fixed form validation by adding hidden input for proper HTML5 validation
- Prevented error messages when clearing selection (sets to 'default')
**Datalist Component (Single Selection):**
- Implemented Alpine.js-powered dropdown with search functionality
- Added visual dropdown arrow that rotates when opened
- Proper entangle binding for wire:model support
- Keyboard support (Escape to close)
- Click outside to close behavior
- Disabled options filtering (skips disabled options)
- Consistent styling with input/textarea components
**Styling Improvements:**
- Explicit background colors: `bg-white` (light) and `dark:bg-coolgray-100` (dark)
- Proper ring border: `ring-1 ring-inset ring-neutral-200 dark:ring-coolgray-300`
- Focus states: `focus-within:ring-2 focus-within:ring-coollabs dark:focus-within:ring-warning`
- Text colors: `text-black dark:text-white`
- Added custom scrollbar styling for dropdown lists
- Wire:dirty state support for visual feedback
- Proper padding and spacing (`py-1.5`, `px-1`, `px-2`)
**Multiple Selection Mode:**
- Also updated for consistent styling and scrollbar support
- Added proper background colors and focus states
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added functionality for users to request an email change, including generating a verification code and setting an expiration time.
- Implemented methods in the User model to handle email change requests, code validation, and confirmation.
- Created a new job to update the user's email in Stripe after confirmation.
- Introduced rate limiting for email change requests and verification attempts to prevent abuse.
- Added a new notification for email change verification.
- Updated the profile component to manage email change requests and verification UI.