mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-28 16:45:32 +00:00
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package viewmodels
|
|
|
|
import (
|
|
"maps"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/Theodor-Springmann-Stiftung/kgpz_web/xmlmodels"
|
|
)
|
|
|
|
// PlacesListView represents the data for the places overview
|
|
type PlacesListView struct {
|
|
Search string
|
|
AvailableLetters []string
|
|
Places map[string]xmlmodels.Place
|
|
Sorted []string
|
|
SelectedPlace *PlaceDetailView
|
|
TotalPiecesWithPlaces int
|
|
}
|
|
|
|
// PlaceDetailView represents a specific place with its associated pieces
|
|
type PlaceDetailView struct {
|
|
Place xmlmodels.Place
|
|
Pieces []xmlmodels.Piece
|
|
}
|
|
|
|
// PlacesView returns places data for the overview page
|
|
func PlacesView(placeID string, lib *xmlmodels.Library) *PlacesListView {
|
|
res := PlacesListView{Search: placeID, Places: make(map[string]xmlmodels.Place)}
|
|
av := make(map[string]bool)
|
|
|
|
// Get all places that are referenced in pieces and count total pieces with places
|
|
referencedPlaces := make(map[string]bool)
|
|
totalPiecesWithPlaces := 0
|
|
|
|
for _, piece := range lib.Pieces.Array {
|
|
hasPlace := false
|
|
for _, placeRef := range piece.PlaceRefs {
|
|
referencedPlaces[placeRef.Ref] = true
|
|
hasPlace = true
|
|
}
|
|
if hasPlace {
|
|
totalPiecesWithPlaces++
|
|
}
|
|
}
|
|
|
|
// Build available letters and places list
|
|
for _, place := range lib.Places.Array {
|
|
// Only include places that are actually referenced in pieces
|
|
if referencedPlaces[place.ID] {
|
|
av[strings.ToUpper(place.ID[:1])] = true
|
|
res.Sorted = append(res.Sorted, place.ID)
|
|
res.Places[place.ID] = place
|
|
}
|
|
}
|
|
|
|
// If a specific place is requested, get its details
|
|
if placeID != "" && len(placeID) > 1 {
|
|
if place, exists := res.Places[placeID]; exists {
|
|
res.SelectedPlace = GetPlaceDetail(place, lib)
|
|
}
|
|
}
|
|
|
|
res.AvailableLetters = slices.Collect(maps.Keys(av))
|
|
slices.Sort(res.AvailableLetters)
|
|
slices.Sort(res.Sorted)
|
|
res.TotalPiecesWithPlaces = totalPiecesWithPlaces
|
|
|
|
return &res
|
|
}
|
|
|
|
// GetPlaceDetail returns detailed information for a specific place including associated pieces
|
|
func GetPlaceDetail(place xmlmodels.Place, lib *xmlmodels.Library) *PlaceDetailView {
|
|
detail := &PlaceDetailView{
|
|
Place: place,
|
|
Pieces: make([]xmlmodels.Piece, 0),
|
|
}
|
|
|
|
// Find all pieces that reference this place
|
|
for _, piece := range lib.Pieces.Array {
|
|
for _, placeRef := range piece.PlaceRefs {
|
|
if placeRef.Ref == place.ID {
|
|
detail.Pieces = append(detail.Pieces, piece)
|
|
break // Don't add the same piece multiple times
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sort pieces by title for consistent display
|
|
slices.SortFunc(detail.Pieces, func(a, b xmlmodels.Piece) int {
|
|
// Get first title from each piece, or use empty string if no titles
|
|
titleA := ""
|
|
if len(a.Title) > 0 {
|
|
titleA = a.Title[0]
|
|
}
|
|
titleB := ""
|
|
if len(b.Title) > 0 {
|
|
titleB = b.Title[0]
|
|
}
|
|
return strings.Compare(strings.ToLower(titleA), strings.ToLower(titleB))
|
|
})
|
|
|
|
return detail
|
|
} |