Simplified edit mode

This commit is contained in:
2026-09-19 22:24:52 +02:00
parent d46a5f10af
commit 6f64475050
10 changed files with 113 additions and 77 deletions

View File

@@ -98,8 +98,3 @@ export function removeRecordedEntry(original) {
});
}
/** Native datetime-local inputs use wall time, never UTC. */
export function localInput(ts) {
const d = new Date(ts);
return `${localDateKey(ts)}T${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
}

View File

@@ -1,7 +1,7 @@
import 'fake-indexeddb/auto';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { closeAndStart, closeDay, createDay, db, exportBackup, getDay, getEntries } from './db.js';
import { insertRecordedEntry, localInput, removeRecordedEntry, saveRecordedEntry } from './editing.js';
import { insertRecordedEntry, removeRecordedEntry, saveRecordedEntry } from './editing.js';
import { buildResume, resumeToText } from './resume.js';
import { atLocalTime, HOUR } from './time.js';
@@ -51,8 +51,8 @@ describe('forgotten entries', () => {
const resume = buildResume(record, entries);
expect(record.status).toBe('closed'); expect(entries[1].client).toBeNull();
expect(resume.lunch).toEqual({ type: 'restaurant', restaurant: 'Le Relais', ms: HOUR });
expect(resume.workedMs).toBe(8 * HOUR); expect(resume.totalMs).toBe(9 * HOUR);
expect(resumeToText(resume)).toContain('Total journée (repas compris) : 9h00');
expect(resume.workedMs).toBe(8 * HOUR);
expect(resumeToText(resume)).toContain('Total travaillé : 8h00');
const backup = await exportBackup();
expect(backup.entries).toHaveLength(3); expect(backup.days[0].status).toBe('closed');
});
@@ -63,7 +63,7 @@ describe('forgotten entries', () => {
const original = (await getEntries(date))[1];
await insertRecordedEntry(original, values('12:15', '12:30'));
const result = buildResume(await getDay(date), await getEntries(date), 1);
expect(result.lunch.ms).toBe(0.75 * HOUR); expect(result.totalMs).toBe(9 * HOUR);
expect(result.lunch.ms).toBe(0.75 * HOUR); expect(result.workedMs).toBe(8.25 * HOUR);
});
it('keeps one running entry when inserting up to the present', async () => {
@@ -118,7 +118,7 @@ describe('recorded day corrections', () => {
await saveRecordedEntry(list.at(-1), values('13:00', '18:00'));
const record = await getDay(date);
expect(record).toMatchObject({ startedTs: at('07:30'), endedTs: at('18:00'), status: 'closed' });
expect(buildResume(record, await getEntries(date)).totalMs).toBe(10.5 * HOUR);
expect(buildResume(record, await getEntries(date)).workedMs).toBe(10.5 * HOUR);
expect(await getDay(other.date)).toEqual(other);
expect((await getEntries(other.date))[0].endTs).toBeNull();
});
@@ -127,7 +127,7 @@ describe('recorded day corrections', () => {
const list = await seed([entry(0, '08:00', '10:00'), entry(1, '11:00', '17:00')]);
await saveRecordedEntry(list[1], values('11:00', '17:00'));
expect((await getEntries(date))[0].endTs).toBe(at('10:00'));
expect(buildResume(await getDay(date), await getEntries(date)).totalMs).toBe(9 * HOUR);
expect(buildResume(await getDay(date), await getEntries(date)).workedMs).toBe(8 * HOUR);
});
it('rejects overlaps beyond neighbours and future timestamps without writes', async () => {
@@ -167,7 +167,5 @@ describe('recorded day corrections', () => {
expect(await getEntries(date)).toHaveLength(1);
});
it('formats local input without a UTC conversion', () => {
expect(localInput(at('07:42'))).toBe('2026-09-07T07:42');
});
});

View File

@@ -67,8 +67,6 @@ export function buildResume(day, entries, roundingMinutes = 15) {
clients,
lunch,
workedMs,
totalMs: Math.max(0, roundTs(fallbackEnd, roundingMinutes) -
roundTs(day.startedTs ?? Math.min(...entries.map((e) => e.startTs), fallbackEnd), roundingMinutes)),
omitted,
};
}
@@ -101,8 +99,7 @@ export function resumeToText(resume) {
lines.push('');
}
lines.push(`Travail hors repas : ${fmtDuration(resume.workedMs)}`);
lines.push(`Total journée (repas compris) : ${fmtDuration(resume.totalMs)}`);
lines.push(`Total travaillé : ${fmtDuration(resume.workedMs)}`);
return lines.join('\n').replace(/\n{3,}/g, '\n\n').trim();
}

View File

@@ -40,7 +40,6 @@ describe('buildResume', () => {
it('keeps lunch out of the worked total', () => {
const r = buildResume(DAY, ENTRIES, 15);
expect(r.workedMs).toBe(9 * 60 * MINUTE); // 09h00 on site, lunch excluded
expect(r.totalMs).toBe(10 * 60 * MINUTE);
expect(r.lunch).toEqual({ type: 'restaurant', restaurant: 'Le Relais', ms: 60 * MINUTE });
});
@@ -93,8 +92,7 @@ describe('resumeToText', () => {
'',
'Déjeuner : restaurant (Le Relais), 1h00',
'',
'Travail hors repas : 9h00',
'Total journée (repas compris) : 10h00',
'Total travaillé : 9h00',
].join('\n'),
);
});