Refactor calendar navigation with flexible day offsets
Improves date navigation by introducing dynamic period-based offsets for calendar views Replaces week-based navigation with more flexible day offsets that support: - Single-day and multi-day navigation - Configurable work week presets with different period lengths - More granular control over date range selection Adds support for dynamic navigation periods through workweek preset configuration
This commit is contained in:
parent
863b433eba
commit
fa2eb66fb2
5 changed files with 526 additions and 43 deletions
|
|
@ -24,7 +24,7 @@ import {
|
|||
export class CalendarApp {
|
||||
private animator!: NavigationAnimator;
|
||||
private container!: HTMLElement;
|
||||
private weekOffset = 0;
|
||||
private dayOffset = 0;
|
||||
private currentViewId = 'simple';
|
||||
private workweekPreset: IWorkweekPreset | null = null;
|
||||
private groupingOverrides: Map<string, string[]> = new Map();
|
||||
|
|
@ -126,13 +126,15 @@ export class CalendarApp {
|
|||
}
|
||||
|
||||
private async handleNavigatePrev(): Promise<void> {
|
||||
this.weekOffset--;
|
||||
const step = this.workweekPreset?.periodDays ?? 7;
|
||||
this.dayOffset -= step;
|
||||
await this.animator.slide('right', () => this.render());
|
||||
this.emitStatus('rendered', { viewId: this.currentViewId });
|
||||
}
|
||||
|
||||
private async handleNavigateNext(): Promise<void> {
|
||||
this.weekOffset++;
|
||||
const step = this.workweekPreset?.periodDays ?? 7;
|
||||
this.dayOffset += step;
|
||||
await this.animator.slide('left', () => this.render());
|
||||
this.emitStatus('rendered', { viewId: this.currentViewId });
|
||||
}
|
||||
|
|
@ -159,11 +161,15 @@ export class CalendarApp {
|
|||
return;
|
||||
}
|
||||
|
||||
// Populate date values based on workweek and offset
|
||||
// Populate date values based on workweek preset and day offset
|
||||
const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5];
|
||||
const dates = this.currentViewId === 'day'
|
||||
? this.dateService.getWeekDates(this.weekOffset, 1)
|
||||
: this.dateService.getWorkWeekDates(this.weekOffset, workDays);
|
||||
const periodDays = this.workweekPreset?.periodDays ?? 7;
|
||||
|
||||
// For single-day navigation (periodDays=1), show consecutive days from offset
|
||||
// For week navigation (periodDays=7), show workDays from the week containing offset
|
||||
const dates = periodDays === 1
|
||||
? this.dateService.getDatesFromOffset(this.dayOffset, workDays.length)
|
||||
: this.dateService.getWorkDaysFromOffset(this.dayOffset, workDays);
|
||||
|
||||
// Clone config and apply overrides
|
||||
const viewConfig: ViewConfig = {
|
||||
|
|
|
|||
|
|
@ -41,21 +41,30 @@ export class DateService {
|
|||
return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date);
|
||||
}
|
||||
|
||||
getWeekDates(offset = 0, days = 7): string[] {
|
||||
const monday = this.baseDate.startOf('week').add(1, 'day').add(offset, 'week');
|
||||
return Array.from({ length: days }, (_, i) =>
|
||||
monday.add(i, 'day').format('YYYY-MM-DD')
|
||||
/**
|
||||
* Get dates starting from a day offset
|
||||
* @param dayOffset - Day offset from base date
|
||||
* @param count - Number of consecutive days to return
|
||||
* @returns Array of date strings in YYYY-MM-DD format
|
||||
*/
|
||||
getDatesFromOffset(dayOffset: number, count: number): string[] {
|
||||
const startDate = this.baseDate.add(dayOffset, 'day');
|
||||
return Array.from({ length: count }, (_, i) =>
|
||||
startDate.add(i, 'day').format('YYYY-MM-DD')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dates for specific weekdays within a week
|
||||
* @param offset - Week offset from base date (0 = current week)
|
||||
* Get specific weekdays from the week containing the offset date
|
||||
* @param dayOffset - Day offset from base date
|
||||
* @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday)
|
||||
* @returns Array of date strings in YYYY-MM-DD format
|
||||
*/
|
||||
getWorkWeekDates(offset: number, workDays: number[]): string[] {
|
||||
const monday = this.baseDate.startOf('week').add(1, 'day').add(offset, 'week');
|
||||
getWorkDaysFromOffset(dayOffset: number, workDays: number[]): string[] {
|
||||
// Get the date at offset, then find its week's Monday
|
||||
const targetDate = this.baseDate.add(dayOffset, 'day');
|
||||
const monday = targetDate.startOf('week').add(1, 'day');
|
||||
|
||||
return workDays.map(isoDay => {
|
||||
// ISO: 1=Monday, 7=Sunday → days from Monday: 0-6
|
||||
const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1;
|
||||
|
|
@ -63,6 +72,15 @@ export class DateService {
|
|||
});
|
||||
}
|
||||
|
||||
// Legacy methods for backwards compatibility
|
||||
getWeekDates(weekOffset = 0, days = 7): string[] {
|
||||
return this.getDatesFromOffset(weekOffset * 7, days);
|
||||
}
|
||||
|
||||
getWorkWeekDates(weekOffset: number, workDays: number[]): string[] {
|
||||
return this.getWorkDaysFromOffset(weekOffset * 7, workDays);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// FORMATTING
|
||||
// ============================================
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export interface IWorkweekPreset {
|
|||
id: string;
|
||||
workDays: number[];
|
||||
label: string;
|
||||
periodDays: number; // Navigation step in days (1 = day, 7 = week)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue