feat(12-02): replace config-page library section with full library management UI

- Add library list with name, path, track count per library
- Add Library button opens folder picker, auto-creates library
- Inline rename with Enter/Escape via overflow menu
- Removal confirmation dialog with real impact counts (tracks, playlists, queue)
- Toast notification with removal summary after library removal
- Add GetAllLibrariesWithTrackCounts + Info type to backend Library struct
- Add Wails binding stubs for AddLibrary, RenameLibrary, RemoveLibrary, GetRemovalImpact
- Add Info, RemovalImpact, RemovalSummary types to models.ts
- Remove old single-directory library config UI (GetLibraryDirectory/SetLibraryDirectory)
This commit is contained in:
2026-03-12 19:50:59 -04:00
parent 27c773b3d0
commit ffc5d9639c
5 changed files with 575 additions and 59 deletions
+39
View File
@@ -443,3 +443,42 @@ func (l *Library) GetAllGenresWithCounts() (
return genres, nil
}
// Info contains library metadata enriched with track count
// for the frontend settings UI.
type Info struct {
ID int64 `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
TrackCount int64 `json:"trackCount"`
}
// GetAllLibrariesWithTrackCounts returns all libraries with their
// audio file counts. Typically 1-5 libraries so the loop is trivial.
func (l *Library) GetAllLibrariesWithTrackCounts() ([]Info, error) {
libs, err := l.db.Queries.GetAllLibraries(l.ctx)
if err != nil {
return nil, fmt.Errorf("could not get libraries: %w", err)
}
result := make([]Info, 0, len(libs))
for _, lib := range libs {
count, countErr := l.db.Queries.CountAudioFilesByLibrary(l.ctx, lib.ID)
if countErr != nil {
l.logger.Error("could not count tracks for library",
"libraryID", lib.ID, "error", countErr)
count = 0
}
result = append(result, Info{
ID: lib.ID,
Name: lib.Name,
Path: lib.Path,
TrackCount: count,
})
}
return result, nil
}