diff --git a/frontend/messages/de.json b/frontend/messages/de.json index e1d7066f..997a8dda 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -1194,12 +1194,11 @@ "journey_intro_save_hint": "Wird mit 'Speichern' gesichert.", "journey_already_added": "Bereits enthalten", "journey_note_aria_label": "Kuratoren-Notiz für {title}", - "journey_drag_aria_label": "Reihenfolge von '{title}' ändern", "journey_move_up": "'{title}' nach oben verschieben", "journey_move_down": "'{title}' nach unten verschieben", "journey_note_error": "Notiz konnte nicht gespeichert werden", "journey_item_moved": "Eintrag {position} von {total} — nach Position {newPosition} verschoben", - "journey_remove_item_aria": "Eintrag entfernen", + "journey_remove_item_aria": "'{title}' entfernen", "journey_remove_confirm": "Wirklich entfernen?", "journey_remove_confirm_yes": "Bestätigen", "journey_remove_confirm_cancel": "Abbrechen", @@ -1215,6 +1214,8 @@ "error_journey_note_too_long": "Die Notiz ist zu lang (maximal 2000 Zeichen).", "error_geschichte_title_too_long": "Der Titel ist zu lang (maximal 255 Zeichen).", "error_geschichte_intro_too_long": "Die Einleitung ist zu lang (maximal 4000 Zeichen).", + "error_geschichte_title_too_long": "Der Titel ist zu lang (maximal 255 Zeichen).", + "error_geschichte_intro_too_long": "Die Einleitung ist zu lang (maximal 4000 Zeichen).", "error_journey_document_already_added": "Dieser Brief ist bereits in der Lesereise enthalten.", "error_geschichte_type_immutable": "Der Typ einer Geschichte kann nach der Erstellung nicht mehr geändert werden." } diff --git a/frontend/messages/en.json b/frontend/messages/en.json index fb443602..07a5a503 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1194,12 +1194,11 @@ "journey_intro_save_hint": "Saved when you click 'Save'.", "journey_already_added": "Already included", "journey_note_aria_label": "Curator note for {title}", - "journey_drag_aria_label": "Change order of '{title}'", "journey_move_up": "Move '{title}' up", "journey_move_down": "Move '{title}' down", "journey_note_error": "Could not save note", "journey_item_moved": "Entry {position} of {total} — moved to position {newPosition}", - "journey_remove_item_aria": "Remove item", + "journey_remove_item_aria": "Remove '{title}'", "journey_remove_confirm": "Really remove?", "journey_remove_confirm_yes": "Confirm", "journey_remove_confirm_cancel": "Cancel", @@ -1215,6 +1214,8 @@ "error_journey_note_too_long": "The note is too long (maximum 2000 characters).", "error_geschichte_title_too_long": "The title is too long (maximum 255 characters).", "error_geschichte_intro_too_long": "The introduction is too long (maximum 4000 characters).", + "error_geschichte_title_too_long": "The title is too long (maximum 255 characters).", + "error_geschichte_intro_too_long": "The introduction is too long (maximum 4000 characters).", "error_journey_document_already_added": "This letter is already included in the reading journey.", "error_geschichte_type_immutable": "The type of a story cannot be changed after creation." } diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 4056fbe0..de4beda4 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -1194,12 +1194,11 @@ "journey_intro_save_hint": "Se guarda al hacer clic en 'Guardar'.", "journey_already_added": "Ya incluido", "journey_note_aria_label": "Nota del curador para {title}", - "journey_drag_aria_label": "Cambiar el orden de '{title}'", "journey_move_up": "Subir '{title}'", "journey_move_down": "Bajar '{title}'", "journey_note_error": "No se pudo guardar la nota", "journey_item_moved": "Entrada {position} de {total} — movida a la posición {newPosition}", - "journey_remove_item_aria": "Eliminar entrada", + "journey_remove_item_aria": "Eliminar '{title}'", "journey_remove_confirm": "¿Realmente eliminar?", "journey_remove_confirm_yes": "Confirmar", "journey_remove_confirm_cancel": "Cancelar", @@ -1215,6 +1214,8 @@ "error_journey_note_too_long": "La nota es demasiado larga (máximo 2000 caracteres).", "error_geschichte_title_too_long": "El título es demasiado largo (máximo 255 caracteres).", "error_geschichte_intro_too_long": "La introducción es demasiado larga (máximo 4000 caracteres).", + "error_geschichte_title_too_long": "El título es demasiado largo (máximo 255 caracteres).", + "error_geschichte_intro_too_long": "La introducción es demasiado larga (máximo 4000 caracteres).", "error_journey_document_already_added": "Esta carta ya está incluida en el viaje de lectura.", "error_geschichte_type_immutable": "El tipo de una historia no se puede cambiar después de su creación." } diff --git a/frontend/src/lib/geschichte/JourneyEditor.svelte b/frontend/src/lib/geschichte/JourneyEditor.svelte index 85e07f37..82ff80d7 100644 --- a/frontend/src/lib/geschichte/JourneyEditor.svelte +++ b/frontend/src/lib/geschichte/JourneyEditor.svelte @@ -18,6 +18,7 @@ type JourneyItemView = components['schemas']['JourneyItemView']; interface Props { geschichte: GeschichteView; + /** Must reject when the save failed — the editor keeps its dirty state then. */ onSubmit: (payload: { title: string; body: string; @@ -203,7 +204,9 @@ async function handleNotePatch(itemId: string, note: string | null) { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ note: note }) }); - if (!res.ok) throw new Error('note patch failed'); + // Carry the backend error code's message so the row can show the specific + // reason (e.g. JOURNEY_NOTE_TOO_LONG) instead of a generic alert. + if (!res.ok) throw new Error(await failureMessage(res)); const updated: JourneyItemView = await res.json(); items = items.map((i) => (i.id === itemId ? updated : i)); } @@ -266,13 +269,16 @@ async function save(nextStatus: 'DRAFT' | 'PUBLISHED') { unsaved.markDirty()} onblur={() => (titleTouched = true)} placeholder={m.geschichte_editor_title_placeholder()} aria-label={m.journey_title_aria_label()} aria-invalid={showTitleError} aria-describedby={showTitleError ? 'journey-title-error' : undefined} - class="block w-full rounded border border-line bg-surface px-3 py-3 font-serif text-2xl font-bold text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring" + class="block w-full rounded border {showTitleError + ? 'border-danger' + : 'border-line'} bg-surface px-3 py-3 font-serif text-2xl font-bold text-ink placeholder:text-ink-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring" /> {#if showTitleError}