Now it seems Skill distribution works as expected

This commit is contained in:
2025-12-24 07:32:38 +01:00
parent 0bae6b4b40
commit 3f0cea82b5
6 changed files with 83 additions and 48 deletions
+61 -40
View File
@@ -120,46 +120,55 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
// Track by "listType:filter" to avoid duplicates // Track by "listType:filter" to avoid duplicates
listTrackers := make(map[string]*listTracker) listTrackers := make(map[string]*listTracker)
// Scan both base template and continuation template to find all unique listType:filter combinations
templatesToScan := []*TemplateMetadata{template}
continuationName := GenerateContinuationTemplateName(templateName, 2)
if contTemplate := p.findTemplate(continuationName); contTemplate != nil {
templatesToScan = append(templatesToScan, contTemplate)
}
// First pass: create filtered lists for each unique listType+filter combination // First pass: create filtered lists for each unique listType+filter combination
for _, block := range template.Blocks { for _, tmpl := range templatesToScan {
// Get the source data based on block's ListType for _, block := range tmpl.Blocks {
var sourceData interface{} // Get the source data based on block's ListType
switch block.ListType { var sourceData interface{}
case "skills": switch block.ListType {
sourceData = dataMap["skills"] case "skills":
case "weapons": sourceData = dataMap["skills"]
sourceData = dataMap["weapons"] case "weapons":
case "spells": sourceData = dataMap["weapons"]
sourceData = dataMap["spells"] case "spells":
case "equipment": sourceData = dataMap["spells"]
sourceData = dataMap["equipment"] case "equipment":
case "magicItems": sourceData = dataMap["equipment"]
sourceData = dataMap["magicItems"] case "magicItems":
default: sourceData = dataMap["magicItems"]
continue default:
} continue
}
if sourceData == nil { if sourceData == nil {
continue continue
} }
// Create unique key for this list type + filter combination // Create unique key for this list type + filter combination
trackerKey := block.ListType trackerKey := block.ListType
if block.Filter != "" { if block.Filter != "" {
trackerKey += ":" + block.Filter trackerKey += ":" + block.Filter
} }
// Only create tracker once per unique combination // Only create tracker once per unique combination
if _, exists := listTrackers[trackerKey]; !exists { if _, exists := listTrackers[trackerKey]; !exists {
// Apply filter if specified // Apply filter if specified
filteredItems := p.applyFilter(sourceData, block.Filter) filteredItems := p.applyFilter(sourceData, block.Filter)
itemCount := p.getItemCount(filteredItems) itemCount := p.getItemCount(filteredItems)
if itemCount > 0 { if itemCount > 0 {
listTrackers[trackerKey] = &listTracker{ listTrackers[trackerKey] = &listTracker{
items: filteredItems, items: filteredItems,
currentIdx: 0, currentIdx: 0,
totalCount: itemCount, totalCount: itemCount,
}
} }
} }
} }
@@ -188,11 +197,21 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
break break
} }
// Determine template name for this page
pageTemplateName := GenerateContinuationTemplateName(templateName, pageNum)
// Load the correct template metadata for this page
// Fall back to base template if continuation template doesn't exist
currentTemplate := p.findTemplate(pageTemplateName)
if currentTemplate == nil {
currentTemplate = template
}
// Create page data // Create page data
pageData := make(map[string]interface{}) pageData := make(map[string]interface{})
// Distribute items to each block for this page // Distribute items to each block for this page
for _, block := range template.Blocks { for _, block := range currentTemplate.Blocks {
// Get tracker for this block's list type + filter // Get tracker for this block's list type + filter
trackerKey := block.ListType trackerKey := block.ListType
if block.Filter != "" { if block.Filter != "" {
@@ -221,7 +240,11 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
if block.NoEmpty && itemsToTake == 0 { if block.NoEmpty && itemsToTake == 0 {
continue continue
} }
// For regular blocks with no items remaining, fill with empty rows
if itemsToTake == 0 {
pageData[block.Name] = p.createEmptySliceWithCapacity(block.ListType, block.MaxItems)
continue
}
// Extract slice for this block // Extract slice for this block
blockItems := p.extractSlice(tracker.items, tracker.currentIdx, itemsToTake) blockItems := p.extractSlice(tracker.items, tracker.currentIdx, itemsToTake)
@@ -232,9 +255,7 @@ func (p *Paginator) PaginateMultiList(dataMap map[string]interface{}, templateNa
tracker.currentIdx += itemsToTake tracker.currentIdx += itemsToTake
} }
// Determine template name - use continuation naming for pages 2+ // Template name was already determined at the start of the loop
pageTemplateName := GenerateContinuationTemplateName(templateName, pageNum)
distributions = append(distributions, PageDistribution{ distributions = append(distributions, PageDistribution{
TemplateName: pageTemplateName, TemplateName: pageTemplateName,
PageNumber: pageNum, PageNumber: pageNum,
@@ -116,6 +116,14 @@ func populatePageDataFromDistribution(pageData *PageData, dist PageDistribution)
if skills, ok := data.([]SkillViewModel); ok { if skills, ok := data.([]SkillViewModel); ok {
pageData.SkillsLearned = skills pageData.SkillsLearned = skills
} }
case "skills_learned_1":
if skills, ok := data.([]SkillViewModel); ok {
pageData.SkillsLearned1 = skills
}
case "skills_learned_2":
if skills, ok := data.([]SkillViewModel); ok {
pageData.SkillsLearned2 = skills
}
case "skills_unlearned": case "skills_unlearned":
if skills, ok := data.([]SkillViewModel); ok { if skills, ok := data.([]SkillViewModel); ok {
// Add to general Skills list for template compatibility // Add to general Skills list for template compatibility
+4
View File
@@ -51,9 +51,13 @@ func LoadTemplateSetFromFiles(templateDir string) (TemplateSet, error) {
description string description string
}{ }{
{"page_1.html", "stats", "Statistikseite mit Grundwerten"}, {"page_1.html", "stats", "Statistikseite mit Grundwerten"},
{"page_1.2.html", "stats", "Fortsetzung Statistikseite"},
{"page_2.html", "play", "Spielbogen mit gelernten Fertigkeiten und Waffen"}, {"page_2.html", "play", "Spielbogen mit gelernten Fertigkeiten und Waffen"},
{"page_2.2.html", "play", "Fortsetzung Spielbogen"},
{"page_3.html", "spell", "Zauberseite mit Zauberliste"}, {"page_3.html", "spell", "Zauberseite mit Zauberliste"},
{"page_3.2.html", "spell", "Fortsetzung Zauberseite"},
{"page_4.html", "equip", "Ausrüstungsseite"}, {"page_4.html", "equip", "Ausrüstungsseite"},
{"page_4.2.html", "equip", "Fortsetzung Ausrüstungsseite"},
} }
// Load each template file and parse its metadata // Load each template file and parse its metadata
+2
View File
@@ -191,6 +191,8 @@ type PageData struct {
SkillsColumn3 []SkillViewModel // For continuation pages (page_1.2) SkillsColumn3 []SkillViewModel // For continuation pages (page_1.2)
SkillsColumn4 []SkillViewModel // For continuation pages (page_1.2) SkillsColumn4 []SkillViewModel // For continuation pages (page_1.2)
SkillsLearned []SkillViewModel // Filtered learned skills (page_2) SkillsLearned []SkillViewModel // Filtered learned skills (page_2)
SkillsLearned1 []SkillViewModel // First block of learned skills (page_2.2)
SkillsLearned2 []SkillViewModel // Second block of learned skills (page_2.2)
SkillsLanguage []SkillViewModel // Filtered language skills (page_2) SkillsLanguage []SkillViewModel // Filtered language skills (page_2)
Weapons []WeaponViewModel Weapons []WeaponViewModel
Spells []SpellViewModel Spells []SpellViewModel
@@ -26,19 +26,19 @@
<div class="left-section"> <div class="left-section">
<!-- Skills tables --> <!-- Skills tables -->
<div class="skills-row"> <div class="skills-row">
<!-- BLOCK: skills_learned, TYPE: skills, MAX: 7, FILTER: learned --> <!-- BLOCK: skills_learned_1, TYPE: skills, MAX: 31, FILTER: learned -->
<table class="skills-table"> <table class="skills-table">
<tr> <tr>
<th>Fertigkeit</th> <th>Fertigkeit</th>
<th>EW</th> <th>EW</th>
<th>PP</th> <th>PP</th>
</tr> </tr>
{{range .SkillsLearned}} {{range .SkillsLearned1}}
<tr><td>{{.Name}}{{if .Bemerkung}}:<span style="font-size: smaller;">{{.Bemerkung}}</span>{{end}}</td><td>{{if .Value}}+ {{.Value}}{{else}}&nbsp;{{end}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr> <tr><td>{{.Name}}{{if .Bemerkung}}:<span style="font-size: smaller;">{{.Bemerkung}}</span>{{end}}</td><td>{{if .Value}}+ {{.Value}}{{else}}&nbsp;{{end}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr>
{{end}} {{end}}
</table> </table>
<div class="skills-stack"> <div class="skills-stack">
<!-- BLOCK: skills_languages, TYPE: skills, MAX: 6, FILTER: language, NOEMPTY --> <!-- BLOCK: skills_languages, TYPE: skills, MAX: 14, FILTER: language, NOEMPTY -->
{{if .SkillsLanguage}}{{if (index .SkillsLanguage 0).Name}} {{if .SkillsLanguage}}{{if (index .SkillsLanguage 0).Name}}
<table class="skills-table" style="width: 100%; height: unset;"> <table class="skills-table" style="width: 100%; height: unset;">
<tr> <tr>
@@ -51,14 +51,14 @@
{{end}} {{end}}
</table> </table>
{{end}}{{end}} {{end}}{{end}}
<!-- BLOCK: skills_learned, TYPE: skills, MAX: 10, FILTER: learned --> <!-- BLOCK: skills_learned_2, TYPE: skills, MAX: 16, FILTER: learned -->
<table class="skills-table" style="width: 100%; height: unset;"> <table class="skills-table" style="width: 100%; height: unset;">
<tr> <tr>
<th>Fertigkeit</th> <th>Fertigkeit</th>
<th>EW</th> <th>EW</th>
<th>PP</th> <th>PP</th>
</tr> </tr>
{{range .SkillsLearned}} {{range .SkillsLearned2}}
<tr><td>{{.Name}}{{if .Bemerkung}}:<span style="font-size: smaller;">{{.Bemerkung}}</span>{{end}}</td><td>{{if .Value}}+ {{.Value}}{{else}}&nbsp;{{end}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr> <tr><td>{{.Name}}{{if .Bemerkung}}:<span style="font-size: smaller;">{{.Bemerkung}}</span>{{end}}</td><td>{{if .Value}}+ {{.Value}}{{else}}&nbsp;{{end}}</td><td>{{if .PracticePoints}}{{.PracticePoints}}{{end}}</td></tr>
{{end}} {{end}}
</table> </table>
@@ -69,7 +69,7 @@
<div class="right-section"> <div class="right-section">
<!-- Weapons table --> <!-- Weapons table -->
<div class="margin-bottom-3"> <div class="margin-bottom-3">
<!-- BLOCK: weapons_main, TYPE: weapons, MAX: 3 --> <!-- BLOCK: weapons_main, TYPE: weapons, MAX: 29 -->
<table class="weapons-table"> <table class="weapons-table">
<tr> <tr>
<th>Waffe</th> <th>Waffe</th>
@@ -26,7 +26,7 @@
<div class="flex main-content"> <div class="flex main-content">
<!-- Left spell table --> <!-- Left spell table -->
<div class="left-section"> <div class="left-section">
<!-- BLOCK: spells_column1, TYPE: spells, MAX: 5 --> <!-- BLOCK: spells_column1, TYPE: spells, MAX: 15 -->
<table class="spells-table"> <table class="spells-table">
<tr> <tr>
<th>AP<hr>Prozess *</th> <th>AP<hr>Prozess *</th>
@@ -51,7 +51,7 @@
<!-- Right spell table --> <!-- Right spell table -->
<div class="right-section"> <div class="right-section">
<!-- BLOCK: spells_column2, TYPE: spells, MAX: 2 --> <!-- BLOCK: spells_column2, TYPE: spells, MAX: 10 -->
<table class="spells-table"> <table class="spells-table">
<tr> <tr>
<th>AP<br>Prozess *</th> <th>AP<br>Prozess *</th>