mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-28 16:45:32 +00:00
Schellfilter; bugfixes; Tagewerk; Anfang Ort Controller
This commit is contained in:
95
viewmodels/place_view.go
Normal file
95
viewmodels/place_view.go
Normal file
@@ -0,0 +1,95 @@
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
referencedPlaces := make(map[string]bool)
|
||||
for _, piece := range lib.Pieces.Array {
|
||||
for _, placeRef := range piece.PlaceRefs {
|
||||
referencedPlaces[placeRef.Ref] = true
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user