fix(community): Label-ID im Veröffentlichen-Dialog, Status nie in „lädt“, Nachprüfung robust

Die Überschrift des Dialogs hatte dieselbe ID wie das Titelfeld (publish-title), das Label des
Pflichtfelds zeigte damit auf die Überschrift; jetzt publish-heading. Schließt der Browser den Dialog
mitten im Senden, wird er wieder geöffnet statt als abgebrochen aufgelöst. Die Status-Abfrage der Seite
wird bei einer lokalen Änderung während der Anfrage wiederholt (nie in „lädt“ hängen), die Nachprüfung nach
offenem Ausgang ist eine eigene Abfrage. Der Löschen-Dialog nennt bei unbekanntem Status einen allgemeinen
Hinweis und sagt, dass sich eine Veröffentlichung nur auf der Community-Seite zurückziehen lässt.
publishCard heißt lokal publishWithCheck.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-04 15:56:21 +00:00
1 parent f6b9ee61f4
commit 87b71ec71f
4 files changed
+216 -33

No files matched your search

+24 -3
View File
@@ -151,8 +151,9 @@ export function publishDialog(opts: PublishDialogOptions): Promise<PublishOutcom
const form = el('form', { class: 'report-form', novalidate: true }, intro, fields, errorEl, statusEl, actions);
const dialog = el(
'dialog',
{ class: 'report-dialog publish-dialog', 'aria-labelledby': 'publish-title' },
el('div', { class: 'report-card' }, el('h2', { id: 'publish-title', class: 'report-title' }, 'Karte veröffentlichen'), form),
{ class: 'report-dialog publish-dialog', 'aria-labelledby': 'publish-heading' },
// Eigene ID für die Überschrift: `publish-title` gehört dem Titelfeld (`publish-<name>`), sonst zeigt sein Label auf die Überschrift.
el('div', { class: 'report-card' }, el('h2', { id: 'publish-heading', class: 'report-title' }, 'Karte veröffentlichen'), form),
);
const finish = () => {
@@ -165,6 +166,17 @@ export function publishDialog(opts: PublishDialogOptions): Promise<PublishOutcom
resolve(outcome);
};
/** Öffnet den Dialog wieder, falls ihn der Browser geschlossen hat (Esc trotz verhindertem `cancel`). */
function reopen(): boolean {
if (dialog.open) return true;
try {
dialog.showModal();
return true;
} catch {
return false;
}
}
function setBusy(value: boolean): void {
busy = value;
form.setAttribute('aria-busy', String(value));
@@ -214,11 +226,13 @@ export function publishDialog(opts: PublishDialogOptions): Promise<PublishOutcom
if (closed) return;
if (isAlreadyPublished(err)) {
setBusy(false);
reopen();
showAlready();
return;
}
setBusy(false);
errorEl.textContent = publishFailureText(err);
reopen(); // war der Dialog zwischendurch zu, soll der Fehler zu sehen sein
return;
}
if (closed) return;
@@ -236,7 +250,14 @@ export function publishDialog(opts: PublishDialogOptions): Promise<PublishOutcom
dialog.addEventListener('cancel', (event) => {
if (busy) event.preventDefault();
});
dialog.addEventListener('close', finish);
// Schließt der Browser den Dialog trotzdem mitten im Senden, wird er wieder geöffnet; aufgelöst wird erst mit dem echten Ergebnis.
dialog.addEventListener('close', () => {
if (busy && !closed) {
reopen();
return;
}
finish();
});
// Hintergrund = Klick auf das <dialog> selbst (die Karte füllt es ganz aus); Drücken und Loslassen müssen beide dort sein,
// sonst schließt ein Textmarkieren, das außerhalb endet, den Dialog.
let pressedOnBackdrop = false;