fix(types): resolve all client TypeScript errors (attendance + plan rollback)

- AttendanceAdmin: declare worked_hours_raw on UserTotalData (the hook sets it at runtime; the local interface omitted it)
- usePlanWork.rollbackMutation: type the mutation param as unknown + explicit cast so passing the TanStack mutation result (with the dynamically-stashed _rolled) no longer trips the weak-type check
tsc -p tsconfig.app.json --noEmit is now clean (0 errors, was 9).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-06 01:20:24 +02:00
parent e845400fca
commit 4a78d31a7f
2 changed files with 14 additions and 7 deletions

View File

@@ -466,23 +466,27 @@ export function usePlanWork({ initialDate, canEdit }: UsePlanWorkArgs) {
// Roll back an optimistic patch on mutation error. Called from // Roll back an optimistic patch on mutation error. Called from
// PlanWork's mutation wrappers via `rollbackMutation(mutation, key)`. // PlanWork's mutation wrappers via `rollbackMutation(mutation, key)`.
function rollbackMutation( // `mutation` is a TanStack mutation result with a `_rolled` snapshot stashed
mutation: { _rolled?: Record<string, ResolvedCell | null> | null }, // on it (see the `(createEntry as any)._rolled = …` writes above). Typed as
userId: number, // `unknown` + an explicit cast so callers can pass the mutation object
) { // directly without the "weak type" mismatch a `{ _rolled? }` param causes.
if (!mutation._rolled) return; function rollbackMutation(mutation: unknown, userId: number) {
const stash = mutation as {
_rolled?: Record<string, ResolvedCell | null> | null;
};
if (!stash._rolled) return;
const prev = qc.getQueryData<GridData>(currentGridKey as any); const prev = qc.getQueryData<GridData>(currentGridKey as any);
if (!prev) return; if (!prev) return;
const userPrev = prev.cells[userId] ?? {}; const userPrev = prev.cells[userId] ?? {};
const userNext = { ...userPrev }; const userNext = { ...userPrev };
for (const [date, cell] of Object.entries(mutation._rolled)) { for (const [date, cell] of Object.entries(stash._rolled)) {
userNext[date] = cell; userNext[date] = cell;
} }
qc.setQueryData(currentGridKey, { qc.setQueryData(currentGridKey, {
...prev, ...prev,
cells: { ...prev.cells, [userId]: userNext }, cells: { ...prev.cells, [userId]: userNext },
}); });
mutation._rolled = null; stash._rolled = null;
} }
return { return {

View File

@@ -21,6 +21,9 @@ interface UserTotalData {
unpaid_hours: number; unpaid_hours: number;
fund: number | null; fund: number | null;
worked_hours: number; worked_hours: number;
// Raw worked hours incl. sub-day remainders (set by computeUserTotals in
// useAttendanceAdmin); used for the Fond "used" calculation below.
worked_hours_raw?: number;
covered: number; covered: number;
missing: number; missing: number;
overtime: number; overtime: number;