From 8714d9bd0332a29275750f2f58fab043df2d677a Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 2 Dec 2025 13:37:41 +0100 Subject: [PATCH] fix: apply frontend path normalization to general settings page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the same frontend path normalization pattern from commit f6398f7cf to the General Settings page for consistency across all forms. Changes: - Add Alpine.js path normalization to Docker Compose section (base directory + compose location) - Add Alpine.js path normalization to non-Docker Compose section (base directory + dockerfile location) - Change wire:model to wire:model.defer to prevent backend requests during tab navigation - Add @blur event handlers for immediate path normalization feedback - Backend normalization remains as defensive fallback This ensures consistent validation behavior and fixes potential tab focus issues on the General Settings page. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/Livewire/Project/Application/General.php | 31 +++++----- .../project/application/general.blade.php | 59 +++++++++++++++---- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index ef474fb02..56d45ae19 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -606,13 +606,6 @@ public function generateDomain(string $serviceName) } } - public function updatedBaseDirectory() - { - if ($this->buildPack === 'dockercompose') { - $this->loadComposeFile(); - } - } - public function updatedIsStatic($value) { if ($value) { @@ -791,6 +784,7 @@ public function submit($showToaster = true) $oldPortsExposes = $this->application->ports_exposes; $oldIsContainerLabelEscapeEnabled = $this->application->settings->is_container_label_escape_enabled; $oldDockerComposeLocation = $this->initialDockerComposeLocation; + $oldBaseDirectory = $this->application->base_directory; // Process FQDN with intermediate variable to avoid Collection/string confusion $this->fqdn = str($this->fqdn)->replaceEnd(',', '')->trim()->toString(); @@ -821,6 +815,16 @@ public function submit($showToaster = true) return; // Stop if there are conflicts and user hasn't confirmed } + // Normalize paths BEFORE validation + if ($this->baseDirectory && $this->baseDirectory !== '/') { + $this->baseDirectory = rtrim($this->baseDirectory, '/'); + $this->application->base_directory = $this->baseDirectory; + } + if ($this->publishDirectory && $this->publishDirectory !== '/') { + $this->publishDirectory = rtrim($this->publishDirectory, '/'); + $this->application->publish_directory = $this->publishDirectory; + } + $this->application->save(); if (! $this->customLabels && $this->application->destination->server->proxyType() !== 'NONE' && ! $this->application->settings->is_container_label_readonly_enabled) { $this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n"); @@ -828,7 +832,10 @@ public function submit($showToaster = true) $this->application->save(); } - if ($this->buildPack === 'dockercompose' && $oldDockerComposeLocation !== $this->dockerComposeLocation) { + // Validate docker compose file path when base directory OR compose location changes + if ($this->buildPack === 'dockercompose' && + ($oldDockerComposeLocation !== $this->dockerComposeLocation || + $oldBaseDirectory !== $this->baseDirectory)) { $compose_return = $this->loadComposeFile(showToast: false); if ($compose_return instanceof \Livewire\Features\SupportEvents\Event) { return; @@ -855,14 +862,6 @@ public function submit($showToaster = true) $this->application->ports_exposes = $port; } } - if ($this->baseDirectory && $this->baseDirectory !== '/') { - $this->baseDirectory = rtrim($this->baseDirectory, '/'); - $this->application->base_directory = $this->baseDirectory; - } - if ($this->publishDirectory && $this->publishDirectory !== '/') { - $this->publishDirectory = rtrim($this->publishDirectory, '/'); - $this->application->publish_directory = $this->publishDirectory; - } if ($this->buildPack === 'dockercompose') { $this->application->docker_compose_domains = json_encode($this->parsedServiceDomains); if ($this->application->isDirty('docker_compose_domains')) { diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index d1a331d1a..8cf46d2f3 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -241,12 +241,32 @@ @else
@endcan -
- +
+ + wire:model.defer="dockerComposeLocation" label="Docker Compose Location" + helper="It is calculated together with the Base Directory:
{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }}" + x-model="composeLocation" @blur="normalizeComposeLocation()" />
@else -
- +
+ @if ($application->build_pack === 'dockerfile' && !$application->dockerfile) - + x-bind:disabled="!canUpdate" x-model="dockerfileLocation" @blur="normalizeDockerfileLocation()" /> @endif @if ($application->build_pack === 'dockerfile')