fix(cms): stable bottom bar and self-save no longer trips the 409 lock
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions

MITHOME-68: the optimistic-lock fingerprint was frozen at page load, so the
user's own second save 409'd. /save now returns the hash of the written
content and the client refreshes CONTENT_HASH on success — 409 only fires
for genuine external changes (deploy, other tab, restore). Also: successful
logins no longer consume the auth failure budget (only failed attempts do).

MITHOME-69: bottom bar items no longer shift while saving/publishing — the
status message occupies a constant flex slot (visibility instead of
display), the publish button locks its width while running and restores
its env-specific label, auto margins removed. Layout guard test added.

Test markers are now run-unique so a crashed run can never poison the
next one's expectations.
This commit is contained in:
Do Siki
2026-08-19 14:04:49 +02:00
parent 41a2259ede
commit 88383049d5
6 changed files with 126 additions and 20 deletions
+14 -6
View File
@@ -258,14 +258,17 @@ async function save() {
const json = await res.json();
const status = document.getElementById('saveStatus');
if (json.ok) {
// Refresh the optimistic-lock fingerprint with the server-computed hash of
// the saved content, so the user's own subsequent saves don't trip 409.
if (json.contentHash) CONTENT_HASH = json.contentHash;
status.textContent = '✅ Mentve!';
status.style.color = '#10b981';
} else {
status.textContent = '❌ Hiba: ' + json.error;
status.style.color = '#f87171';
}
status.style.display = 'inline';
setTimeout(() => status.style.display = 'none', 3000);
status.style.visibility = 'visible';
setTimeout(() => status.style.visibility = 'hidden', 3000);
}
async function publish() {
@@ -274,7 +277,11 @@ async function publish() {
// Save first
await save();
// WHY: lock the button width and remember the label so the running state
// neither resizes the bottom bar nor permanently swaps the env-specific label.
const originalLabel = btn.textContent;
btn.style.minWidth = btn.offsetWidth + 'px';
btn.textContent = '⏳ Élesítés folyamatban...';
btn.disabled = true;
@@ -295,10 +302,11 @@ async function publish() {
status.style.color = '#f87171';
}
btn.textContent = '🚀 Publikálás & Élesítés';
btn.textContent = originalLabel;
btn.style.minWidth = '';
btn.disabled = false;
status.style.display = 'inline';
setTimeout(() => status.style.display = 'none', 5000);
status.style.visibility = 'visible';
setTimeout(() => status.style.visibility = 'hidden', 5000);
}
async function logout() {