Multiple minor changes and improvements
This commit is contained in:
@@ -24,13 +24,13 @@ import { DAY, HOUR, localDateKey } from './time.js';
|
||||
|
||||
/**
|
||||
* One stretch of the day. `endTs === null` marks the single running entry; every
|
||||
* other entry's `endTs` equals the next entry's `startTs`.
|
||||
* other entry has a finite end; imported histories may contain gaps.
|
||||
*
|
||||
* @typedef {object} EntryRecord
|
||||
* @property {number} [id]
|
||||
* @property {string} date
|
||||
* @property {number} seq position within the day, dense from 0
|
||||
* @property {'travel'|'work'|'lunch'} kind
|
||||
* @property {'travel'|'work'|'lunch'|'break'} kind
|
||||
* @property {string} task
|
||||
* @property {string|null} client
|
||||
* @property {number} startTs
|
||||
@@ -120,15 +120,30 @@ export function closeDay(date, ts, stale = false) {
|
||||
});
|
||||
}
|
||||
|
||||
/** Undo a premature close; no new entry or unaccounted interval is introduced. */
|
||||
export function reopenDay(date, now) {
|
||||
/** Confirmed same-day reopening; status and all resumed slots commit together. */
|
||||
export function reopenDay(date, now, mode = 'continue') {
|
||||
return db.transaction('rw', db.days, db.entries, async () => {
|
||||
const day = await getDay(date);
|
||||
if (!day || day.status !== 'closed' || await getActiveDay()) return false;
|
||||
if (!['continue', 'break'].includes(mode)) throw new Error('Choix de reprise invalide.');
|
||||
if (!day || date !== localDateKey(now) || day.status !== 'closed' || await getActiveDay()) return false;
|
||||
const entries = await getEntries(date);
|
||||
const last = entries.at(-1);
|
||||
if (!last) return false;
|
||||
await db.entries.update(last.id, { endTs: null });
|
||||
const boundary = day.endedTs;
|
||||
if (!Number.isFinite(boundary) || now < boundary) return false;
|
||||
if (mode === 'continue' && ['work', 'travel'].includes(last.kind)) {
|
||||
await db.entries.update(last.id, { endTs: null, automatic: false });
|
||||
} else {
|
||||
let seq = last.seq + 1;
|
||||
if (now > boundary) {
|
||||
if (mode === 'continue') await db.entries.update(last.id, { endTs: now, automatic: false });
|
||||
else await db.entries.add({ date, seq: seq++, kind: 'break', task: 'Pause', client: null, startTs: boundary, endTs: now });
|
||||
}
|
||||
const history = await db.entries.toArray();
|
||||
const work = history.filter((e) => e.kind === 'work' && e.date <= date)
|
||||
.sort((a, b) => b.date.localeCompare(a.date) || b.seq - a.seq)[0];
|
||||
await db.entries.add({ date, seq, kind: 'work', task: work?.task || 'Travaux sur site', client: work?.client ?? null, startTs: now, endTs: null });
|
||||
}
|
||||
await patchDay(date, {
|
||||
status: 'active', endedTs: null, closePromptedTs: null,
|
||||
plannedEndTs: Math.max(day.plannedEndTs, now + HOUR),
|
||||
@@ -230,13 +245,13 @@ export function setEntryStart(id, ts, now = Date.now()) {
|
||||
const list = await db.entries.where('date').equals(entry.date).sortBy('seq');
|
||||
const prev = list[list.findIndex((e) => e.id === id) - 1];
|
||||
|
||||
const lower = prev ? prev.startTs : Number.NEGATIVE_INFINITY;
|
||||
const lower = prev ? (prev.endTs === entry.startTs ? prev.startTs : prev.endTs) : Number.NEGATIVE_INFINITY;
|
||||
const upper = entry.endTs ?? now;
|
||||
const stored = Math.min(Math.max(ts, lower), upper);
|
||||
|
||||
await db.entries.update(entry.id, { startTs: stored, ...(entry.automatic ? { automatic: false } : {}) });
|
||||
if (prev) await db.entries.update(prev.id, { endTs: stored, ...(prev.automatic ? { automatic: false } : {}) });
|
||||
else await db.days.update(entry.date, { startedTs: stored });
|
||||
if (prev && prev.endTs === entry.startTs) await db.entries.update(prev.id, { endTs: stored, ...(prev.automatic ? { automatic: false } : {}) });
|
||||
else if (!prev) await db.days.update(entry.date, { startedTs: stored });
|
||||
|
||||
return stored;
|
||||
});
|
||||
@@ -257,11 +272,11 @@ export function deleteEntry(id) {
|
||||
const next = list[i + 1];
|
||||
|
||||
await db.entries.delete(id);
|
||||
if (prev) {
|
||||
if (prev && prev.endTs === victim.startTs && (!next || victim.endTs === next.startTs)) {
|
||||
// Extend the previous entry over the hole; if nothing follows, it inherits
|
||||
// the victim's end (including `null`, i.e. it becomes the running entry).
|
||||
await db.entries.update(prev.id, { endTs: next ? next.startTs : victim.endTs });
|
||||
} else if (next) {
|
||||
} else if (!prev && next && victim.endTs === next.startTs) {
|
||||
await db.entries.update(next.id, { startTs: victim.startTs });
|
||||
}
|
||||
// Re-number so `seq` stays dense.
|
||||
|
||||
Reference in New Issue
Block a user