Add themed UI, favicon, plan deletion, regrow cycles, and crop prep/post tasks
This commit is contained in:
@@ -6,48 +6,30 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func buildTasksForDay(plans []Plan, month, day int) []Task {
|
||||
func buildTasksForDay(plans []Plan, stepMap map[int64][]CropStep, month, day int) []Task {
|
||||
var tasks []Task
|
||||
for _, p := range plans {
|
||||
field := p.TargetName
|
||||
if strings.TrimSpace(field) == "" {
|
||||
field = "Unbekanntes Feld"
|
||||
}
|
||||
if p.StartMonth == month && p.StartDay == day {
|
||||
tasks = append(tasks, Task{Type: "Aussaat", Field: field, Message: fmt.Sprintf("%s auf %s aussaeen", p.CropName, field), SortOrder: 1})
|
||||
}
|
||||
if p.HarvestMonth == month && p.HarvestDay == day {
|
||||
tasks = append(tasks, Task{Type: "Ernte", Field: field, Message: fmt.Sprintf("%s auf %s ernten", p.CropName, field), SortOrder: 2})
|
||||
}
|
||||
tasks = append(tasks, expandPlanDayTasks(p, stepMap[p.CropID], month, day)...)
|
||||
}
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
if tasks[i].SortOrder == tasks[j].SortOrder {
|
||||
return tasks[i].Field < tasks[j].Field
|
||||
}
|
||||
return tasks[i].SortOrder < tasks[j].SortOrder
|
||||
})
|
||||
sortTasks(tasks)
|
||||
return tasks
|
||||
}
|
||||
|
||||
func buildCalendar(plans []Plan, startMonth, startDay, daysPerMonth, spanMonths int) []CalendarMonth {
|
||||
func buildCalendar(plans []Plan, stepMap map[int64][]CropStep, startMonth, startDay, daysPerMonth, spanMonths int) []CalendarMonth {
|
||||
tasksByKey := make(map[string][]Task)
|
||||
for _, p := range plans {
|
||||
field := p.TargetName
|
||||
if strings.TrimSpace(field) == "" {
|
||||
field = "Unbekanntes Feld"
|
||||
for m := 1; m <= 12; m++ {
|
||||
for d := 1; d <= daysPerMonth; d++ {
|
||||
dayTasks := expandPlanDayTasks(p, stepMap[p.CropID], m, d)
|
||||
if len(dayTasks) > 0 {
|
||||
key := fmt.Sprintf("%d-%d", m, d)
|
||||
tasksByKey[key] = append(tasksByKey[key], dayTasks...)
|
||||
}
|
||||
}
|
||||
}
|
||||
tasksByKey[fmt.Sprintf("%d-%d", p.StartMonth, p.StartDay)] = append(tasksByKey[fmt.Sprintf("%d-%d", p.StartMonth, p.StartDay)], Task{
|
||||
Type: "Aussaat",
|
||||
Field: field,
|
||||
Message: fmt.Sprintf("Aussaat %s", p.CropName),
|
||||
SortOrder: 1,
|
||||
})
|
||||
tasksByKey[fmt.Sprintf("%d-%d", p.HarvestMonth, p.HarvestDay)] = append(tasksByKey[fmt.Sprintf("%d-%d", p.HarvestMonth, p.HarvestDay)], Task{
|
||||
Type: "Ernte",
|
||||
Field: field,
|
||||
Message: fmt.Sprintf("Ernte %s", p.CropName),
|
||||
SortOrder: 2,
|
||||
})
|
||||
}
|
||||
for k := range tasksByKey {
|
||||
sortTasks(tasksByKey[k])
|
||||
}
|
||||
|
||||
var out []CalendarMonth
|
||||
@@ -64,16 +46,10 @@ func buildCalendar(plans []Plan, startMonth, startDay, daysPerMonth, spanMonths
|
||||
fromDay = startDay
|
||||
}
|
||||
var days []CalendarDay
|
||||
for day := fromDay; day <= daysPerMonth; day++ {
|
||||
key := fmt.Sprintf("%d-%d", month, day)
|
||||
for d := fromDay; d <= daysPerMonth; d++ {
|
||||
key := fmt.Sprintf("%d-%d", month, d)
|
||||
items := append([]Task(nil), tasksByKey[key]...)
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
if items[i].SortOrder == items[j].SortOrder {
|
||||
return items[i].Field < items[j].Field
|
||||
}
|
||||
return items[i].SortOrder < items[j].SortOrder
|
||||
})
|
||||
days = append(days, CalendarDay{Day: day, Tasks: items})
|
||||
days = append(days, CalendarDay{Day: d, Tasks: items})
|
||||
}
|
||||
out = append(out, CalendarMonth{
|
||||
Offset: offset,
|
||||
@@ -85,3 +61,111 @@ func buildCalendar(plans []Plan, startMonth, startDay, daysPerMonth, spanMonths
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func expandPlanDayTasks(p Plan, steps []CropStep, month, day int) []Task {
|
||||
field := p.TargetName
|
||||
if strings.TrimSpace(field) == "" {
|
||||
field = "Unbekanntes Feld"
|
||||
}
|
||||
var out []Task
|
||||
baseHarvest := p.HarvestMonth
|
||||
|
||||
if p.StartMonth == month && p.StartDay == day {
|
||||
out = append(out, Task{
|
||||
Type: "Aussaat",
|
||||
Field: field,
|
||||
Message: withOptionalNote(fmt.Sprintf("Aussaat %s", p.CropName), p.Notes),
|
||||
SortOrder: 10,
|
||||
})
|
||||
}
|
||||
|
||||
harvestMonths := []int{baseHarvest}
|
||||
if p.RegrowEnabled {
|
||||
maxExtra := p.RegrowCycles
|
||||
if maxExtra == 0 {
|
||||
maxExtra = 24
|
||||
}
|
||||
for i := 1; i <= maxExtra; i++ {
|
||||
harvestMonths = append(harvestMonths, wrapMonth(baseHarvest+(i*p.HarvestDistance())))
|
||||
}
|
||||
}
|
||||
harvestMonths = uniqueMonths(harvestMonths)
|
||||
for _, hm := range harvestMonths {
|
||||
if hm == month && p.HarvestDay == day {
|
||||
out = append(out, Task{
|
||||
Type: "Ernte",
|
||||
Field: field,
|
||||
Message: withOptionalNote(fmt.Sprintf("Ernte %s", p.CropName), p.Notes),
|
||||
SortOrder: 20,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range steps {
|
||||
switch s.Phase {
|
||||
case "pre":
|
||||
taskMonth := wrapMonth(p.StartMonth - s.MonthOffset)
|
||||
if taskMonth == month && p.StartDay == day {
|
||||
out = append(out, Task{
|
||||
Type: "Vorbereitung",
|
||||
Field: field,
|
||||
Message: s.Title,
|
||||
SortOrder: 5,
|
||||
})
|
||||
}
|
||||
case "post":
|
||||
for _, hm := range harvestMonths {
|
||||
taskMonth := wrapMonth(hm + s.MonthOffset)
|
||||
if taskMonth == month && p.HarvestDay == day {
|
||||
out = append(out, Task{
|
||||
Type: "Nachbereitung",
|
||||
Field: field,
|
||||
Message: s.Title,
|
||||
SortOrder: 30,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (p Plan) HarvestDistance() int {
|
||||
if p.GrowMonths <= 0 {
|
||||
return 1
|
||||
}
|
||||
return p.GrowMonths
|
||||
}
|
||||
|
||||
func withOptionalNote(base, note string) string {
|
||||
n := strings.TrimSpace(note)
|
||||
if n == "" {
|
||||
return base
|
||||
}
|
||||
return fmt.Sprintf("%s (Notiz: %s)", base, n)
|
||||
}
|
||||
|
||||
func sortTasks(tasks []Task) {
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
if tasks[i].SortOrder == tasks[j].SortOrder {
|
||||
if tasks[i].Field == tasks[j].Field {
|
||||
return tasks[i].Message < tasks[j].Message
|
||||
}
|
||||
return tasks[i].Field < tasks[j].Field
|
||||
}
|
||||
return tasks[i].SortOrder < tasks[j].SortOrder
|
||||
})
|
||||
}
|
||||
|
||||
func uniqueMonths(values []int) []int {
|
||||
seen := make(map[int]bool)
|
||||
var out []int
|
||||
for _, v := range values {
|
||||
if !seen[v] {
|
||||
seen[v] = true
|
||||
out = append(out, v)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user