Fill to capacity works

This commit is contained in:
2025-12-23 19:00:39 +01:00
parent e00355f787
commit 4782fd3f85
2 changed files with 85 additions and 7 deletions
+40 -3
View File
@@ -201,8 +201,8 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
tracker, exists := listTrackers[trackerKey] tracker, exists := listTrackers[trackerKey]
if !exists { if !exists {
// Block has no data, add empty slice // Block has no data, fill with empty items up to MAX
pageData[block.Name] = p.createEmptySlice(block.ListType) pageData[block.Name] = p.createEmptySliceWithCapacity(block.ListType, block.MaxItems)
continue continue
} }
@@ -213,8 +213,9 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
itemsToTake = remaining itemsToTake = remaining
} }
// Extract slice for this block // Extract slice for this block and fill to capacity
blockItems := p.extractSlice(tracker.items, tracker.currentIdx, itemsToTake) blockItems := p.extractSlice(tracker.items, tracker.currentIdx, itemsToTake)
blockItems = p.fillSliceToCapacity(blockItems, block.MaxItems)
pageData[block.Name] = blockItems pageData[block.Name] = blockItems
tracker.currentIdx += itemsToTake tracker.currentIdx += itemsToTake
} }
@@ -495,6 +496,42 @@ func (p *Paginator) createEmptySlice(listType string) interface{} {
} }
} }
// createEmptySliceWithCapacity creates an empty slice filled to capacity with zero values
func (p *Paginator) createEmptySliceWithCapacity(listType string, capacity int) interface{} {
switch listType {
case "skills":
return FillToCapacity([]SkillViewModel{}, capacity)
case "weapons":
return FillToCapacity([]WeaponViewModel{}, capacity)
case "spells":
return FillToCapacity([]SpellViewModel{}, capacity)
case "equipment":
return FillToCapacity([]EquipmentViewModel{}, capacity)
case "magicItems":
return FillToCapacity([]MagicItemViewModel{}, capacity)
default:
return []interface{}{}
}
}
// fillSliceToCapacity fills an existing slice to the specified capacity
func (p *Paginator) fillSliceToCapacity(items interface{}, capacity int) interface{} {
switch v := items.(type) {
case []SkillViewModel:
return FillToCapacity(v, capacity)
case []WeaponViewModel:
return FillToCapacity(v, capacity)
case []SpellViewModel:
return FillToCapacity(v, capacity)
case []EquipmentViewModel:
return FillToCapacity(v, capacity)
case []MagicItemViewModel:
return FillToCapacity(v, capacity)
default:
return items
}
}
// CalculatePagesNeeded calculates how many pages are needed for given data // CalculatePagesNeeded calculates how many pages are needed for given data
func (p *Paginator) CalculatePagesNeeded(templateName string, listType string, itemCount int) (int, error) { func (p *Paginator) CalculatePagesNeeded(templateName string, listType string, itemCount int) (int, error) {
template := p.findTemplate(templateName) template := p.findTemplate(templateName)
+45 -4
View File
@@ -5,6 +5,39 @@ import (
"testing" "testing"
) )
// Helper function to count non-empty skills (skills with a name)
func countNonEmptySkills(skills []SkillViewModel) int {
count := 0
for _, skill := range skills {
if skill.Name != "" {
count++
}
}
return count
}
// Helper function to count non-empty weapons
func countNonEmptyWeapons(weapons []WeaponViewModel) int {
count := 0
for _, weapon := range weapons {
if weapon.Name != "" {
count++
}
}
return count
}
// Helper function to count non-empty spells
func countNonEmptySpells(spells []SpellViewModel) int {
count := 0
for _, spell := range spells {
if spell.Name != "" {
count++
}
}
return count
}
// TestPaginateMultiList_SingleListType tests pagination with a single list type (skills only) // TestPaginateMultiList_SingleListType tests pagination with a single list type (skills only)
func TestPaginateMultiList_SingleListType(t *testing.T) { func TestPaginateMultiList_SingleListType(t *testing.T) {
// Arrange // Arrange
@@ -46,7 +79,7 @@ func TestPaginateMultiList_SingleListType(t *testing.T) {
for _, blockName := range skillBlocks { for _, blockName := range skillBlocks {
if data, exists := page.Data[blockName]; exists { if data, exists := page.Data[blockName]; exists {
if skillsList, ok := data.([]SkillViewModel); ok { if skillsList, ok := data.([]SkillViewModel); ok {
totalSkills += len(skillsList) totalSkills += countNonEmptySkills(skillsList)
} }
} }
} }
@@ -105,9 +138,9 @@ func TestPaginateMultiList_MultipleListTypes(t *testing.T) {
for _, data := range dist.Data { for _, data := range dist.Data {
switch v := data.(type) { switch v := data.(type) {
case []SkillViewModel: case []SkillViewModel:
totalSkills += len(v) totalSkills += countNonEmptySkills(v)
case []WeaponViewModel: case []WeaponViewModel:
totalWeapons += len(v) totalWeapons += countNonEmptyWeapons(v)
} }
} }
} }
@@ -169,7 +202,7 @@ func TestPaginateMultiList_WithOverflow(t *testing.T) {
if skillsList, ok := data.([]SkillViewModel); ok && if skillsList, ok := data.([]SkillViewModel); ok &&
(blockName == "skills_column1" || blockName == "skills_column2" || (blockName == "skills_column1" || blockName == "skills_column2" ||
blockName == "skills_column3" || blockName == "skills_column4") { blockName == "skills_column3" || blockName == "skills_column4") {
totalSkills += len(skillsList) totalSkills += countNonEmptySkills(skillsList)
} }
} }
} }
@@ -240,6 +273,10 @@ func TestPaginateMultiList_WithFilters(t *testing.T) {
if learnedData, ok := page.Data["skills_learned"]; ok { if learnedData, ok := page.Data["skills_learned"]; ok {
learned := learnedData.([]SkillViewModel) learned := learnedData.([]SkillViewModel)
for _, skill := range learned { for _, skill := range learned {
// Skip empty items (padding)
if skill.Name == "" {
continue
}
if !skill.IsLearned { if !skill.IsLearned {
t.Errorf("Found unlearned skill '%s' in learned block", skill.Name) t.Errorf("Found unlearned skill '%s' in learned block", skill.Name)
} }
@@ -249,6 +286,10 @@ func TestPaginateMultiList_WithFilters(t *testing.T) {
if languageData, ok := page.Data["skills_languages"]; ok { if languageData, ok := page.Data["skills_languages"]; ok {
languages := languageData.([]SkillViewModel) languages := languageData.([]SkillViewModel)
for _, skill := range languages { for _, skill := range languages {
// Skip empty items (padding)
if skill.Name == "" {
continue
}
if skill.Category != "Sprache" { if skill.Category != "Sprache" {
t.Errorf("Found non-language skill '%s' in language block", skill.Name) t.Errorf("Found non-language skill '%s' in language block", skill.Name)
} }