feat(time-tracking): extract the smart-fill start computation
This commit is contained in:
parent
e4b0a487fc
commit
8c34676946
|
|
@ -0,0 +1,47 @@
|
|||
import {describe, it, expect} from 'vitest'
|
||||
|
||||
import {smartFillStart} from './smartFillStart'
|
||||
import type {ITimeEntry} from '@/modelTypes/ITimeEntry'
|
||||
|
||||
function entry(startTime: Date, endTime: Date | null): ITimeEntry {
|
||||
return {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
taskId: 0,
|
||||
projectId: 0,
|
||||
startTime,
|
||||
endTime,
|
||||
comment: '',
|
||||
created: startTime,
|
||||
updated: startTime,
|
||||
maxPermission: null,
|
||||
}
|
||||
}
|
||||
|
||||
describe('smartFillStart', () => {
|
||||
const now = new Date('2026-06-07T15:30:00')
|
||||
|
||||
it('continues from the latest entry end time', () => {
|
||||
const entries = [
|
||||
entry(new Date('2026-06-07T09:00:00'), new Date('2026-06-07T10:00:00')),
|
||||
entry(new Date('2026-06-07T11:00:00'), new Date('2026-06-07T12:30:00')),
|
||||
]
|
||||
expect(smartFillStart(entries, '09:00', now)).toEqual(new Date('2026-06-07T12:30:00'))
|
||||
})
|
||||
|
||||
it('ignores still-running entries (no end) when picking the latest end', () => {
|
||||
const entries = [
|
||||
entry(new Date('2026-06-07T09:00:00'), new Date('2026-06-07T10:00:00')),
|
||||
entry(new Date('2026-06-07T13:00:00'), null),
|
||||
]
|
||||
expect(smartFillStart(entries, '09:00', now)).toEqual(new Date('2026-06-07T10:00:00'))
|
||||
})
|
||||
|
||||
it('falls back to the default start time on the current day when there are no entries', () => {
|
||||
expect(smartFillStart([], '08:15', now)).toEqual(new Date('2026-06-07T08:15:00'))
|
||||
})
|
||||
|
||||
it('falls back to 09:00 when no default is configured', () => {
|
||||
expect(smartFillStart([], '', now)).toEqual(new Date('2026-06-07T09:00:00'))
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import type {ITimeEntry} from '@/modelTypes/ITimeEntry'
|
||||
|
||||
// The smart-clock start time: continue from the most recent entry's end so
|
||||
// consecutive entries don't overlap or leave gaps; with no completed entry to
|
||||
// continue from, fall back to the user's configured default start (HH:MM) on
|
||||
// the given day.
|
||||
export function smartFillStart(recentEntries: ITimeEntry[], defaultStart: string, now: Date): Date {
|
||||
const lastEnd = recentEntries
|
||||
.map(entry => entry.endTime)
|
||||
.filter((end): end is Date => end !== null)
|
||||
.sort((a, b) => b.getTime() - a.getTime())[0]
|
||||
if (lastEnd !== undefined) {
|
||||
return new Date(lastEnd)
|
||||
}
|
||||
|
||||
const [hours, minutes] = (defaultStart || '09:00').split(':').map(Number)
|
||||
const start = new Date(now)
|
||||
start.setHours(hours || 0, minutes || 0, 0, 0)
|
||||
return start
|
||||
}
|
||||
Loading…
Reference in New Issue