5.6 KiB
Lied bearbeiten
Route
/songs/:songId/edit
Die Route ist im Songs-Modul als path: ':songId/edit' definiert. Der übergeordnete /songs-Eintrag im App-Router verlangt Authentifizierung und die Rolle user. Die Edit-Route selbst definiert keinen zusätzlichen canActivate-Guard, verwendet aber EditSongGuard als canDeactivate-Guard.
Zweck
Die Bearbeitungsseite bündelt die Pflege eines Songs. Sie erlaubt das Bearbeiten von Inhalt, musikalischen Angaben, rechtlichen Metadaten und Attributen, verwaltet Anhänge und zeigt die letzte Änderungshistorie. Sie ist die Anschlussseite nach dem Anlegen eines neuen Songs und die zentrale Stelle für spätere Songpflege.
Aufbau
EditComponent ist eine Container-Komponente innerhalb eines app-page-frame ohne Menü. Sie rendert drei Teilbereiche:
EditSongComponent: Formular für Songtext, Stammdaten und Rechtsinformationen.EditFileComponent: Upload und Verwaltung angehängter Dateien.HistoryComponent: Anzeige der letzten gespeicherten Änderungen.
Der Container hält über ViewChild eine Referenz auf EditSongComponent, damit der EditSongGuard beim Verlassen der Route ungespeicherte Formularänderungen prüfen kann.
Datenquellen
SongService.read$(songId)lädt den Song für Formular und Historie.EditService.createSongForm(song)erzeugt das reaktive Formular aus dem geladenen Song.SongService.update$(songId, data)speichert Änderungen und ergänzt einen Eintrag insong.edits.UserService.currentUser()liefert beim Speichern den Namen des aktuellen Benutzers für die Änderungshistorie.FileDataService.read$(songId)liest vorhandene Anhänge aussongs/{songId}/files.UploadServiceschreibt neue Dateien nach Firebase Storage unter/attachments/{songId}und speichert die Metadaten anschließend in Firestore.FileServicelöst Download-URLs auf und löscht Anhänge aus Storage sowie aus der Firestore-Subcollection.
Wichtige UI-Elemente
Der Song-Editor zeigt eine Card mit der Überschrift {Nummer} bearbeiten und einem Zurück-Link zur Detailseite. Das Formular enthält:
- Titel
- Typ
- Tonart
- Tempo
- Status
- Songtext
- Kommentar
- Attribute als Chips
- rechtlicher Status
- Rechteinhaber
- Rechteinhaber-ID mit CCLI-Link, wenn der Rechteinhaber CCLI ist
- Künstler
- Verlag / Copyright
- Nutzungsbedingungen
- abweichende Quelle
Während das Songtextfeld fokussiert ist, zeigt die Seite eine Vorschau über app-song-text sowie Bearbeitungshinweise zum Aufbau von Strophen, Refrain, Bridge und Akkordzeilen. Akkordvalidierungsfehler werden unter Akkordschreibweise korrigieren mit Zeile, Meldung, betroffenem Token und optionalem Vorschlag angezeigt.
Der Dateibereich zeigt eine Upload-Auswahl, einen Upload-Button, während des Uploads einen Fortschrittsbalken und die vorhandenen Anhänge. Jeder Anhang kann geöffnet und über ein Papierkorb-Symbol gelöscht werden.
Die Historie zeigt vorhandene song.edits mit Benutzername und Datum.
Aktionen
Speichern: validiert das Formular, speichert die Rohwerte überSongService.update$(), markiert das Formular als unverändert und navigiert nach/songs/:songId.- Attribut hinzufügen: Eingabe im Chip-Feld wird bei Enter, Komma oder Blur an die semikolongetrennte
flags-Liste angehängt. - Attribut entfernen: entfernt den Chip und schreibt die verbleibenden Attribute zurück in
flags. - Datei auswählen: übernimmt die aktuelle Dateiauswahl aus dem File-Input.
- Datei hochladen: lädt die erste ausgewählte Datei nach Firebase Storage und speichert danach die Dateimetadaten.
- Datei löschen: entfernt die Datei aus Firebase Storage und löscht den Firestore-Metadatensatz.
- Seite verlassen mit ungespeicherten Änderungen: öffnet einen Speicherdialog; bei Bestätigung wird vor der Navigation gespeichert.
Berechtigungen
Der Zugriff auf das Songs-Modul erfordert Authentifizierung und die Rolle user. Die Edit-Route selbst erzwingt in songs-routing.module.ts keine contributor-Rolle. Der Einstieg aus der Detailseite ist allerdings nur für contributor sichtbar, weil der Button Bearbeiten rollenabhängig gerendert wird.
Für die Dokumentation ist deshalb wichtig: Die UI versteckt den regulären Einstieg für Nicht-Contributors, die Route selbst enthält aber keinen zusätzlichen Aktivierungs-Guard. Falls direkte URL-Aufrufe ebenfalls verhindert werden sollen, müsste die Route analog zu /songs/new mit einem RoleGuard erweitert werden.
Relevante technische Hinweise
Die Akkordvalidierung wird bei jeder Änderung des Songtextes aktualisiert. TextRenderingService.validateChordNotation() erkennt unter anderem alternative Schreibweisen wie is/es, falsche Dur/Moll-Großschreibung, nicht normalisierte Suffixe, unbekannte Akkordtokens und Tabulatoren in Akkordzeilen. Validierungsfehler werden als Formularfehler chordNotation am Text-Control gesetzt; dadurch ist der Speichern-Button deaktiviert, solange der Text ungültig ist.
SongService.update$() liest vor dem Speichern den aktuellen Song, hängt einen neuen Historieneintrag mit Benutzername und Timestamp.now() an und schreibt anschließend die Änderungen. Dadurch wird die Historie nur bei Speichervorgängen über diesen Service erweitert.
Der Upload-Service ignoriert Upload-Fehler im aktuellen Stand bewusst im Error-Callback. Die UI zeigt Fortschritt und erfolgreiche Metadaten danach über die Dateiliste, aber keine eigene Fehlermeldung.
Der EditSongGuard schützt nur vor Navigation aus dem Angular-Router heraus. Er fragt EditSongComponent.askForSave(nextState) ab und navigiert nach dem Dialog selbst weiter. Bei nicht dirty Formularen wird die Navigation direkt erlaubt.