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">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
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 {
|
import {
|
||||||
currentWeekKey, weekDayKeys, formatDurationShort, formatDelta, todayKey, isWorkday
|
currentWeekKey, weekDayKeys, formatDurationShort, formatDelta, todayKey, isWorkday
|
||||||
} from '$lib/utils';
|
} from '$lib/utils';
|
||||||
|
|
||||||
let weekKey = $state(currentWeekKey());
|
let weekKey = $state(currentWeekKey());
|
||||||
let dayKeys = $derived(weekDayKeys(weekKey));
|
let dayKeys = $derived(weekDayKeys(weekKey));
|
||||||
let closedDaysMap: Record<string, ClosedDay> = $state({});
|
let closedDaysMap = $state<Record<string, ClosedDay>>({});
|
||||||
let closedWeek: ClosedWeek | null = $state(null);
|
let daysWithEntries = $state<Set<string>>(new Set());
|
||||||
|
let closedWeek = $state<ClosedWeek | null>(null);
|
||||||
let currentSettings = $state<Settings | null>(null);
|
let currentSettings = $state<Settings | null>(null);
|
||||||
let error = $state('');
|
let error = $state('');
|
||||||
|
|
||||||
@@ -17,14 +18,19 @@
|
|||||||
const from = dayKeys[0];
|
const from = dayKeys[0];
|
||||||
const to = dayKeys[6];
|
const to = dayKeys[6];
|
||||||
try {
|
try {
|
||||||
const [ds, ws, s] = await Promise.all([
|
const [ds, ws, s, es] = await Promise.all([
|
||||||
days.list(from, to),
|
days.list(from, to),
|
||||||
weeks.list(weekKey, weekKey),
|
weeks.list(weekKey, weekKey),
|
||||||
settings.current()
|
settings.current(),
|
||||||
|
entries.list(from, to)
|
||||||
]);
|
]);
|
||||||
closedDaysMap = Object.fromEntries((ds ?? []).map((d) => [d.day_key, d]));
|
closedDaysMap = Object.fromEntries((ds ?? []).map((d) => [d.day_key, d]));
|
||||||
closedWeek = (ws ?? []).find((w) => w.week_key === weekKey) ?? null;
|
closedWeek = (ws ?? []).find((w) => w.week_key === weekKey) ?? null;
|
||||||
currentSettings = s;
|
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) {
|
} catch (e) {
|
||||||
error = e instanceof ApiError ? e.message : String(e);
|
error = e instanceof ApiError ? e.message : String(e);
|
||||||
}
|
}
|
||||||
@@ -61,10 +67,16 @@
|
|||||||
currentSettings ? currentSettings.hours_per_week * 3_600_000 : 0
|
currentSettings ? currentSettings.hours_per_week * 3_600_000 : 0
|
||||||
);
|
);
|
||||||
|
|
||||||
// Week can be closed if it's not already closed and the week has started
|
// Week can be closed if it's not already closed, the week has started,
|
||||||
// (i.e. Monday ≤ today). The server enforces the detailed per-day rules.
|
// and every past workday that has entries is also closed.
|
||||||
const canCloseWeek = $derived(
|
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); }
|
function prevWeek() { weekKey = offsetWeek(weekKey, -1); }
|
||||||
|
|||||||
Reference in New Issue
Block a user