fix(service): avoid storing inherited ports as overrides
This commit is contained in:
parent
0134401f7c
commit
36befcfecd
4 changed files with 27 additions and 7 deletions
|
|
@ -5,3 +5,7 @@ ## Alpine x-transition + tw-animate-css exit animations flash at the end
|
|||
- Cause: `animate-out` keyframes default to `animation-fill-mode: none`. The element snaps back to its natural state when the keyframe ends. Alpine hides the element (display: none) only after its own timer (read from `transition-duration`), which starts ~2 rAF later than the animation. The gap shows the element at full opacity.
|
||||
- Rule: every `x-transition:leave` that uses tw-animate-css `animate-out` MUST also include `fill-mode-forwards`.
|
||||
- Rule: when a user reports UI flicker, check ALL layers of the animation stack (state reset timing, spinner flash, keyframe fill mode, focus restore) before you report the fix as complete. My first fix covered state reset and spinner only; the fill-mode snap was the visible one.
|
||||
|
||||
## Displayed defaults must not become stored overrides
|
||||
- When an edit form shows an inherited or computed default, trace an unchanged save and a related-field edit through persistence.
|
||||
- Preserve the inherited state when the displayed value still equals the computed default; store an override only when the user selects a different value.
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -40,6 +40,7 @@ CHANGELOG.md
|
|||
/.workspaces
|
||||
/.superpowers/
|
||||
/docs/superpowers/plans/
|
||||
/.ai/todo.md
|
||||
tests/Browser/Screenshots
|
||||
tests/v4/Browser/Screenshots
|
||||
ref
|
||||
|
|
|
|||
|
|
@ -1180,11 +1180,9 @@ public function startEdit(int $index): void
|
|||
$this->editingIndex = $index;
|
||||
$this->editingDomain = $this->domainRows[$index]['url'];
|
||||
$this->editingDomainParts = DomainUrlParts::split($this->editingDomain);
|
||||
$app = $this->findServiceApp((int) $this->domainRows[$index]['service_application_id']);
|
||||
$canonical = DomainPortOverrides::withoutPort($this->editingDomain);
|
||||
$savedPort = ($app?->domain_port_overrides ?? [])[$canonical] ?? null;
|
||||
if (filled($savedPort)) {
|
||||
$this->editingDomainParts['port'] = (string) $savedPort;
|
||||
$internalPort = $this->domainRows[$index]['internal_port'] ?? null;
|
||||
if (filled($internalPort)) {
|
||||
$this->editingDomainParts['port'] = (string) $internalPort;
|
||||
}
|
||||
$this->editingDomainPartsChanged = false;
|
||||
$this->editingServiceApplicationId = (int) $this->domainRows[$index]['service_application_id'];
|
||||
|
|
@ -1219,8 +1217,16 @@ public function updateDomain(): void
|
|||
return;
|
||||
}
|
||||
|
||||
if ($this->editingDomainPartsChanged || filled($this->editingDomainParts['host'] ?? null)) {
|
||||
$this->editingDomain = DomainUrlParts::compose(...$this->editingDomainParts);
|
||||
$editingDomainParts = $this->editingDomainParts;
|
||||
$editingRow = $this->domainRows[$this->editingIndex];
|
||||
if (
|
||||
! ($editingRow['has_port_override'] ?? false)
|
||||
&& (string) ($editingDomainParts['port'] ?? '') === (string) ($editingRow['internal_port'] ?? '')
|
||||
) {
|
||||
$editingDomainParts['port'] = '';
|
||||
}
|
||||
if ($this->editingDomainPartsChanged || filled($editingDomainParts['host'] ?? null)) {
|
||||
$this->editingDomain = DomainUrlParts::compose(...$editingDomainParts);
|
||||
}
|
||||
$this->validateOnly('editingDomain');
|
||||
|
||||
|
|
|
|||
|
|
@ -907,9 +907,18 @@
|
|||
Livewire::test(Domains::class, ['service' => $this->service->fresh(['applications', 'server'])])
|
||||
->assertSet('domainRows.0.internal_port', 3000)
|
||||
->assertSet('domainRows.0.has_port_override', false)
|
||||
->set('dnsValidationEnabled', false)
|
||||
->call('startEdit', 0)
|
||||
->assertSet('editingDomainParts.port', '3000')
|
||||
->call('updateDomain')
|
||||
->assertHasNoErrors()
|
||||
->assertSee('Internal port 3000')
|
||||
->assertSee('Inherited from the Coolify service port', false)
|
||||
->assertDontSee('No internal port');
|
||||
|
||||
expect($this->apiApp->fresh())
|
||||
->fqdn->toBe('https://api.example.com')
|
||||
->domain_port_overrides->toBeNull();
|
||||
});
|
||||
|
||||
it('shows a custom internal port badge for a service domain override', function () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue