diff --git a/app/src/assets/scss/main/_mobile.scss b/app/src/assets/scss/main/_mobile.scss index bb86ff8c6..6fc0254ce 100644 --- a/app/src/assets/scss/main/_mobile.scss +++ b/app/src/assets/scss/main/_mobile.scss @@ -29,6 +29,11 @@ &:hover { background-color: transparent; } + + svg, img { + height: 20px; + width: 20px; + } } &__graphic { diff --git a/kernel/av/value.go b/kernel/av/value.go index fe3aaed85..ec3cb09d3 100644 --- a/kernel/av/value.go +++ b/kernel/av/value.go @@ -899,6 +899,10 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { for _, v := range r.Contents { if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { sum += v.Number.Content + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + sum += f } } r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(sum, destKey.NumberFormat)}} @@ -909,6 +913,11 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { sum += v.Number.Content count++ + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + sum += f + count++ } } if 0 < count { @@ -919,6 +928,10 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { for _, v := range r.Contents { if KeyTypeNumber == v.Type && nil != v.Number && v.Number.IsNotEmpty { numbers = append(numbers, v.Number.Content) + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + numbers = append(numbers, f) } } sort.Float64s(numbers) @@ -936,6 +949,12 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { if v.Number.Content < minVal { minVal = v.Number.Content } + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + if f < minVal { + minVal = f + } } } if math.MaxFloat64 != minVal { @@ -948,6 +967,12 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { if v.Number.Content > maxVal { maxVal = v.Number.Content } + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + if f > maxVal { + maxVal = f + } } } if -math.MaxFloat64 != maxVal { @@ -1004,6 +1029,15 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { isNotTime = true hasEndDate = false } + } else { + content := v.String(false) + f, _ := util.Convert2Float(content) + if f < minVal { + minVal = f + } + if f > maxVal { + maxVal = f + } } } @@ -1025,6 +1059,10 @@ func (r *ValueRollup) calcContents(calc *RollupCalc, destKey *Key) { if 0 != earliest && 0 != latest { r.Contents = []*Value{{Type: KeyTypeCreated, Created: NewFormattedValueCreated(earliest, latest, CreatedFormatDuration)}} } + default: + if math.MaxFloat64 != minVal && -math.MaxFloat64 != maxVal { + r.Contents = []*Value{{Type: KeyTypeNumber, Number: NewFormattedValueNumber(maxVal-minVal, destKey.NumberFormat)}} + } } case CalcOperatorEarliest: if 1 > len(r.Contents) { diff --git a/kernel/filesys/template.go b/kernel/filesys/template.go index 3184da077..2e22f416e 100644 --- a/kernel/filesys/template.go +++ b/kernel/filesys/template.go @@ -46,6 +46,7 @@ func BuiltInTemplateFuncs() (ret template.FuncMap) { ret["ISOWeek"] = util.ISOWeek ret["ISOYear"] = util.ISOYear ret["ISOMonth"] = util.ISOMonth + ret["ISOWeekDate"] = util.ISOWeekDate ret["pow"] = pow ret["powf"] = powf ret["log"] = log diff --git a/kernel/util/time.go b/kernel/util/time.go index b13186516..933e88084 100644 --- a/kernel/util/time.go +++ b/kernel/util/time.go @@ -80,6 +80,19 @@ func ISOMonth(date time.Time) int { return int(monday.Month()) } +// ISOWeekDate returns the date of the specified day of the week in the ISO 8601 week of date. +// day: Monday=1, ..., Sunday=7. +func ISOWeekDate(date time.Time, day int) time.Time { + weekday := int(date.Weekday()) + if weekday == 0 { + weekday = 7 + } + + daysToMonday := weekday - 1 + monday := date.AddDate(0, 0, -daysToMonday) + return monday.AddDate(0, 0, day-1) +} + func Millisecond2Time(t int64) time.Time { sec := t / 1000 msec := t % 1000