Remove resource calendar mode support
Simplifies calendar configuration and removes resource-specific code paths Eliminates complexity around resource-based calendar rendering by: - Removing ResourceCalendarData type - Removing resource-specific renderers and managers - Streamlining event and grid management logic - Consolidating to single date-based calendar implementation
This commit is contained in:
parent
349e1e8293
commit
cda201301c
16 changed files with 65 additions and 323 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Calendar configuration management
|
||||
// Pure static configuration class - no dependencies, no events
|
||||
|
||||
import { ICalendarConfig, ViewPeriod, CalendarMode } from '../types/CalendarTypes';
|
||||
import { ICalendarConfig, ViewPeriod } from '../types/CalendarTypes';
|
||||
import { TimeFormatter, TimeFormatSettings } from '../utils/TimeFormatter';
|
||||
|
||||
/**
|
||||
|
|
@ -61,18 +61,6 @@ interface WorkWeekSettings {
|
|||
firstWorkDay: number; // ISO: 1 = Monday, 7 = Sunday
|
||||
}
|
||||
|
||||
/**
|
||||
* View settings for resource-based calendar mode
|
||||
*/
|
||||
interface ResourceViewSettings {
|
||||
maxResources: number; // Maximum resources to display
|
||||
showAvatars: boolean; // Display user avatars
|
||||
avatarSize: number; // Avatar size in pixels
|
||||
resourceNameFormat: 'full' | 'short'; // How to display names
|
||||
showResourceDetails: boolean; // Show additional resource info
|
||||
showAllDay: boolean; // Show all-day event row
|
||||
}
|
||||
|
||||
/**
|
||||
* Time format configuration settings
|
||||
*/
|
||||
|
|
@ -116,7 +104,6 @@ export class CalendarConfig {
|
|||
maxEventDuration: 480 // 8 hours
|
||||
};
|
||||
|
||||
private static calendarMode: CalendarMode = 'date';
|
||||
private static selectedDate: Date | null = new Date();
|
||||
private static currentWorkWeek: string = 'standard';
|
||||
|
||||
|
|
@ -143,16 +130,6 @@ export class CalendarConfig {
|
|||
showAllDay: true
|
||||
};
|
||||
|
||||
// Resource view settings
|
||||
private static resourceViewSettings: ResourceViewSettings = {
|
||||
maxResources: 10,
|
||||
showAvatars: true,
|
||||
avatarSize: 32,
|
||||
resourceNameFormat: 'full',
|
||||
showResourceDetails: true,
|
||||
showAllDay: true
|
||||
};
|
||||
|
||||
// Time format settings - default to Denmark with technical format
|
||||
private static timeFormatConfig: TimeFormatConfig = {
|
||||
timezone: 'Europe/Copenhagen',
|
||||
|
|
@ -293,28 +270,6 @@ export class CalendarConfig {
|
|||
return { ...CalendarConfig.dateViewSettings };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource view settings
|
||||
*/
|
||||
static getResourceViewSettings(): ResourceViewSettings {
|
||||
return { ...CalendarConfig.resourceViewSettings };
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get calendar mode
|
||||
*/
|
||||
static getCalendarMode(): CalendarMode {
|
||||
return CalendarConfig.calendarMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set calendar mode
|
||||
*/
|
||||
static setCalendarMode(mode: CalendarMode): void {
|
||||
CalendarConfig.calendarMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get selected date
|
||||
*/
|
||||
|
|
@ -440,7 +395,6 @@ export class CalendarConfig {
|
|||
const data = JSON.parse(json);
|
||||
if (data.gridSettings) CalendarConfig.updateGridSettings(data.gridSettings);
|
||||
if (data.dateViewSettings) CalendarConfig.dateViewSettings = { ...CalendarConfig.dateViewSettings, ...data.dateViewSettings };
|
||||
if (data.resourceViewSettings) CalendarConfig.resourceViewSettings = { ...CalendarConfig.resourceViewSettings, ...data.resourceViewSettings };
|
||||
if (data.timeFormatConfig) {
|
||||
CalendarConfig.timeFormatConfig = { ...CalendarConfig.timeFormatConfig, ...data.timeFormatConfig };
|
||||
TimeFormatter.configure(CalendarConfig.timeFormatConfig);
|
||||
|
|
@ -469,9 +423,6 @@ export class CalendarConfig {
|
|||
getGridSettings() { return CalendarConfig.getGridSettings(); }
|
||||
updateGridSettings(updates: Partial<GridSettings>) { return CalendarConfig.updateGridSettings(updates); }
|
||||
getDateViewSettings() { return CalendarConfig.getDateViewSettings(); }
|
||||
getResourceViewSettings() { return CalendarConfig.getResourceViewSettings(); }
|
||||
getCalendarMode() { return CalendarConfig.getCalendarMode(); }
|
||||
setCalendarMode(mode: CalendarMode) { return CalendarConfig.setCalendarMode(mode); }
|
||||
getSelectedDate() { return CalendarConfig.getSelectedDate(); }
|
||||
setSelectedDate(date: Date) { return CalendarConfig.setSelectedDate(date); }
|
||||
getWorkWeekSettings() { return CalendarConfig.getWorkWeekSettings(); }
|
||||
|
|
|
|||
16
src/index.ts
16
src/index.ts
|
|
@ -22,8 +22,8 @@ import { HeaderManager } from './managers/HeaderManager';
|
|||
import { ConfigManager } from './managers/ConfigManager';
|
||||
|
||||
// Import renderers
|
||||
import { DateHeaderRenderer, ResourceHeaderRenderer, type HeaderRenderer } from './renderers/HeaderRenderer';
|
||||
import { DateColumnRenderer, ResourceColumnRenderer, type ColumnRenderer } from './renderers/ColumnRenderer';
|
||||
import { DateHeaderRenderer, type HeaderRenderer } from './renderers/HeaderRenderer';
|
||||
import { DateColumnRenderer, type ColumnRenderer } from './renderers/ColumnRenderer';
|
||||
import { DateEventRenderer, type EventRendererStrategy } from './renderers/EventRenderer';
|
||||
import { AllDayEventRenderer } from './renderers/AllDayEventRenderer';
|
||||
import { GridRenderer } from './renderers/GridRenderer';
|
||||
|
|
@ -86,15 +86,9 @@ async function initializeCalendar(): Promise<void> {
|
|||
// Bind core services as instances
|
||||
builder.registerInstance(eventBus).as<IEventBus>();
|
||||
|
||||
// Register renderers based on calendar mode
|
||||
const calendarMode = CalendarConfig.getCalendarMode();
|
||||
if (calendarMode === 'resource') {
|
||||
builder.registerType(ResourceHeaderRenderer).as<HeaderRenderer>().singleInstance();
|
||||
builder.registerType(ResourceColumnRenderer).as<ColumnRenderer>().singleInstance();
|
||||
} else {
|
||||
builder.registerType(DateHeaderRenderer).as<HeaderRenderer>().singleInstance();
|
||||
builder.registerType(DateColumnRenderer).as<ColumnRenderer>().singleInstance();
|
||||
}
|
||||
// Register renderers
|
||||
builder.registerType(DateHeaderRenderer).as<HeaderRenderer>().singleInstance();
|
||||
builder.registerType(DateColumnRenderer).as<ColumnRenderer>().singleInstance();
|
||||
builder.registerType(DateEventRenderer).as<EventRendererStrategy>().singleInstance();
|
||||
|
||||
// Register core services and utilities
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export class AllDayManager {
|
|||
heightDifference: number;
|
||||
} {
|
||||
const root = document.documentElement;
|
||||
const targetHeight = targetRows * ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT + 2;
|
||||
const targetHeight = targetRows * ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT;
|
||||
// Read CSS variable directly from style property or default to 0
|
||||
const currentHeightStr = root.style.getPropertyValue('--all-day-row-height') || '0px';
|
||||
const currentHeight = parseInt(currentHeightStr) || 0;
|
||||
|
|
|
|||
|
|
@ -47,17 +47,10 @@ export class CalendarManager {
|
|||
|
||||
|
||||
try {
|
||||
// Debug: Check calendar type
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
|
||||
// Step 1: Load data
|
||||
await this.eventManager.loadData();
|
||||
|
||||
// Step 2: Pass data to GridManager and render grid structure
|
||||
if (calendarType === 'resource') {
|
||||
const resourceData = this.eventManager.getResourceData();
|
||||
this.gridManager.setResourceData(this.eventManager.getRawData() as import('../types/CalendarTypes').ResourceCalendarData);
|
||||
}
|
||||
// Step 2: Render grid structure
|
||||
await this.gridManager.render();
|
||||
|
||||
this.scrollManager.initialize();
|
||||
|
|
|
|||
|
|
@ -98,21 +98,4 @@ export class ConfigManager {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set calendar mode and emit event
|
||||
*/
|
||||
setCalendarMode(mode: 'date' | 'resource'): void {
|
||||
const oldMode = CalendarConfig.getCalendarMode();
|
||||
CalendarConfig.setCalendarMode(mode);
|
||||
|
||||
// Emit event if changed
|
||||
if (oldMode !== mode) {
|
||||
this.eventBus.emit(CoreEvents.REFRESH_REQUESTED, {
|
||||
key: 'calendarMode',
|
||||
value: mode,
|
||||
oldValue: oldMode
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { IEventBus, CalendarEvent, ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { IEventBus, CalendarEvent } from '../types/CalendarTypes';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { ResourceData } from '../types/ManagerTypes';
|
||||
|
||||
interface RawEventData {
|
||||
id: string;
|
||||
|
|
@ -22,7 +21,7 @@ interface RawEventData {
|
|||
export class EventManager {
|
||||
|
||||
private events: CalendarEvent[] = [];
|
||||
private rawData: ResourceCalendarData | RawEventData[] | null = null;
|
||||
private rawData: RawEventData[] | null = null;
|
||||
private eventCache = new Map<string, CalendarEvent[]>(); // Cache for period queries
|
||||
private lastCacheKey: string = '';
|
||||
private dateService: DateService;
|
||||
|
|
@ -52,46 +51,28 @@ export class EventManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Optimized mock data loading with better resource handling
|
||||
* Optimized mock data loading
|
||||
*/
|
||||
private async loadMockData(): Promise<void> {
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
const jsonFile = calendarType === 'resource'
|
||||
? '/data/mock-resource-events.json'
|
||||
: '/data/mock-events.json';
|
||||
|
||||
const jsonFile = 'data/mock-events.json';
|
||||
|
||||
const response = await fetch(jsonFile);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load mock events: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
|
||||
// Store raw data and process in one operation
|
||||
this.rawData = data;
|
||||
this.events = this.processCalendarData(calendarType, data);
|
||||
this.events = this.processCalendarData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized data processing with better type safety
|
||||
*/
|
||||
private processCalendarData(calendarType: string, data: ResourceCalendarData | RawEventData[]): CalendarEvent[] {
|
||||
if (calendarType === 'resource') {
|
||||
const resourceData = data as ResourceCalendarData;
|
||||
return resourceData.resources.flatMap(resource =>
|
||||
resource.events.map(event => ({
|
||||
...event,
|
||||
start: new Date(event.start),
|
||||
end: new Date(event.end),
|
||||
resourceName: resource.name,
|
||||
resourceDisplayName: resource.displayName,
|
||||
resourceEmployeeId: resource.employeeId
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
const eventData = data as RawEventData[];
|
||||
return eventData.map((event): CalendarEvent => ({
|
||||
private processCalendarData(data: RawEventData[]): CalendarEvent[] {
|
||||
return data.map((event): CalendarEvent => ({
|
||||
...event,
|
||||
start: new Date(event.start),
|
||||
end: new Date(event.end),
|
||||
|
|
@ -116,30 +97,6 @@ export class EventManager {
|
|||
return copy ? [...this.events] : this.events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw resource data for resource calendar mode
|
||||
*/
|
||||
public getResourceData(): ResourceData | null {
|
||||
if (!this.rawData || !('resources' in this.rawData)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
resources: this.rawData.resources.map(r => ({
|
||||
id: r.employeeId || r.name, // Use employeeId as id, fallback to name
|
||||
name: r.name,
|
||||
type: r.employeeId ? 'employee' : 'resource',
|
||||
color: 'blue' // Default color since Resource interface doesn't have color
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw data for compatibility
|
||||
*/
|
||||
public getRawData(): ResourceCalendarData | RawEventData[] | null {
|
||||
return this.rawData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized event lookup with early return
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { eventBus } from '../core/EventBus';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
||||
import { CalendarView } from '../types/CalendarTypes';
|
||||
import { GridRenderer } from '../renderers/GridRenderer';
|
||||
import { GridStyleManager } from '../renderers/GridStyleManager';
|
||||
import { DateService } from '../utils/DateService';
|
||||
|
|
@ -16,7 +16,6 @@ import { DateService } from '../utils/DateService';
|
|||
export class GridManager {
|
||||
private container: HTMLElement | null = null;
|
||||
private currentDate: Date = new Date();
|
||||
private resourceData: ResourceCalendarData | null = null;
|
||||
private currentView: CalendarView = 'week';
|
||||
private gridRenderer: GridRenderer;
|
||||
private styleManager: GridStyleManager;
|
||||
|
|
@ -83,15 +82,7 @@ export class GridManager {
|
|||
this.currentView = view;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource data for resource calendar mode
|
||||
*/
|
||||
public setResourceData(resourceData: ResourceCalendarData | null): void {
|
||||
this.resourceData = resourceData;
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main render method - delegates to GridRenderer
|
||||
*/
|
||||
|
|
@ -99,15 +90,14 @@ export class GridManager {
|
|||
if (!this.container) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Update CSS variables first
|
||||
this.styleManager.updateGridStyles(this.resourceData);
|
||||
|
||||
this.styleManager.updateGridStyles();
|
||||
|
||||
// Delegate to GridRenderer with current view context
|
||||
this.gridRenderer.renderGrid(
|
||||
this.container,
|
||||
this.currentDate,
|
||||
this.resourceData
|
||||
this.currentDate
|
||||
);
|
||||
|
||||
// Calculate period range
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { eventBus } from '../core/EventBus';
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
import { HeaderRenderer, HeaderRenderContext } from '../renderers/HeaderRenderer';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
||||
import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
||||
|
||||
|
|
@ -30,8 +29,8 @@ export class HeaderManager {
|
|||
/**
|
||||
* Initialize header with initial date
|
||||
*/
|
||||
public initializeHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
||||
this.updateHeader(currentDate, resourceData);
|
||||
public initializeHeader(currentDate: Date): void {
|
||||
this.updateHeader(currentDate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -89,20 +88,20 @@ export class HeaderManager {
|
|||
*/
|
||||
private setupNavigationListener(): void {
|
||||
eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => {
|
||||
const { currentDate, resourceData } = (event as CustomEvent).detail;
|
||||
this.updateHeader(currentDate, resourceData);
|
||||
const { currentDate } = (event as CustomEvent).detail;
|
||||
this.updateHeader(currentDate);
|
||||
});
|
||||
|
||||
// Also listen for date changes (including initial setup)
|
||||
eventBus.on(CoreEvents.DATE_CHANGED, (event) => {
|
||||
const { currentDate } = (event as CustomEvent).detail;
|
||||
this.updateHeader(currentDate, null);
|
||||
this.updateHeader(currentDate);
|
||||
});
|
||||
|
||||
// Listen for workweek header updates after grid rebuild
|
||||
eventBus.on('workweek:header-update', (event) => {
|
||||
const { currentDate } = (event as CustomEvent).detail;
|
||||
this.updateHeader(currentDate, null);
|
||||
this.updateHeader(currentDate);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -110,10 +109,9 @@ export class HeaderManager {
|
|||
/**
|
||||
* Update header content for navigation
|
||||
*/
|
||||
private updateHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
||||
private updateHeader(currentDate: Date): void {
|
||||
console.log('🎯 HeaderManager.updateHeader called', {
|
||||
currentDate,
|
||||
hasResourceData: !!resourceData,
|
||||
rendererType: this.headerRenderer.constructor.name
|
||||
});
|
||||
|
||||
|
|
@ -129,8 +127,7 @@ export class HeaderManager {
|
|||
// Render new header content using injected renderer
|
||||
const context: HeaderRenderContext = {
|
||||
currentWeek: currentDate,
|
||||
config: this.config,
|
||||
resourceData: resourceData
|
||||
config: this.config
|
||||
};
|
||||
|
||||
console.log('🎨 HeaderManager: Calling renderer.render()', context);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Column rendering strategy interface and implementations
|
||||
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { DateService } from '../utils/DateService';
|
||||
import { WorkHoursManager } from '../managers/WorkHoursManager';
|
||||
|
||||
|
|
@ -18,7 +17,6 @@ export interface ColumnRenderer {
|
|||
export interface ColumnRenderContext {
|
||||
currentWeek: Date;
|
||||
config: CalendarConfig;
|
||||
resourceData?: ResourceCalendarData | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,29 +78,3 @@ export class DateColumnRenderer implements ColumnRenderer {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource-based column renderer
|
||||
*/
|
||||
export class ResourceColumnRenderer implements ColumnRenderer {
|
||||
render(columnContainer: HTMLElement, context: ColumnRenderContext): void {
|
||||
const { resourceData } = context;
|
||||
|
||||
if (!resourceData) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
resourceData.resources.forEach((resource) => {
|
||||
const column = document.createElement('swp-resource-column');
|
||||
(column as any).dataset.resource = resource.name;
|
||||
(column as any).dataset.employeeId = resource.employeeId;
|
||||
(column as any).dataset.date = resourceData.date;
|
||||
|
||||
const eventsLayer = document.createElement('swp-events-layer');
|
||||
column.appendChild(eventsLayer);
|
||||
|
||||
columnContainer.appendChild(column);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
||||
import { CalendarView } from '../types/CalendarTypes';
|
||||
import { ColumnRenderer, ColumnRenderContext } from './ColumnRenderer';
|
||||
import { eventBus } from '../core/EventBus';
|
||||
import { DateService } from '../utils/DateService';
|
||||
|
|
@ -30,7 +30,6 @@ export class GridRenderer {
|
|||
public renderGrid(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView = 'week'
|
||||
): void {
|
||||
|
||||
|
|
@ -43,12 +42,12 @@ export class GridRenderer {
|
|||
|
||||
// Only clear and rebuild if grid is empty (first render)
|
||||
if (grid.children.length === 0) {
|
||||
this.createCompleteGridStructure(grid, currentDate, resourceData, view);
|
||||
this.createCompleteGridStructure(grid, currentDate, view);
|
||||
// Setup grid-related event listeners on first render
|
||||
// this.setupGridEventListeners();
|
||||
} else {
|
||||
// Optimized update - only refresh dynamic content
|
||||
this.updateGridContent(grid, currentDate, resourceData, view);
|
||||
this.updateGridContent(grid, currentDate, view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +57,6 @@ export class GridRenderer {
|
|||
private createCompleteGridStructure(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): void {
|
||||
// Create all elements in memory first for better performance
|
||||
|
|
@ -74,7 +72,7 @@ export class GridRenderer {
|
|||
fragment.appendChild(timeAxis);
|
||||
|
||||
// Create grid container with caching
|
||||
const gridContainer = this.createOptimizedGridContainer(currentDate, resourceData, view);
|
||||
const gridContainer = this.createOptimizedGridContainer(currentDate, view);
|
||||
this.cachedGridContainer = gridContainer;
|
||||
fragment.appendChild(gridContainer);
|
||||
|
||||
|
|
@ -105,7 +103,6 @@ export class GridRenderer {
|
|||
|
||||
private createOptimizedGridContainer(
|
||||
currentDate: Date,
|
||||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): HTMLElement {
|
||||
const gridContainer = document.createElement('swp-grid-container');
|
||||
|
|
@ -124,7 +121,7 @@ export class GridRenderer {
|
|||
|
||||
// Create column container
|
||||
const columnContainer = document.createElement('swp-day-columns');
|
||||
this.renderColumnContainer(columnContainer, currentDate, resourceData, view);
|
||||
this.renderColumnContainer(columnContainer, currentDate, view);
|
||||
timeGrid.appendChild(columnContainer);
|
||||
|
||||
scrollableContent.appendChild(timeGrid);
|
||||
|
|
@ -142,13 +139,11 @@ export class GridRenderer {
|
|||
private renderColumnContainer(
|
||||
columnContainer: HTMLElement,
|
||||
currentDate: Date,
|
||||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): void {
|
||||
const context: ColumnRenderContext = {
|
||||
currentWeek: currentDate, // ColumnRenderer expects currentWeek property
|
||||
config: this.config,
|
||||
resourceData: resourceData
|
||||
config: this.config
|
||||
};
|
||||
|
||||
this.columnRenderer.render(columnContainer, context);
|
||||
|
|
@ -160,14 +155,13 @@ export class GridRenderer {
|
|||
private updateGridContent(
|
||||
grid: HTMLElement,
|
||||
currentDate: Date,
|
||||
resourceData: ResourceCalendarData | null,
|
||||
view: CalendarView
|
||||
): void {
|
||||
// Update column container if needed
|
||||
const columnContainer = grid.querySelector('swp-day-columns');
|
||||
if (columnContainer) {
|
||||
columnContainer.innerHTML = '';
|
||||
this.renderColumnContainer(columnContainer as HTMLElement, currentDate, resourceData, view);
|
||||
this.renderColumnContainer(columnContainer as HTMLElement, currentDate, view);
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -182,8 +176,8 @@ export class GridRenderer {
|
|||
|
||||
const weekEnd = this.dateService.addDays(weekStart, 6);
|
||||
|
||||
// Use SAME method as initial load - respects workweek and resource settings
|
||||
const newGrid = this.createOptimizedGridContainer(weekStart, null, 'week');
|
||||
// Use SAME method as initial load - respects workweek settings
|
||||
const newGrid = this.createOptimizedGridContainer(weekStart, 'week');
|
||||
|
||||
// Position new grid for animation - NO transform here, let Animation API handle it
|
||||
newGrid.style.position = 'absolute';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
|
||||
interface GridSettings {
|
||||
hourHeight: number;
|
||||
|
|
@ -25,27 +24,26 @@ export class GridStyleManager {
|
|||
/**
|
||||
* Update all grid CSS variables
|
||||
*/
|
||||
public updateGridStyles(resourceData: ResourceCalendarData | null = null): void {
|
||||
public updateGridStyles(): void {
|
||||
const root = document.documentElement;
|
||||
const gridSettings = this.config.getGridSettings();
|
||||
const calendar = document.querySelector('swp-calendar') as HTMLElement;
|
||||
const calendarType = this.config.getCalendarMode();
|
||||
|
||||
|
||||
// Set CSS variables for time and grid measurements
|
||||
this.setTimeVariables(root, gridSettings);
|
||||
|
||||
// Set column count based on calendar type
|
||||
const columnCount = this.calculateColumnCount(calendarType, resourceData);
|
||||
|
||||
// Set column count based on view
|
||||
const columnCount = this.calculateColumnCount();
|
||||
root.style.setProperty('--grid-columns', columnCount.toString());
|
||||
|
||||
|
||||
// Set column width based on fitToWidth setting
|
||||
this.setColumnWidth(root, gridSettings);
|
||||
|
||||
|
||||
// Set fitToWidth data attribute for CSS targeting
|
||||
if (calendar) {
|
||||
calendar.setAttribute('data-fit-to-width', gridSettings.fitToWidth.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -63,28 +61,22 @@ export class GridStyleManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate number of columns based on calendar type and view
|
||||
* Calculate number of columns based on view
|
||||
*/
|
||||
private calculateColumnCount(calendarType: string, resourceData: ResourceCalendarData | null): number {
|
||||
if (calendarType === 'resource' && resourceData) {
|
||||
return resourceData.resources.length;
|
||||
} else if (calendarType === 'date') {
|
||||
const dateSettings = this.config.getDateViewSettings();
|
||||
const workWeekSettings = this.config.getWorkWeekSettings();
|
||||
private calculateColumnCount(): number {
|
||||
const dateSettings = this.config.getDateViewSettings();
|
||||
const workWeekSettings = this.config.getWorkWeekSettings();
|
||||
|
||||
switch (dateSettings.period) {
|
||||
case 'day':
|
||||
return 1;
|
||||
case 'week':
|
||||
return workWeekSettings.totalDays;
|
||||
case 'month':
|
||||
return workWeekSettings.totalDays; // Use work week for month view too
|
||||
default:
|
||||
return workWeekSettings.totalDays;
|
||||
}
|
||||
switch (dateSettings.period) {
|
||||
case 'day':
|
||||
return 1;
|
||||
case 'week':
|
||||
return workWeekSettings.totalDays;
|
||||
case 'month':
|
||||
return workWeekSettings.totalDays; // Use work week for month view too
|
||||
default:
|
||||
return workWeekSettings.totalDays;
|
||||
}
|
||||
|
||||
return this.config.getWorkWeekSettings().totalDays; // Default to work week
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Header rendering strategy interface and implementations
|
||||
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
import { DateService } from '../utils/DateService';
|
||||
|
||||
/**
|
||||
|
|
@ -18,7 +17,6 @@ export interface HeaderRenderer {
|
|||
export interface HeaderRenderContext {
|
||||
currentWeek: Date;
|
||||
config: CalendarConfig;
|
||||
resourceData?: ResourceCalendarData | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,34 +56,6 @@ export class DateHeaderRenderer implements HeaderRenderer {
|
|||
`;
|
||||
(header as any).dataset.date = this.dateService.formatISODate(date);
|
||||
|
||||
calendarHeader.appendChild(header);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource-based header renderer
|
||||
*/
|
||||
export class ResourceHeaderRenderer implements HeaderRenderer {
|
||||
render(calendarHeader: HTMLElement, context: HeaderRenderContext): void {
|
||||
const { resourceData } = context;
|
||||
|
||||
if (!resourceData) {
|
||||
return;
|
||||
}
|
||||
|
||||
resourceData.resources.forEach((resource) => {
|
||||
const header = document.createElement('swp-resource-header');
|
||||
header.setAttribute('data-resource', resource.name);
|
||||
header.setAttribute('data-employee-id', resource.employeeId);
|
||||
|
||||
header.innerHTML = `
|
||||
<swp-resource-avatar>
|
||||
<img src="${resource.avatarUrl}" alt="${resource.displayName}" onerror="this.style.display='none'">
|
||||
</swp-resource-avatar>
|
||||
<swp-resource-name>${resource.displayName}</swp-resource-name>
|
||||
`;
|
||||
|
||||
calendarHeader.appendChild(header);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,12 @@
|
|||
* Allows clean separation between week view, month view, day view etc.
|
||||
*/
|
||||
|
||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
||||
|
||||
/**
|
||||
* Context object passed to strategy methods
|
||||
*/
|
||||
export interface ViewContext {
|
||||
currentDate: Date;
|
||||
container: HTMLElement;
|
||||
resourceData: ResourceCalendarData | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,27 +3,11 @@
|
|||
// Time period view types (how much time to display)
|
||||
export type ViewPeriod = 'day' | 'week' | 'month';
|
||||
|
||||
// Calendar mode types (how to organize the data)
|
||||
export type CalendarMode = 'date' | 'resource';
|
||||
|
||||
// Type aliases
|
||||
export type CalendarView = ViewPeriod;
|
||||
|
||||
export type SyncStatus = 'synced' | 'pending' | 'error';
|
||||
|
||||
export interface Resource {
|
||||
name: string;
|
||||
displayName: string;
|
||||
avatarUrl: string;
|
||||
employeeId: string;
|
||||
events: CalendarEvent[];
|
||||
}
|
||||
|
||||
export interface ResourceCalendarData {
|
||||
date: string;
|
||||
resources: Resource[];
|
||||
}
|
||||
|
||||
export interface RenderContext {
|
||||
container: HTMLElement;
|
||||
startDate: Date;
|
||||
|
|
@ -38,14 +22,7 @@ export interface CalendarEvent {
|
|||
type: string; // Flexible event type - can be any string value
|
||||
allDay: boolean;
|
||||
syncStatus: SyncStatus;
|
||||
|
||||
// Resource information (only present in resource calendar mode)
|
||||
resource?: {
|
||||
name: string;
|
||||
displayName: string;
|
||||
employeeId: string;
|
||||
};
|
||||
|
||||
|
||||
recurringId?: string;
|
||||
metadata?: Record<string, any>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ export interface EventManager extends IManager {
|
|||
loadData(): Promise<void>;
|
||||
getEvents(): CalendarEvent[];
|
||||
getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[];
|
||||
getResourceData(): ResourceData | null;
|
||||
navigateToEvent(eventId: string): boolean;
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +41,6 @@ export interface EventRenderingService extends IManager {
|
|||
export interface GridManager extends IManager {
|
||||
render(): Promise<void>;
|
||||
getDisplayDates(): Date[];
|
||||
setResourceData(resourceData: import('./CalendarTypes').ResourceCalendarData | null): void;
|
||||
}
|
||||
|
||||
export interface ScrollManager extends IManager {
|
||||
|
|
@ -76,20 +74,3 @@ export interface AllDayManager extends IManager {
|
|||
export interface ResizeHandleManager extends IManager {
|
||||
// ResizeHandleManager handles hover effects for resize handles
|
||||
}
|
||||
|
||||
export interface ResourceData {
|
||||
resources: Resource[];
|
||||
assignments?: ResourceAssignment[];
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
id: string;
|
||||
name: string;
|
||||
type?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface ResourceAssignment {
|
||||
resourceId: string;
|
||||
eventId: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,7 +186,6 @@ swp-calendar-header {
|
|||
min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width));
|
||||
/* Dynamic width */
|
||||
background: var(--color-surface);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 3;
|
||||
|
|
@ -197,10 +196,7 @@ swp-calendar-header {
|
|||
/* Force scrollbar to appear for alignment */
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
|
||||
/* Firefox - hide scrollbar but keep space */
|
||||
scrollbar-width: auto;
|
||||
/* Normal width to match content scrollbar */
|
||||
|
||||
|
||||
/* All-day events container */
|
||||
swp-allday-container {
|
||||
|
|
@ -211,12 +207,10 @@ swp-calendar-header {
|
|||
grid-auto-rows: var(--single-row-height);
|
||||
/* Each row is exactly SINGLE_ROW_HEIGHT */
|
||||
gap: 2px 0px;
|
||||
padding: 2px 0px 5px 0px;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
scrollbar-color: transparent transparent;
|
||||
|
||||
}
|
||||
|
||||
/* WebKit browsers (Chrome, Safari, Edge) - hide scrollbar but keep space */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue