fix: hide close-week button when a tracked day is still open
Fetch entries for the week alongside days/weeks in the week view. canCloseWeek now mirrors the server rule: every past workday that has at least one entry must have a closed_days record. Days with no entries are still skipped (they count as 0h implicitly).
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { days, weeks, settings, type ClosedDay, type ClosedWeek, type Settings, ApiError } from '$lib/api/client';
|
||||
import { entries, days, weeks, settings, type Entry, type ClosedDay, type ClosedWeek, type Settings, ApiError } from '$lib/api/client';
|
||||
import {
|
||||
currentWeekKey, weekDayKeys, formatDurationShort, formatDelta, todayKey, isWorkday
|
||||
} from '$lib/utils';
|
||||
|
||||
let weekKey = $state(currentWeekKey());
|
||||
let dayKeys = $derived(weekDayKeys(weekKey));
|
||||
let closedDaysMap: Record<string, ClosedDay> = $state({});
|
||||
let closedWeek: ClosedWeek | null = $state(null);
|
||||
let closedDaysMap = $state<Record<string, ClosedDay>>({});
|
||||
let daysWithEntries = $state<Set<string>>(new Set());
|
||||
let closedWeek = $state<ClosedWeek | null>(null);
|
||||
let currentSettings = $state<Settings | null>(null);
|
||||
let error = $state('');
|
||||
|
||||
@@ -17,14 +18,19 @@
|
||||
const from = dayKeys[0];
|
||||
const to = dayKeys[6];
|
||||
try {
|
||||
const [ds, ws, s] = await Promise.all([
|
||||
const [ds, ws, s, es] = await Promise.all([
|
||||
days.list(from, to),
|
||||
weeks.list(weekKey, weekKey),
|
||||
settings.current()
|
||||
settings.current(),
|
||||
entries.list(from, to)
|
||||
]);
|
||||
closedDaysMap = Object.fromEntries((ds ?? []).map((d) => [d.day_key, d]));
|
||||
closedWeek = (ws ?? []).find((w) => w.week_key === weekKey) ?? null;
|
||||
currentSettings = s;
|
||||
// Track which day_keys have at least one entry (for close-week guard).
|
||||
const set = new Set<string>();
|
||||
for (const e of (es ?? [])) set.add(e.day_key);
|
||||
daysWithEntries = set;
|
||||
} catch (e) {
|
||||
error = e instanceof ApiError ? e.message : String(e);
|
||||
}
|
||||
@@ -61,10 +67,16 @@
|
||||
currentSettings ? currentSettings.hours_per_week * 3_600_000 : 0
|
||||
);
|
||||
|
||||
// Week can be closed if it's not already closed and the week has started
|
||||
// (i.e. Monday ≤ today). The server enforces the detailed per-day rules.
|
||||
// Week can be closed if it's not already closed, the week has started,
|
||||
// and every past workday that has entries is also closed.
|
||||
const canCloseWeek = $derived(
|
||||
!closedWeek && dayKeys[0] <= todayKey()
|
||||
!closedWeek &&
|
||||
dayKeys[0] <= todayKey() &&
|
||||
dayKeys.every((dk) => {
|
||||
if (dk > todayKey()) return true; // future day — skip
|
||||
if (!daysWithEntries.has(dk)) return true; // no entries — skip
|
||||
return !!closedDaysMap[dk]; // has entries → must be closed
|
||||
})
|
||||
);
|
||||
|
||||
function prevWeek() { weekKey = offsetWeek(weekKey, -1); }
|
||||
|
||||
Reference in New Issue
Block a user