Commit graph

5 commits

Author SHA1 Message Date
Thorsten Bus ae42b48753 feat(songs): per-song sections + section editing; fix CCLI import bugs
Refactor lyric storage so each song owns its sections instead of sharing
global labels. Adds song_sections (per song+label) owning song_slides;
labels stay global ProPresenter group tags (name/color/macro). Arrangements
now reference sections, so editing/importing one song no longer corrupts
others that share a label name.

- New: song_sections table + migration with safe backfill; SongSection,
  SongArrangementSection models; SongSectionController (edit/add/delete
  sections, immediate persistence) wired into SongEditModal.
- Refactor writers/readers: CcliImport, ProImport, SongService,
  ArrangementController, SongController, ProExport, PDF, Translation
  (translation reset now section-scoped), CCLI pairing.
- CCLI import fixes: parse SongSelect copy-icon format (German "Vers"
  abbrev + trailing author), fill empty CTS-synced songs instead of
  blocking as duplicate, distinct label colors per section kind,
  import&edit/existing-song open the edit modal (no 404/405), teleport
  paste dialog above assign dialog, preview shows section content,
  correct SongSelect search URL, copy-icon instructions.
- Bookmarklet clicks #generalCopyLyricsButton and captures clipboard;
  serves correct host from request.
- Export: embed key-visual/background under fixed bundle-relative names.
- Tests updated for the section model; new section + isolation coverage.
2026-05-31 14:45:47 +02:00
Thorsten Bus bdbf0c65e3 refactor(php): rename SongGroup references throughout controllers/services/tests
Replace all SongGroup/SongArrangementGroup model usages with Label/SongArrangementLabel
after the schema migration to global labels. Updates 12 app files and 11 test files:

- SongService: createDefaultGroups now finds-or-creates global Labels by name
- ArrangementController: validates label_id (labels are global, no song-ownership)
- ProImportService: imports groups as Labels (firstOrCreate by name); does not
  overwrite existing label colors per spec
- ProExportService/SongPdfController/TranslationService/etc: traverse via
  arrangements -> arrangementLabels -> label -> songSlides chain
- All test factories and assertions adapted to label-based schema
2026-05-03 22:55:02 +02:00
Thorsten Bus 149389a382 fix(test): add deterministic order values in SongPdfTest
Specify explicit order values for SongGroup factories to avoid unique
constraint violations on the composite (song_id, order) key when
faker generates duplicate random values.
2026-03-02 23:02:58 +01:00
Thorsten Bus 27f8402ae8 feat: Wave 4 - Song DB Management + Finalization (T20-T24)
T20: Song DB Page
- Songs/Index.vue with search, action buttons, pagination
- Upload area for .pro files (calls T23 placeholder)
- Song-Datenbank nav link added to AuthenticatedLayout
- Tests: 9 new (44 assertions)

T21: Song DB Edit Popup
- SongEditModal.vue with metadata + ArrangementConfigurator
- Auto-save with fetch (500ms debounce for text, immediate on blur)
- Tests: 11 new (53 assertions)

T22: Song DB Translate Page
- Songs/Translate.vue with two-column editor
- URL fetch or manual paste, line-count constraints
- Group headers with colors, save marks has_translation=true
- Tests: 1 new (12 assertions)

T23: .pro File Placeholders
- ProParserNotImplementedException with HTTP 501
- ProFileController with importPro/downloadPro placeholders
- German error messages
- Tests: 5 new (7 assertions)

T24: Service Finalization + Status
- Two-step finalization with warnings (unmatched songs, missing slides)
- Download placeholder toast
- isReadyToFinalize accessor on Service model
- Tests: 11 new (30 assertions)

All tests passing: 174/174 (905 assertions)
Build: ✓ Vite production build successful
German UI: All user-facing text in German with 'Du' form
2026-03-01 20:30:07 +01:00
Thorsten Bus d75d748417 feat: T19 - Song Preview Modal + PDF Download
- SongPreviewModal.vue: Teleport modal with song text in arrangement order
  - Group headers with group.color background
  - Side-by-side translations when use_translation=true
  - Copyright footer from song metadata
  - Close button + click-outside/Escape dismiss
  - PDF download button

- SongPdfController.php: PDF generation endpoint
  - GET /songs/{song}/arrangements/{arrangement}/pdf
  - Uses barryvdh/laravel-dompdf with DejaVu Sans font
  - Old-school CSS only (NO Tailwind)
  - Handles German umlauts correctly

- resources/views/pdf/song.blade.php: PDF template
  - Title header, groups with colored headers, slide text, copyright footer
  - Includes translation text when present
  - Simple CSS: font-family, color, background-color, margin, padding

- Tests: 9 new (25 assertions)
  - PDF content type verification
  - Filename includes song title
  - Groups in correct arrangement order
  - Translation text included when present
  - Copyright footer present
  - German umlauts render correctly
  - Auth guard
  - 404 when arrangement doesn't belong to song
  - Empty arrangement handling

All tests passing: 133/133 (728 assertions)
Build: ✓ Vite production build successful
Fix: Removed duplicate content from SongPdfTest.php (parse error)
2026-03-01 20:15:02 +01:00