Files
coolify/app/Livewire/Project/Application/DomainAdd.php
T
Andras BacsaiandClaude 3a08d26dc9 feat: Add domains sidebar view for simple applications
Implement a dedicated Domains management view for non-Docker Compose applications with:

- Separate Domains sidebar item under application configuration
- List-based domain management (add/remove individual domains)
- Three-field domain input (scheme, domain, port) with searchable dropdown for schemes
- Support for custom protocols (tcp, grpc, ftp, ssh, etc.) via x-forms.datalist component
- Generate random domain functionality
- DNS validation per domain
- Domain conflict detection
- Modal dialogs for adding/editing domains matching Coolify's design patterns
- Authorization checks using AuthorizesRequests trait
- Read-only domain display in General view for simple applications

Features:
- DomainAdd component: Creates new domains via searchable scheme dropdown
- DomainEdit component: Parses and updates existing domains
- Domains component: Manages domain list with add/edit/remove/refresh actions
- Backend stores domains as comma-separated strings in applications.fqdn column
- Frontend UI uses dashboard box styling with proper dark mode support

Documentation:
- Added x-forms.datalist component documentation to CLAUDE.md
- Added Domain Management section with architecture details
- Documented DomainAdd/DomainEdit components and workflow

🧠 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-27 15:23:33 +01:00

117 lines
3.4 KiB
PHP

<?php
namespace App\Livewire\Project\Application;
use App\Models\Application;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
use Spatie\Url\Url;
class DomainAdd extends Component
{
use AuthorizesRequests;
public Application $application;
public string $scheme = 'https';
public string $domain = '';
public string $port = '';
public function mount()
{
$this->authorize('update', $this->application);
}
public function submit()
{
$this->authorize('update', $this->application);
$this->validate([
'scheme' => 'required|string|alpha_dash',
'domain' => 'required|string',
'port' => 'nullable|integer|min:1|max:65535',
]);
try {
// Build the full domain URL
$fullDomain = $this->scheme.'://'.trim($this->domain);
// Add port if specified
if (! empty($this->port)) {
$fullDomain .= ':'.$this->port;
}
// Clean and validate
$fullDomain = str($fullDomain)->replaceEnd(',', '')->trim()->toString();
$fullDomain = str($fullDomain)->replaceStart(',', '')->trim()->toString();
// Validate URL format (allow any scheme)
try {
Url::fromString($fullDomain);
} catch (\Throwable $e) {
$this->dispatch('error', 'Invalid URL format.');
return;
}
$fullDomain = str($fullDomain)->lower()->toString();
// Get current domains
$currentDomains = $this->application->fqdn
? array_values(array_filter(explode(',', $this->application->fqdn)))
: [];
// Check if domain already exists
if (in_array($fullDomain, $currentDomains)) {
$this->dispatch('error', 'Domain already exists in the list.');
return;
}
// Add to domains array
$currentDomains[] = $fullDomain;
// Check for domain conflicts
$this->application->fqdn = implode(',', $currentDomains);
$result = checkDomainUsage(resource: $this->application);
if ($result['hasConflicts']) {
$this->dispatch('domainConflict', [
'conflicts' => $result['conflicts'],
'newDomain' => $fullDomain,
]);
return;
}
// Save to database
$this->application->save();
// Reset default labels
if ($this->application->settings->is_container_label_readonly_enabled) {
$customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n");
$this->application->custom_labels = base64_encode($customLabels);
$this->application->save();
}
$this->dispatch('configurationChanged');
$this->dispatch('success', 'Domain added successfully.');
$this->dispatch('modalClosed');
$this->dispatch('refreshDomains');
// Reset inputs
$this->scheme = 'https';
$this->domain = '';
$this->port = '';
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function render()
{
return view('livewire.project.application.domain-add');
}
}