clean up svelte ui big time, and add beginnings of item stuff.
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-02-29 16:54:38 +01:00
parent e724eb57b5
commit bb13195f4b
42 changed files with 1051 additions and 504 deletions
+9
View File
@@ -0,0 +1,9 @@
package models
// A Goal is a declared investment into the goal.
type Goal struct {
ID string `json:"id"`
ActivityID string `json:"activityId"`
ItemID string `json:"itemId"`
PointCount int `json:"pointCount"`
}
+45
View File
@@ -0,0 +1,45 @@
package models
import "github.com/gisle/stufflog/internal/generate"
type Item struct {
ID string `json:"id" msgpack:"id"`
UserID string `json:"userId" msgpack:"userId"`
Active bool `json:"active" msgpack:"active"`
Name string `json:"name" msgpack:"name"`
Multiplier float64 `json:"multiplier" msgpack:"multiplier"`
}
func (item *Item) GenerateID() {
item.ID = generate.ID("I", 16)
}
func (item *Item) ApplyUpdate(update ItemUpdate) error {
if update.SetActive != nil {
item.Active = *update.SetActive
}
if update.SetName != nil {
item.Name = *update.SetName
}
return nil
}
type ItemUpdate struct {
SetName *string `json:"setName"`
SetActive *bool `json:"setActive"`
}
type ItemsByName []*Item
func (items ItemsByName) Len() int {
return len(items)
}
func (items ItemsByName) Less(i, j int) bool {
return items[i].Name < items[j].Name
}
func (items ItemsByName) Swap(i, j int) {
items[i], items[j] = items[j], items[i]
}
+17
View File
@@ -0,0 +1,17 @@
package models
import "time"
// Log is a logged performance of an activity during the period. SubGoalID is optional, but GoalID is not. The
// points is the points calculated on the time of submission and does not need to reflect the latest.
type Log struct {
Date time.Time `json:"date"`
ID string `json:"id"`
SubActivityID string `json:"subActivityId"`
GoalID string `json:"goalId"`
SubGoalID string `json:"subGoalId"`
Description string `json:"description"`
SubmitTime time.Time `json:"submitTime"`
Amount int `json:"amount"`
Score *Score `json:"score"`
}
+42 -120
View File
@@ -16,9 +16,8 @@ type Period struct {
ShouldReScore bool `json:"-" msgpack:"-"`
Tags []string `json:"tags"`
Goals []PeriodGoal `json:"goals"`
Logs []PeriodLog `json:"logs"`
Goals []Goal `json:"goals"`
Logs []Log `json:"logs"`
}
// GenerateIDs generates IDs. It should only be used initially.
@@ -26,10 +25,6 @@ func (period *Period) GenerateIDs() {
period.ID = generate.ID("P", 12)
for i := range period.Goals {
period.Goals[i].ID = generate.ID("PG", 16)
for j := range period.Goals[i].SubGoals {
period.Goals[i].SubGoals[j].ID = generate.ID("PGS", 20)
}
}
for i := range period.Logs {
period.Logs[i].ID = generate.ID("PL", 16)
@@ -46,7 +41,6 @@ func (period *Period) Clear() {
period.ShouldReScore = false
period.Tags = period.Tags[:0]
period.Goals = period.Goals[:0]
period.Logs = period.Logs[:0]
}
@@ -55,11 +49,9 @@ func (period *Period) Clear() {
func (period *Period) Copy() *Period {
periodCopy := *period
periodCopy.Tags = make([]string, len(period.Tags))
copy(periodCopy.Tags, period.Tags)
periodCopy.Goals = make([]PeriodGoal, len(period.Goals))
periodCopy.Goals = make([]Goal, len(period.Goals))
copy(periodCopy.Goals, period.Goals)
periodCopy.Logs = make([]PeriodLog, len(period.Logs))
periodCopy.Logs = make([]Log, len(period.Logs))
copy(periodCopy.Logs, period.Logs)
return &periodCopy
@@ -87,29 +79,6 @@ func (period *Period) ApplyUpdate(update PeriodUpdate) (changed bool, err error)
period.Name = *update.SetName
}
if update.RemoveTag != nil {
for i, existingTag := range period.Tags {
if *update.AddTag == existingTag {
period.Tags = append(period.Tags[:i], period.Tags[i+1:]...)
changed = true
break
}
}
}
if update.AddTag != nil {
found := false
for _, existingTag := range period.Tags {
if *update.AddTag == existingTag {
found = true
break
}
}
if !found {
changed = true
period.Tags = append(period.Tags, *update.AddTag)
}
}
if update.AddGoal != nil {
goal := *update.AddGoal
goal.ID = generate.ID("PG", 16)
@@ -125,9 +94,6 @@ func (period *Period) ApplyUpdate(update PeriodUpdate) (changed bool, err error)
if update.AddLog != nil && update.AddLog.GoalID == "NEW" {
update.AddLog.GoalID = goal.ID
}
for i := range goal.SubGoals {
goal.SubGoals[i].ID = generate.ID("PGS", 20)
}
changed = true
}
@@ -139,7 +105,6 @@ func (period *Period) ApplyUpdate(update PeriodUpdate) (changed bool, err error)
}
goal.PointCount = update.ReplaceGoal.PointCount
goal.SubGoals = update.ReplaceGoal.SubGoals
changed = true
period.ShouldReScore = true
@@ -176,6 +141,30 @@ func (period *Period) ApplyUpdate(update PeriodUpdate) (changed bool, err error)
period.Logs = append(period.Logs, log)
changed = true
}
if update.ReplaceLog != nil {
log := *update.ReplaceLog
found := false
for i, log2 := range period.Logs {
if log.ID == log2.ID {
found = true
goal := period.Goal(log.GoalID)
if goal == nil {
err = slerrors.NotFound("Goal")
return
}
period.Logs[i] = log
break
}
}
if !found {
err = slerrors.NotFound("Log")
return
}
}
if update.RemoveLog != nil {
found := false
for i, log := range period.Logs {
@@ -197,7 +186,7 @@ func (period *Period) ApplyUpdate(update PeriodUpdate) (changed bool, err error)
}
func (period *Period) RemoveBrokenLogs() {
goodLogs := make([]PeriodLog, 0, len(period.Logs))
goodLogs := make([]Log, 0, len(period.Logs))
for _, log := range period.Logs {
goal := period.Goal(log.GoalID)
@@ -205,34 +194,13 @@ func (period *Period) RemoveBrokenLogs() {
continue
}
if log.SubGoalID != "" {
if goal.SubGoal(log.SubGoalID) == nil {
continue
}
}
goodLogs = append(goodLogs, log)
}
period.Logs = goodLogs
}
func (period *Period) RemoveDuplicateTags() {
deleteList := make([]int, 0, 2)
found := make(map[string]bool)
for i, tag := range period.Tags {
if found[tag] {
deleteList = append(deleteList, i-len(deleteList))
}
found[tag] = true
}
for _, index := range deleteList {
period.Tags = append(period.Tags[:index], period.Tags[index+1:]...)
}
}
func (period *Period) Goal(id string) *PeriodGoal {
func (period *Period) Goal(id string) *Goal {
for i, goal := range period.Goals {
if goal.ID == id {
return &period.Goals[i]
@@ -263,79 +231,33 @@ func (period *Period) DayHadActivity(date time.Time, activityID string) bool {
return false
}
// A PeriodGoal is a declared investment into the goal.
type PeriodGoal struct {
ID string `json:"id"`
ActivityID string `json:"activityId"`
PointCount int `json:"pointCount"`
SubGoals []PeriodSubGoal `json:"subGoals"`
}
func (goal *PeriodGoal) SubGoal(id string) *PeriodSubGoal {
if goal == nil {
return nil
}
for i, subGoal := range goal.SubGoals {
if subGoal.ID == id {
return &goal.SubGoals[i]
}
}
return nil
}
// A PeriodSubGoal is a specific sub-goal that should either punish or boost performance. For example, it could represent
// a project or technique that should take priority, or a guilty pleasure that should definitely not be.
type PeriodSubGoal struct {
ID string `json:"id"`
Name string `json:"name"`
Multiplier float64 `json:"multiplier"`
}
// PeriodLog is a logged performance of an activity during the period. SubGoalID is optional, but GoalID is not. The
// points is the points calculated on the time of submission and does not need to reflect the latest.
type PeriodLog struct {
Date time.Time `json:"date"`
ID string `json:"id"`
SubActivityID string `json:"subActivityId"`
GoalID string `json:"goalId"`
SubGoalID string `json:"subGoalId"`
Description string `json:"description"`
SubmitTime time.Time `json:"submitTime"`
Amount int `json:"amount"`
Score *Score `json:"score"`
}
// PeriodUpdate describes a change to a period
type PeriodUpdate struct {
SetFrom *time.Time `json:"setFrom"`
SetTo *time.Time `json:"setTo"`
SetName *string `json:"setName"`
AddLog *PeriodLog `json:"addLog"`
RemoveLog *string `json:"removeLog"`
AddGoal *PeriodGoal `json:"addGoal"`
ReplaceGoal *PeriodGoal `json:"replaceGoal"`
RemoveGoal *string `json:"removeGoal"`
AddTag *string `json:"addTag"`
RemoveTag *string `json:"removeTag"`
AddLog *Log `json:"addLog"`
ReplaceLog *Log `json:"replaceGoal"`
RemoveLog *string `json:"removeLog"`
AddGoal *Goal `json:"addGoal"`
ReplaceGoal *Goal `json:"replaceGoal"`
RemoveGoal *string `json:"removeGoal"`
}
type Score struct {
ActivityScore float64 `json:"activityScore"`
Amount int `json:"amount"`
SubGoalMultiplier *float64 `json:"subGoalMultiplier"`
DailyBonus int `json:"dailyBonus"`
ActivityScore float64 `json:"activityScore"`
Amount int `json:"amount"`
ItemMultiplier *float64 `json:"subGoalMultiplier"`
DailyBonus int `json:"dailyBonus"`
Total int64 `json:"total"`
}
func (s *Score) Calc() {
subGoalMultiplier := 1.0
if s.SubGoalMultiplier != nil {
subGoalMultiplier = *s.SubGoalMultiplier
if s.ItemMultiplier != nil {
subGoalMultiplier = *s.ItemMultiplier
}
s.Total = int64(s.DailyBonus) + int64(s.ActivityScore*float64(s.Amount)*subGoalMultiplier)