diff --git a/src/components/features/calendar/index.ts b/src/components/features/calendar/index.ts index 593d609d..94df6769 100644 --- a/src/components/features/calendar/index.ts +++ b/src/components/features/calendar/index.ts @@ -64,6 +64,10 @@ export class CalendarComponent extends Component { private badgeEventsCache: Map = new Map(); private badgeEventsCacheVersion: number = 0; + + // Per-view override from Bases (firstDayOfWeek, hideWeekends, ...) + private configOverride: Partial | null = null; + constructor( app: App, plugin: TaskProgressBarPlugin, @@ -92,6 +96,7 @@ export class CalendarComponent extends Component { this.currentViewMode = viewMode as CalendarViewMode; } + console.log("CalendarComponent initialized with params:", this.params); } @@ -107,6 +112,8 @@ export class CalendarComponent extends Component { override onunload() { super.onunload(); // Detach the active view component if it exists + + if (this.activeViewComponent) { this.removeChild(this.activeViewComponent); this.activeViewComponent = null; @@ -132,6 +139,8 @@ export class CalendarComponent extends Component { this.invalidateBadgeEventsCache(); this.processTasks(); // Only update the currently active view + + if (this.activeViewComponent) { this.activeViewComponent.updateEvents(this.events); } else { @@ -153,6 +162,8 @@ export class CalendarComponent extends Component { this.app.saveLocalStorage( "task-genius:calendar-view", this.currentViewMode + + ); } } @@ -169,6 +180,7 @@ export class CalendarComponent extends Component { this.currentDate.add(1, unit); } this.render(); // Re-render header and update the view + } /** @@ -304,6 +316,7 @@ export class CalendarComponent extends Component { ); switch (this.currentViewMode) { case "month": + const effMonth = this.getEffectiveCalendarConfig(); nextViewComponent = new MonthView( this.app, this.plugin, @@ -320,10 +333,12 @@ export class CalendarComponent extends Component { onEventComplete: this.onEventComplete, getBadgeEventsForDate: this.getBadgeEventsForDate.bind(this), - } + }, + effMonth ); break; case "week": + const effWeek = this.getEffectiveCalendarConfig(); nextViewComponent = new WeekView( this.app, this.plugin, @@ -340,7 +355,8 @@ export class CalendarComponent extends Component { onEventComplete: this.onEventComplete, getBadgeEventsForDate: this.getBadgeEventsForDate.bind(this), - } + }, + effWeek ); break; case "day": @@ -374,6 +390,7 @@ export class CalendarComponent extends Component { ); break; case "year": + const effYear = this.getEffectiveCalendarConfig(); nextViewComponent = new YearView( this.app, this.plugin, @@ -387,7 +404,8 @@ export class CalendarComponent extends Component { onDayHover: this.onDayHover, onMonthClick: this.onMonthClick, onMonthHover: this.onMonthHover, - } + }, + effYear ); break; default: @@ -690,11 +708,9 @@ export class CalendarComponent extends Component { const startOfMonth = this.currentDate.clone().startOf("month"); const endOfMonth = this.currentDate.clone().endOf("month"); - // Get first day of week setting - const viewConfig = this.plugin.settings.viewConfiguration.find( - (v) => v.id === this.viewId - )?.specificConfig as any; // Use any for now to avoid import complexity - const firstDayOfWeek = viewConfig?.firstDayOfWeek ?? 0; + // Get first day of week setting (effective with override) + const effCfg = this.getEffectiveCalendarConfig(); + const firstDayOfWeek = effCfg.firstDayOfWeek ?? 0; const gridStart = startOfMonth .clone() @@ -917,6 +933,21 @@ export class CalendarComponent extends Component { public onEventComplete = (ev: MouseEvent, event: CalendarEvent) => { this.params?.onTaskCompleted?.(event); }; + + // Allow external overrides (e.g., from Bases) and compute effective config + public setConfigOverride( + override: Partial | null + ): void { + this.configOverride = override ?? null; + // Re-render to apply new config + this.render(); + } + + private getEffectiveCalendarConfig(): Partial { + const baseCfg = this.plugin.settings.viewConfiguration.find((v) => v.id === this.viewId)?.specificConfig as Partial | undefined; + return { ...(baseCfg ?? {}), ...(this.configOverride ?? {}) }; + } + } // Helper function (example - might move to a utils file) diff --git a/src/components/features/calendar/views/month-view.ts b/src/components/features/calendar/views/month-view.ts index b6523034..c610a8b3 100644 --- a/src/components/features/calendar/views/month-view.ts +++ b/src/components/features/calendar/views/month-view.ts @@ -29,6 +29,7 @@ export class MonthView extends CalendarViewComponent { private app: App; // Keep app reference if needed directly private plugin: TaskProgressBarPlugin; // Keep plugin reference if needed directly private sortableInstances: Sortable[] = []; // Store sortable instances for cleanup + private overrideConfig?: Partial; constructor( app: App, @@ -37,21 +38,23 @@ export class MonthView extends CalendarViewComponent { private currentViewId: string, currentDate: moment.Moment, events: CalendarEvent[], - options: CalendarViewOptions // Use the base options type + options: CalendarViewOptions, // Use the base options type + overrideConfig?: Partial ) { super(plugin, app, containerEl, events, options); // Call base constructor this.app = app; // Still store app if needed directly this.plugin = plugin; // Still store plugin if needed directly this.currentDate = currentDate; + this.overrideConfig = overrideConfig; } render(): void { - // Get view settings, including the first day of the week override and weekend hiding + // Get view settings, prefer override values when provided const viewConfig = this.plugin.settings.viewConfiguration.find( (v) => v.id === this.currentViewId - )?.specificConfig as CalendarSpecificConfig; // Assuming 'calendar' view for settings lookup, adjust if needed - const firstDayOfWeekSetting = viewConfig?.firstDayOfWeek; - const hideWeekends = viewConfig?.hideWeekends ?? false; + )?.specificConfig as CalendarSpecificConfig; + const firstDayOfWeekSetting = this.overrideConfig?.firstDayOfWeek ?? viewConfig?.firstDayOfWeek; + const hideWeekends = (this.overrideConfig?.hideWeekends ?? viewConfig?.hideWeekends) ?? false; // Default to Sunday (0) if the setting is undefined, following 0=Sun, 1=Mon, ..., 6=Sat const effectiveFirstDay = firstDayOfWeekSetting === undefined ? 0 : firstDayOfWeekSetting; diff --git a/src/components/features/calendar/views/week-view.ts b/src/components/features/calendar/views/week-view.ts index d937c19c..9177fef7 100644 --- a/src/components/features/calendar/views/week-view.ts +++ b/src/components/features/calendar/views/week-view.ts @@ -20,6 +20,8 @@ export class WeekView extends CalendarViewComponent { private app: App; // Keep app reference private plugin: TaskProgressBarPlugin; // Keep plugin reference private sortableInstances: Sortable[] = []; // Store sortable instances for cleanup + private overrideConfig?: Partial; + // Removed onEventClick/onMouseHover properties, now in this.options constructor( @@ -29,25 +31,25 @@ export class WeekView extends CalendarViewComponent { private currentViewId: string, currentDate: moment.Moment, events: CalendarEvent[], - options: CalendarViewOptions // Use the base options type + options: CalendarViewOptions, // Use the base options type + overrideConfig?: Partial ) { super(plugin, app, containerEl, events, options); // Call base constructor this.app = app; // Store app this.plugin = plugin; // Store plugin this.currentDate = currentDate; + this.overrideConfig = overrideConfig; } render(): void { - // Get view settings, including the first day of the week override and weekend hiding + // Get view settings, prefer override values when provided const viewConfig = getViewSettingOrDefault( this.plugin, this.currentViewId ); console.log("viewConfig calendar", viewConfig); - const firstDayOfWeekSetting = ( - viewConfig.specificConfig as CalendarSpecificConfig - ).firstDayOfWeek; - const hideWeekends = (viewConfig.specificConfig as CalendarSpecificConfig)?.hideWeekends ?? false; + const firstDayOfWeekSetting = (this.overrideConfig?.firstDayOfWeek ?? (viewConfig.specificConfig as CalendarSpecificConfig).firstDayOfWeek); + const hideWeekends = (this.overrideConfig?.hideWeekends ?? (viewConfig.specificConfig as CalendarSpecificConfig)?.hideWeekends) ?? false; // Default to Sunday (0) if the setting is undefined, following 0=Sun, 1=Mon, ..., 6=Sat const effectiveFirstDay = firstDayOfWeekSetting === undefined ? 0 : firstDayOfWeekSetting; @@ -369,7 +371,7 @@ export class WeekView extends CalendarViewComponent { taskId: calendarEvent.id, updates: updatedTask, }); - + if (!result.success) { throw new Error(`Failed to update task: ${result.error}`); } diff --git a/src/components/features/calendar/views/year-view.ts b/src/components/features/calendar/views/year-view.ts index 08f066db..a6f7fba7 100644 --- a/src/components/features/calendar/views/year-view.ts +++ b/src/components/features/calendar/views/year-view.ts @@ -18,6 +18,8 @@ export class YearView extends CalendarViewComponent { private app: App; // Keep app reference private plugin: TaskProgressBarPlugin; // Keep plugin reference // Removed specific click/hover properties, use this.options + private overrideConfig?: Partial; + constructor( app: App, @@ -25,12 +27,14 @@ export class YearView extends CalendarViewComponent { containerEl: HTMLElement, currentDate: moment.Moment, events: CalendarEvent[], - options: CalendarViewOptions // Use base options type + options: CalendarViewOptions, // Use base options type + overrideConfig?: Partial ) { super(plugin, app, containerEl, events, options); // Call base constructor this.app = app; this.plugin = plugin; this.currentDate = currentDate; + this.overrideConfig = overrideConfig; } render(): void { @@ -64,12 +68,10 @@ export class YearView extends CalendarViewComponent { } events for year ${year} in ${endTimeFilter - startTimeFilter}ms` ); // Log filtering time - // Get view settings (assuming 'calendar' or a 'year' specific setting) + // Get view settings (prefer override when provided) const viewConfig = getViewSettingOrDefault(this.plugin, "calendar"); // Adjust if needed - const firstDayOfWeekSetting = ( - viewConfig.specificConfig as CalendarSpecificConfig - ).firstDayOfWeek; - const hideWeekends = (viewConfig.specificConfig as CalendarSpecificConfig)?.hideWeekends ?? false; + const firstDayOfWeekSetting = (this.overrideConfig?.firstDayOfWeek ?? (viewConfig.specificConfig as CalendarSpecificConfig).firstDayOfWeek); + const hideWeekends = (this.overrideConfig?.hideWeekends ?? (viewConfig.specificConfig as CalendarSpecificConfig)?.hideWeekends) ?? false; // Add hide-weekends class if weekend hiding is enabled if (hideWeekends) { diff --git a/src/components/features/kanban/kanban.ts b/src/components/features/kanban/kanban.ts index f7963fd0..ab689830 100644 --- a/src/components/features/kanban/kanban.ts +++ b/src/components/features/kanban/kanban.ts @@ -55,7 +55,7 @@ export class KanbanComponent extends Component { private columnSortableInstance: Sortable | null = null; private tasks: Task[] = []; private allTasks: Task[] = []; - private currentViewId: string = "kanban"; // 新增:当前视图ID + private currentViewId = "kanban"; // 新增:当前视图ID private columnOrder: string[] = []; private params: { onTaskStatusUpdate?: ( @@ -74,7 +74,7 @@ export class KanbanComponent extends Component { order: "desc", label: "Priority (High to Low)", }; - private hideEmptyColumns: boolean = false; + private hideEmptyColumns = false; private configOverride: Partial | null = null; // Configuration override from Bases view constructor( @@ -91,7 +91,7 @@ export class KanbanComponent extends Component { onTaskCompleted?: (task: Task) => void; onTaskContextMenu?: (ev: MouseEvent, task: Task) => void; } = {}, - viewId: string = "kanban" // 新增:视图ID参数 + viewId = "kanban" // 新增:视图ID参数 ) { super(); this.app = app; @@ -534,7 +534,7 @@ export class KanbanComponent extends Component { // Resolve effective config (Bases override wins over plugin settings) const kanbanConfig = this.getEffectiveKanbanConfig(); - console.log('[Kanban] renderColumns effective config', kanbanConfig); + console.log('[Kanban] renderColumns effective config', kanbanConfig); const groupBy = kanbanConfig?.groupBy || "status"; diff --git a/src/components/features/quadrant/quadrant.ts b/src/components/features/quadrant/quadrant.ts index fe85ae6e..438a9e74 100644 --- a/src/components/features/quadrant/quadrant.ts +++ b/src/components/features/quadrant/quadrant.ts @@ -7,6 +7,7 @@ import "@/styles/quadrant/quadrant.css"; import { t } from "@/translations/helper"; import { FilterComponent } from "@/components/features/task/filter/in-view/filter"; import { ActiveFilter } from "@/components/features/task/filter/in-view/filter-type"; +import { QuadrantSpecificConfig } from "@/common/setting-definition"; export interface QuadrantSortOption { field: @@ -95,6 +96,10 @@ export class QuadrantComponent extends Component { }; private hideEmptyColumns: boolean = false; + // Per-view override from Bases + private configOverride: Partial | null = null; + + // Quadrant-specific configuration private get quadrantConfig() { const view = this.plugin.settings.viewConfiguration.find( @@ -105,19 +110,18 @@ export class QuadrantComponent extends Component { view.specificConfig && view.specificConfig.viewType === "quadrant" ) { - return view.specificConfig as any; + return { ...(view.specificConfig as any), ...(this.configOverride ?? {}) }; } // Fallback to default quadrant config const defaultView = this.plugin.settings.viewConfiguration.find( (v) => v.id === "quadrant" ); - return ( - (defaultView?.specificConfig as any) || { - urgentTag: "#urgent", - importantTag: "#important", - urgentThresholdDays: 3, - } - ); + const base = (defaultView?.specificConfig as any) || { + urgentTag: "#urgent", + importantTag: "#important", + urgentThresholdDays: 3, + }; + return { ...base, ...(this.configOverride ?? {}) }; } constructor( @@ -144,6 +148,8 @@ export class QuadrantComponent extends Component { this.containerEl = parentEl.createDiv( "tg-quadrant-component-container" ); + + this.tasks = initialTasks; this.params = params; } @@ -153,6 +159,14 @@ export class QuadrantComponent extends Component { this.render(); } + + public setConfigOverride(override: Partial | null): void { + this.configOverride = override ?? null; + // Re-render to apply new config safely + this.cleanup(); + this.render(); + } + override onunload() { this.cleanup(); super.onunload(); diff --git a/src/components/features/task/view/forecast.ts b/src/components/features/task/view/forecast.ts index 59e8cb3e..9a64e320 100644 --- a/src/components/features/task/view/forecast.ts +++ b/src/components/features/task/view/forecast.ts @@ -60,6 +60,10 @@ export class ForecastComponent extends Component { private treeComponents: TaskTreeItemComponent[] = []; private allTasksMap: Map = new Map(); + + // Per-view override from Bases + private configOverride: Partial | null = null; + constructor( private parentEl: HTMLElement, private app: App, @@ -77,6 +81,8 @@ export class ForecastComponent extends Component { super(); // Initialize dates this.currentDate = new Date(); + + this.currentDate.setHours(0, 0, 0, 0); this.selectedDate = new Date(this.currentDate); } @@ -155,6 +161,50 @@ export class ForecastComponent extends Component { this.registerDomEvent(window, "focus", this.windowFocusHandler); } + public setConfigOverride(override: Partial | null): void { + this.configOverride = override ?? null; + this.rebuildCalendarWithEffectiveOptions(); + } + + private getEffectiveForecastConfig(): Partial { + const baseCfg = this.plugin.settings.viewConfiguration.find((v) => v.id === "forecast")?.specificConfig as ForecastSpecificConfig | undefined; + return { ...(baseCfg ?? {}), ...(this.configOverride ?? {}) }; + } + + private rebuildCalendarWithEffectiveOptions(): void { + if (!this.calendarContainerEl) return; + // Remove old calendar component if exists + if (this.calendarComponent) { + this.removeChild(this.calendarComponent); + } + this.calendarContainerEl.empty(); + const eff = this.getEffectiveForecastConfig(); + const calendarOptions: Partial = { + firstDayOfWeek: eff.firstDayOfWeek ?? 0, + showWeekends: !(eff.hideWeekends ?? false), + showTaskCounts: true, + }; + this.calendarComponent = new CalendarComponent(this.calendarContainerEl, calendarOptions); + this.addChild(this.calendarComponent); + this.calendarComponent.load(); + // Restore state and tasks + this.calendarComponent.setCurrentDate(this.currentDate); + this.calendarComponent.selectDate(this.selectedDate); + this.calendarComponent.setTasks(this.allTasks); + // Rebind selection handler + this.calendarComponent.onDateSelected = (date, tasks) => { + const selectedDate = new Date(date); + selectedDate.setHours(0, 0, 0, 0); + this.selectedDate = selectedDate; + this.updateDueSoonSection(); + this.refreshDateSectionsUI(); + if (Platform.isPhone) { + this.toggleLeftColumnVisibility(false); + } + }; + } + + private createForecastHeader() { this.forecastHeaderEl = this.taskContainerEl.createDiv({ cls: "forecast-header", @@ -293,22 +343,15 @@ export class ForecastComponent extends Component { cls: "forecast-calendar-section", }); - // Create and initialize calendar component - const forecastConfig = this.plugin.settings.viewConfiguration.find( - (view) => view.id === "forecast" - )?.specificConfig as ForecastSpecificConfig; - - // Convert ForecastSpecificConfig to CalendarOptions + // Create and initialize calendar component using effective config (Bases override + settings) + const eff = this.getEffectiveForecastConfig(); const calendarOptions: Partial = { - firstDayOfWeek: forecastConfig?.firstDayOfWeek ?? 0, - showWeekends: !(forecastConfig?.hideWeekends ?? false), // Invert hideWeekends to showWeekends + firstDayOfWeek: eff.firstDayOfWeek ?? 0, + showWeekends: !(eff.hideWeekends ?? false), // Invert hideWeekends to showWeekends showTaskCounts: true, }; - this.calendarComponent = new CalendarComponent( - this.calendarContainerEl, - calendarOptions - ); + this.calendarComponent = new CalendarComponent(this.calendarContainerEl, calendarOptions); this.addChild(this.calendarComponent); this.calendarComponent.load(); @@ -983,23 +1026,23 @@ export class ForecastComponent extends Component { // 基于选择日期重新分类所有任务 const selectedTimestamp = new Date(this.selectedDate).setHours(0, 0, 0, 0); - + // 获取有相关日期的任务 const tasksWithRelevantDate = this.allTasks.filter( (task) => this.getRelevantDate(task) !== undefined ); - + // 相对于选择日期重新分类 const pastTasksRelativeToSelected = tasksWithRelevantDate.filter((task) => { const relevantTimestamp = this.getRelevantDate(task)!; return relevantTimestamp < selectedTimestamp; }); - + const selectedDateTasks = tasksWithRelevantDate.filter((task) => { const relevantTimestamp = this.getRelevantDate(task)!; return relevantTimestamp === selectedTimestamp; }); - + const futureTasksRelativeToSelected = tasksWithRelevantDate.filter((task) => { const relevantTimestamp = this.getRelevantDate(task)!; return relevantTimestamp > selectedTimestamp; diff --git a/src/pages/bases/registerBasesViews.ts b/src/pages/bases/registerBasesViews.ts index 2e737308..ff788cc8 100644 --- a/src/pages/bases/registerBasesViews.ts +++ b/src/pages/bases/registerBasesViews.ts @@ -88,6 +88,13 @@ const TASK_GENIUS_BASES_VIEWS: TaskGeniusBasesViewType[] = [ defaultViewMode: 'flagged', description: 'View high-priority flagged tasks' }, + { + id: 'task-genius-quadrant', + name: 'Quadrant (Task Genius)', + icon: 'lucide-grid', + defaultViewMode: 'quadrant', + description: 'Organize tasks using the Eisenhower Matrix' + } ]; /**