mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:01:08 +02:00
fix(timeblocks): type errors from recurrence migration
- calendar/types: replace duplicate recurrenceRule with recurrenceDate on CalendarEvent; map it in timeBlockToCalendarEvent - recurrence: drop stale Record casts now that LocalTimeBlock types isRecurrenceException and recurrenceDate - todo: route recurrenceRule through TimeBlock in createTask/updateTask, load it from block in useTaskForm; accept labelIds via metadata; remove stale projectId casts - calendar/events: include linkedBlockId/parentBlockId/recurrenceDate in createDraftEvent - habits: drop unused db / LocalTimeBlock imports - eslint-config: disable consistent-type-imports (parser conflict with .svelte.ts files) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
af9b1f9369
commit
ce04f43248
8 changed files with 26 additions and 11 deletions
|
|
@ -195,7 +195,7 @@ export async function cleanupFutureInstances(templateBlockId: string): Promise<v
|
|||
|
||||
for (const instance of instances) {
|
||||
if (instance.deletedAt) continue;
|
||||
if ((instance as Record<string, unknown>).isRecurrenceException) continue;
|
||||
if (instance.isRecurrenceException) continue;
|
||||
if (instance.recurrenceDate && instance.recurrenceDate >= today) {
|
||||
await deleteBlock(instance.id);
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ export function expandTemplatesVirtually(
|
|||
const existingKeys = new Set(
|
||||
existingBlocks
|
||||
.filter((b) => b.parentBlockId)
|
||||
.map((b) => `${b.parentBlockId}|${(b as Record<string, unknown>).recurrenceDate}`)
|
||||
.map((b) => `${b.parentBlockId}|${b.recurrenceDate}`)
|
||||
);
|
||||
|
||||
const virtuals: VirtualTimeBlock[] = [];
|
||||
|
|
|
|||
|
|
@ -377,6 +377,9 @@ export const eventsStore = {
|
|||
icon: null,
|
||||
isLive: false,
|
||||
projectId: null,
|
||||
linkedBlockId: null,
|
||||
parentBlockId: null,
|
||||
recurrenceDate: null,
|
||||
};
|
||||
return draftEvent;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export interface CalendarEvent {
|
|||
projectId: string | null;
|
||||
linkedBlockId: string | null;
|
||||
parentBlockId: string | null;
|
||||
recurrenceRule: string | null;
|
||||
recurrenceDate: string | null;
|
||||
}
|
||||
|
||||
export interface Calendar {
|
||||
|
|
@ -107,5 +107,6 @@ export function timeBlockToCalendarEvent(
|
|||
projectId: block.projectId,
|
||||
linkedBlockId: block.linkedBlockId,
|
||||
parentBlockId: block.parentBlockId,
|
||||
recurrenceDate: block.recurrenceDate,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ import {
|
|||
materializeRecurringBlocks,
|
||||
regenerateForBlock,
|
||||
} from '$lib/data/time-blocks/recurrence';
|
||||
import { db } from '$lib/data/database';
|
||||
import type { LocalTimeBlock } from '$lib/data/time-blocks/types';
|
||||
import type { LocalHabit, LocalHabitLog, HabitSchedule } from '../types';
|
||||
|
||||
export const habitsStore = {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ export function useTaskForm() {
|
|||
title = task.title;
|
||||
description = task.description ?? '';
|
||||
dueDate = task.dueDate ? task.dueDate.split('T')[0] : '';
|
||||
// Load scheduled time from TimeBlock if scheduled
|
||||
// Load scheduled time + recurrence from TimeBlock if scheduled
|
||||
recurrenceRule = '';
|
||||
if (task.scheduledBlockId) {
|
||||
const block = await getBlock(task.scheduledBlockId);
|
||||
if (block) {
|
||||
|
|
@ -55,6 +56,7 @@ export function useTaskForm() {
|
|||
dueTime = block.startDate.includes('T')
|
||||
? block.startDate.split('T')[1]?.substring(0, 5)
|
||||
: '';
|
||||
recurrenceRule = block.recurrenceRule ?? '';
|
||||
}
|
||||
} else {
|
||||
dueTime = '';
|
||||
|
|
@ -63,7 +65,6 @@ export function useTaskForm() {
|
|||
priority = task.priority;
|
||||
status = task.status;
|
||||
subtasks = task.subtasks ? [...task.subtasks] : [];
|
||||
recurrenceRule = task.recurrenceRule ?? '';
|
||||
effectiveDuration = task.estimatedDuration ?? null;
|
||||
showDeleteConfirm = false;
|
||||
isLoading = false;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import type {
|
|||
export function toTask(local: LocalTask): Task {
|
||||
return {
|
||||
id: local.id,
|
||||
projectId: (local as Record<string, unknown>).projectId as string | null | undefined,
|
||||
projectId: local.projectId,
|
||||
title: local.title,
|
||||
description: local.description,
|
||||
dueDate: local.dueDate,
|
||||
|
|
@ -30,7 +30,6 @@ export function toTask(local: LocalTask): Task {
|
|||
isCompleted: local.isCompleted,
|
||||
completedAt: local.completedAt,
|
||||
order: local.order,
|
||||
recurrenceRule: local.recurrenceRule,
|
||||
subtasks: local.subtasks ?? null,
|
||||
metadata: local.metadata ?? null,
|
||||
createdAt: local.createdAt ?? new Date().toISOString(),
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export const tasksStore = {
|
|||
subtasks?: Subtask[];
|
||||
recurrenceRule?: string;
|
||||
estimatedDuration?: number;
|
||||
labelIds?: string[];
|
||||
// Optional: schedule on calendar
|
||||
scheduleStartDate?: string; // YYYY-MM-DD
|
||||
scheduleStartTime?: string; // HH:mm
|
||||
|
|
@ -49,6 +50,7 @@ export const tasksStore = {
|
|||
sourceId: taskId,
|
||||
title: data.title,
|
||||
projectId: data.projectId ?? null,
|
||||
recurrenceRule: data.recurrenceRule ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -62,12 +64,12 @@ export const tasksStore = {
|
|||
scheduledBlockId,
|
||||
estimatedDuration: data.estimatedDuration ?? null,
|
||||
order: count,
|
||||
recurrenceRule: data.recurrenceRule ?? null,
|
||||
subtasks: data.subtasks,
|
||||
metadata: data.labelIds && data.labelIds.length > 0 ? { labelIds: data.labelIds } : undefined,
|
||||
};
|
||||
|
||||
if (data.projectId !== undefined) {
|
||||
(newLocal as Record<string, unknown>).projectId = data.projectId;
|
||||
newLocal.projectId = data.projectId;
|
||||
}
|
||||
|
||||
await taskTable.add(newLocal);
|
||||
|
|
@ -82,8 +84,11 @@ export const tasksStore = {
|
|||
// Handle schedule changes via TimeBlock
|
||||
const schedStartDate = data._scheduleStartDate as string | null | undefined;
|
||||
const schedStartTime = data._scheduleStartTime as string | null | undefined;
|
||||
const recurrenceRule = data.recurrenceRule as string | null | undefined;
|
||||
delete data._scheduleStartDate;
|
||||
delete data._scheduleStartTime;
|
||||
// recurrenceRule lives on the TimeBlock — never on the task row
|
||||
delete data.recurrenceRule;
|
||||
|
||||
if (schedStartDate !== undefined) {
|
||||
if (schedStartDate) {
|
||||
|
|
@ -103,6 +108,7 @@ export const tasksStore = {
|
|||
endDate: endISO,
|
||||
allDay: !schedStartTime,
|
||||
title: (data.title as string) ?? task.title,
|
||||
...(recurrenceRule !== undefined ? { recurrenceRule } : {}),
|
||||
});
|
||||
} else {
|
||||
// Create new block
|
||||
|
|
@ -116,6 +122,7 @@ export const tasksStore = {
|
|||
sourceId: id,
|
||||
title: (data.title as string) ?? task.title,
|
||||
projectId: (data.projectId as string) ?? task.projectId ?? null,
|
||||
recurrenceRule: recurrenceRule ?? null,
|
||||
});
|
||||
data.scheduledBlockId = blockId;
|
||||
}
|
||||
|
|
@ -133,6 +140,11 @@ export const tasksStore = {
|
|||
await updateBlock(task.scheduledBlockId, { title: data.title as string });
|
||||
}
|
||||
|
||||
// Update recurrence on existing TimeBlock when not also rescheduling
|
||||
if (recurrenceRule !== undefined && schedStartDate === undefined && task.scheduledBlockId) {
|
||||
await updateBlock(task.scheduledBlockId, { recurrenceRule });
|
||||
}
|
||||
|
||||
await taskTable.update(id, {
|
||||
...data,
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export const typescriptConfig = [
|
|||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue