Browse Source
Move group to backend and change intervals and such to use 05:00 as start of day.
master
0.1.21
Move group to backend and change intervals and such to use 05:00 as start of day.
master
0.1.21
Gisle Aune
2 years ago
15 changed files with 230 additions and 103 deletions
-
2frontend/src/app.d.ts
-
15frontend/src/lib/clients/sl3.ts
-
7frontend/src/lib/components/contexts/ItemListContext.svelte
-
4frontend/src/lib/components/controls/TimeRangeInput.svelte
-
8frontend/src/lib/models/item.ts
-
71frontend/src/lib/utils/items.ts
-
13frontend/src/lib/utils/timeinterval.ts
-
7frontend/src/routes/[scope=prettyid]/history/[interval].svelte
-
6frontend/src/routes/[scope=prettyid]/overview.svelte
-
8frontend/src/routes/index.svelte
-
9internal/genutils/map.go
-
8models/date.go
-
9ports/httpapi/common.go
-
61ports/httpapi/items.go
-
105usecases/items/groups.go
@ -1,71 +0,0 @@ |
|||
import type { ItemGroup, ItemGroupReference } from "$lib/models/item"; |
|||
import type Item from "$lib/models/item"; |
|||
import { formatDate, formatDateTime, formatTime, formatWeekdayDate } from "./date"; |
|||
|
|||
export interface GroupItemsOptions { |
|||
hideCreated?: boolean |
|||
hideScheduled?: boolean |
|||
hideAcquired?: boolean |
|||
} |
|||
|
|||
export function groupItemOptionsQuery(opts: GroupItemsOptions): string { |
|||
return `hideCreated=${opts.hideCreated},hideScheduled=${opts.hideScheduled},hideAcquired=${opts.hideAcquired}`; |
|||
} |
|||
|
|||
export function groupItems(items: Item[], minDate?: string, opts: GroupItemsOptions = {}): ItemGroup[] { |
|||
let groups: Record<string, ItemGroup> = {}; |
|||
|
|||
for (let i = 0; i < items.length; ++i) { |
|||
const item = items[i]; |
|||
const createKey = formatDate(item.createdTime) |
|||
const createSortKey = `${createKey} ${formatTime(item.createdTime)}` |
|||
|
|||
if (!opts.hideCreated) { |
|||
if (!item.acquiredTime || item.acquiredTime >= item.createdTime) { |
|||
addItem(groups, createKey, i, createSortKey, item, "created"); |
|||
} |
|||
} |
|||
|
|||
if (!opts.hideScheduled) { |
|||
if (item.scheduledDate) { |
|||
addItem(groups, item.scheduledDate, i, `${item.scheduledDate} 23:59:59`, item, "scheduled"); |
|||
} |
|||
} |
|||
|
|||
if (!opts.hideAcquired) { |
|||
if (item.acquiredTime) { |
|||
addItem(groups, formatDate(item.acquiredTime), i, formatDateTime(item.acquiredTime), item, "acquired"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return Object.keys(groups).sort((a,b) => ( |
|||
b.localeCompare(a) |
|||
)).map(k => ({ |
|||
...groups[k], |
|||
list: groups[k].list.sort((a, b) => { |
|||
return b.sortKey.localeCompare(a.sortKey); |
|||
}).map(r => ({...r, sortKey: void(0)})), |
|||
})).filter(g => minDate == null || g.label > minDate); |
|||
} |
|||
|
|||
function addItem(groups: Record<string, ItemGroup>, key: string, index: number, sortKey: string, item: Item, event: ItemGroupReference["event"]) { |
|||
if (groups[key] == null) { |
|||
groups[key] = { |
|||
label: formatWeekdayDate(sortKey), |
|||
list: [], |
|||
} |
|||
} |
|||
|
|||
const i = groups[key].list.findIndex(r => r.idx === index) |
|||
if (i == -1) { |
|||
groups[key].list.push({ |
|||
idx: index, |
|||
event: event, |
|||
sortKey: sortKey, |
|||
}) |
|||
} else { |
|||
groups[key].list[i].event = event; |
|||
groups[key].list[i].sortKey = sortKey; |
|||
} |
|||
} |
@ -0,0 +1,105 @@ |
|||
package items |
|||
|
|||
import ( |
|||
"git.aiterp.net/stufflog3/stufflog3/internal/genutils" |
|||
"sort" |
|||
"time" |
|||
) |
|||
|
|||
type Group struct { |
|||
Label string `json:"label,omitempty"` |
|||
List []GroupReference `json:"list,omitempty"` |
|||
} |
|||
|
|||
type GroupOptions struct { |
|||
HideCreated bool `json:"hideCreated,omitempty"` |
|||
HideScheduled bool `json:"hideScheduled,omitempty"` |
|||
HideAcquired bool `json:"hideAcquired,omitempty"` |
|||
} |
|||
|
|||
type GroupReference struct { |
|||
Index int `json:"idx"` |
|||
Event string `json:"event"` |
|||
Time string `json:"time"` |
|||
|
|||
sortKey string |
|||
} |
|||
|
|||
func GenerateGroups(items []Result, opts GroupOptions) []Group { |
|||
groups := make(map[string]Group, 16) |
|||
|
|||
// TODO: Get the scope from somewhere else, if necessary.
|
|||
|
|||
for i, item := range items { |
|||
if !opts.HideCreated && (item.AcquiredTime == nil || item.AcquiredTime.After(item.CreatedTime)) { |
|||
addItem(groups, i, "created", item.CreatedTime, tz) |
|||
} |
|||
if !opts.HideScheduled && item.ScheduledDate != nil { |
|||
addItem(groups, i, "scheduled", item.ScheduledDate.WithTimeAndLocation(23, 59, 59, tz), tz) |
|||
} |
|||
if !opts.HideAcquired && item.AcquiredTime != nil { |
|||
addItem(groups, i, "acquired", *item.AcquiredTime, tz) |
|||
} |
|||
} |
|||
|
|||
for _, group := range groups { |
|||
sort.Slice(group.List, func(i, j int) bool { |
|||
return group.List[j].sortKey < group.List[i].sortKey |
|||
}) |
|||
} |
|||
|
|||
groupSlice := genutils.MapValues(groups) |
|||
sort.Slice(groupSlice, func(i, j int) bool { |
|||
return groupSlice[j].Label < groupSlice[i].Label |
|||
}) |
|||
|
|||
return groupSlice |
|||
} |
|||
|
|||
func addItem(groups map[string]Group, index int, event string, eventDate time.Time, tz *time.Location) { |
|||
groupDate := eventDate.In(tz).Add(-time.Minute * 300) |
|||
eventDate = eventDate.In(tz) |
|||
|
|||
groupKey := groupDate.Format("2006-01-02") |
|||
var sortKey string |
|||
if event == "scheduled" { |
|||
sortKey = eventDate.Format("2006-01-02") + " 23:59:59.999" |
|||
} else { |
|||
sortKey = eventDate.Format("2006-01-02 15:04:05") |
|||
} |
|||
|
|||
// Why, Go, must you be so.
|
|||
group, ok := groups[groupKey] |
|||
if !ok { |
|||
group = Group{ |
|||
Label: groupDate.Format("2006-01-02 (Monday)"), |
|||
List: make([]GroupReference, 0, 16), |
|||
} |
|||
} |
|||
|
|||
for i, ref := range group.List { |
|||
if ref.Index == index { |
|||
group.List = append(group.List[:i], group.List[i+1:]...) |
|||
break |
|||
} |
|||
} |
|||
|
|||
group.List = append(group.List, GroupReference{ |
|||
Index: index, |
|||
Event: event, |
|||
Time: eventDate.Format("15:04"), |
|||
sortKey: sortKey, |
|||
}) |
|||
groups[groupKey] = group |
|||
} |
|||
|
|||
var tz *time.Location |
|||
|
|||
func init() { |
|||
var err error |
|||
|
|||
tz, err = time.LoadLocation("Europe/Oslo") |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue