fix(tasks): keep a task whole through import and edit, and fix two counts
Review found that import and edit rebuilt a task from this build's parse. That stripped any field it didn't know, and import dropped a newer version's task entirely. Both now keep the record as stored and validate only to display it. An event whose goal is points can't be ticked, so it no longer counts as waiting today: it counts with its week. The month-day field reset itself to 1 when emptied; it now keeps a draft. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
54d8424d1e
commit
5a4c746a44
7 files changed
+110
-28
No files matched your search
@@ -13,23 +13,32 @@ export interface TaskFields {
|
||||
title: string;
|
||||
unit: "week" | "month";
|
||||
weekday: number;
|
||||
monthDay: number;
|
||||
/** As typed, so the field can be emptied and retyped; read through `parseMonthDay`. */
|
||||
monthDay: string | number;
|
||||
kind: "days" | "amount";
|
||||
required: string;
|
||||
target: string;
|
||||
amountUnit: string;
|
||||
}
|
||||
|
||||
/** A typed day of the month, clamped to 1–31; null while empty or unreadable. */
|
||||
export function parseMonthDay(raw: string): number | null {
|
||||
const n = Number.parseInt(raw, 10);
|
||||
return Number.isFinite(n) ? Math.min(31, Math.max(1, n)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The task these fields describe, or null while they do not describe one the
|
||||
* store would accept. Checked against `TaskSchema` itself, so the form can
|
||||
* never offer Save on something the store would then refuse.
|
||||
*/
|
||||
export function taskDraftFrom(f: TaskFields): TaskDraft | null {
|
||||
const monthDay = parseMonthDay(String(f.monthDay));
|
||||
if (f.unit === "month" && monthDay === null) return null;
|
||||
const period =
|
||||
f.unit === "week"
|
||||
? ({ unit: "week", startsOn: f.weekday } as const)
|
||||
: ({ unit: "month", startsOn: f.monthDay } as const);
|
||||
: ({ unit: "month", startsOn: monthDay ?? 1 } as const);
|
||||
const unit = f.amountUnit.trim();
|
||||
const target = parseAmount(f.target);
|
||||
const measure =
|
||||
@@ -78,7 +87,7 @@ export function TaskForm({
|
||||
title: initial?.title ?? "",
|
||||
unit: initial?.period.unit ?? "week",
|
||||
weekday: initial?.period.unit === "week" ? initial.period.startsOn : 1,
|
||||
monthDay: initial?.period.unit === "month" ? initial.period.startsOn : 1,
|
||||
monthDay: String(initial?.period.unit === "month" ? initial.period.startsOn : 1),
|
||||
kind: initial?.measure.kind ?? "days",
|
||||
required: initial?.measure.kind === "days" ? String(initial.measure.required) : "1",
|
||||
target: initial?.measure.kind === "amount" ? String(initial.measure.target) : "",
|
||||
@@ -156,7 +165,7 @@ export function TaskForm({
|
||||
min={1}
|
||||
max={31}
|
||||
value={f.monthDay}
|
||||
onChange={(e) => set({ monthDay: Number.parseInt(e.target.value, 10) || 1 })}
|
||||
onChange={(e) => set({ monthDay: e.target.value })}
|
||||
className={`tnum w-14 ${field}`}
|
||||
/>
|
||||
</label>
|
||||
|
||||
Reference in new issue
Block a user