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
|
// Calendar configuration management
|
||||||
// Pure static configuration class - no dependencies, no events
|
// 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';
|
import { TimeFormatter, TimeFormatSettings } from '../utils/TimeFormatter';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,18 +61,6 @@ interface WorkWeekSettings {
|
||||||
firstWorkDay: number; // ISO: 1 = Monday, 7 = Sunday
|
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
|
* Time format configuration settings
|
||||||
*/
|
*/
|
||||||
|
|
@ -116,7 +104,6 @@ export class CalendarConfig {
|
||||||
maxEventDuration: 480 // 8 hours
|
maxEventDuration: 480 // 8 hours
|
||||||
};
|
};
|
||||||
|
|
||||||
private static calendarMode: CalendarMode = 'date';
|
|
||||||
private static selectedDate: Date | null = new Date();
|
private static selectedDate: Date | null = new Date();
|
||||||
private static currentWorkWeek: string = 'standard';
|
private static currentWorkWeek: string = 'standard';
|
||||||
|
|
||||||
|
|
@ -143,16 +130,6 @@ export class CalendarConfig {
|
||||||
showAllDay: true
|
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
|
// Time format settings - default to Denmark with technical format
|
||||||
private static timeFormatConfig: TimeFormatConfig = {
|
private static timeFormatConfig: TimeFormatConfig = {
|
||||||
timezone: 'Europe/Copenhagen',
|
timezone: 'Europe/Copenhagen',
|
||||||
|
|
@ -293,28 +270,6 @@ export class CalendarConfig {
|
||||||
return { ...CalendarConfig.dateViewSettings };
|
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
|
* Get selected date
|
||||||
*/
|
*/
|
||||||
|
|
@ -440,7 +395,6 @@ export class CalendarConfig {
|
||||||
const data = JSON.parse(json);
|
const data = JSON.parse(json);
|
||||||
if (data.gridSettings) CalendarConfig.updateGridSettings(data.gridSettings);
|
if (data.gridSettings) CalendarConfig.updateGridSettings(data.gridSettings);
|
||||||
if (data.dateViewSettings) CalendarConfig.dateViewSettings = { ...CalendarConfig.dateViewSettings, ...data.dateViewSettings };
|
if (data.dateViewSettings) CalendarConfig.dateViewSettings = { ...CalendarConfig.dateViewSettings, ...data.dateViewSettings };
|
||||||
if (data.resourceViewSettings) CalendarConfig.resourceViewSettings = { ...CalendarConfig.resourceViewSettings, ...data.resourceViewSettings };
|
|
||||||
if (data.timeFormatConfig) {
|
if (data.timeFormatConfig) {
|
||||||
CalendarConfig.timeFormatConfig = { ...CalendarConfig.timeFormatConfig, ...data.timeFormatConfig };
|
CalendarConfig.timeFormatConfig = { ...CalendarConfig.timeFormatConfig, ...data.timeFormatConfig };
|
||||||
TimeFormatter.configure(CalendarConfig.timeFormatConfig);
|
TimeFormatter.configure(CalendarConfig.timeFormatConfig);
|
||||||
|
|
@ -469,9 +423,6 @@ export class CalendarConfig {
|
||||||
getGridSettings() { return CalendarConfig.getGridSettings(); }
|
getGridSettings() { return CalendarConfig.getGridSettings(); }
|
||||||
updateGridSettings(updates: Partial<GridSettings>) { return CalendarConfig.updateGridSettings(updates); }
|
updateGridSettings(updates: Partial<GridSettings>) { return CalendarConfig.updateGridSettings(updates); }
|
||||||
getDateViewSettings() { return CalendarConfig.getDateViewSettings(); }
|
getDateViewSettings() { return CalendarConfig.getDateViewSettings(); }
|
||||||
getResourceViewSettings() { return CalendarConfig.getResourceViewSettings(); }
|
|
||||||
getCalendarMode() { return CalendarConfig.getCalendarMode(); }
|
|
||||||
setCalendarMode(mode: CalendarMode) { return CalendarConfig.setCalendarMode(mode); }
|
|
||||||
getSelectedDate() { return CalendarConfig.getSelectedDate(); }
|
getSelectedDate() { return CalendarConfig.getSelectedDate(); }
|
||||||
setSelectedDate(date: Date) { return CalendarConfig.setSelectedDate(date); }
|
setSelectedDate(date: Date) { return CalendarConfig.setSelectedDate(date); }
|
||||||
getWorkWeekSettings() { return CalendarConfig.getWorkWeekSettings(); }
|
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 { ConfigManager } from './managers/ConfigManager';
|
||||||
|
|
||||||
// Import renderers
|
// Import renderers
|
||||||
import { DateHeaderRenderer, ResourceHeaderRenderer, type HeaderRenderer } from './renderers/HeaderRenderer';
|
import { DateHeaderRenderer, type HeaderRenderer } from './renderers/HeaderRenderer';
|
||||||
import { DateColumnRenderer, ResourceColumnRenderer, type ColumnRenderer } from './renderers/ColumnRenderer';
|
import { DateColumnRenderer, type ColumnRenderer } from './renderers/ColumnRenderer';
|
||||||
import { DateEventRenderer, type EventRendererStrategy } from './renderers/EventRenderer';
|
import { DateEventRenderer, type EventRendererStrategy } from './renderers/EventRenderer';
|
||||||
import { AllDayEventRenderer } from './renderers/AllDayEventRenderer';
|
import { AllDayEventRenderer } from './renderers/AllDayEventRenderer';
|
||||||
import { GridRenderer } from './renderers/GridRenderer';
|
import { GridRenderer } from './renderers/GridRenderer';
|
||||||
|
|
@ -86,15 +86,9 @@ async function initializeCalendar(): Promise<void> {
|
||||||
// Bind core services as instances
|
// Bind core services as instances
|
||||||
builder.registerInstance(eventBus).as<IEventBus>();
|
builder.registerInstance(eventBus).as<IEventBus>();
|
||||||
|
|
||||||
// Register renderers based on calendar mode
|
// Register renderers
|
||||||
const calendarMode = CalendarConfig.getCalendarMode();
|
builder.registerType(DateHeaderRenderer).as<HeaderRenderer>().singleInstance();
|
||||||
if (calendarMode === 'resource') {
|
builder.registerType(DateColumnRenderer).as<ColumnRenderer>().singleInstance();
|
||||||
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();
|
|
||||||
}
|
|
||||||
builder.registerType(DateEventRenderer).as<EventRendererStrategy>().singleInstance();
|
builder.registerType(DateEventRenderer).as<EventRendererStrategy>().singleInstance();
|
||||||
|
|
||||||
// Register core services and utilities
|
// Register core services and utilities
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ export class AllDayManager {
|
||||||
heightDifference: number;
|
heightDifference: number;
|
||||||
} {
|
} {
|
||||||
const root = document.documentElement;
|
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
|
// Read CSS variable directly from style property or default to 0
|
||||||
const currentHeightStr = root.style.getPropertyValue('--all-day-row-height') || '0px';
|
const currentHeightStr = root.style.getPropertyValue('--all-day-row-height') || '0px';
|
||||||
const currentHeight = parseInt(currentHeightStr) || 0;
|
const currentHeight = parseInt(currentHeightStr) || 0;
|
||||||
|
|
|
||||||
|
|
@ -47,17 +47,10 @@ export class CalendarManager {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Debug: Check calendar type
|
|
||||||
const calendarType = this.config.getCalendarMode();
|
|
||||||
|
|
||||||
// Step 1: Load data
|
// Step 1: Load data
|
||||||
await this.eventManager.loadData();
|
await this.eventManager.loadData();
|
||||||
|
|
||||||
// Step 2: Pass data to GridManager and render grid structure
|
// Step 2: Render grid structure
|
||||||
if (calendarType === 'resource') {
|
|
||||||
const resourceData = this.eventManager.getResourceData();
|
|
||||||
this.gridManager.setResourceData(this.eventManager.getRawData() as import('../types/CalendarTypes').ResourceCalendarData);
|
|
||||||
}
|
|
||||||
await this.gridManager.render();
|
await this.gridManager.render();
|
||||||
|
|
||||||
this.scrollManager.initialize();
|
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 { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { CalendarConfig } from '../core/CalendarConfig';
|
import { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { DateService } from '../utils/DateService';
|
import { DateService } from '../utils/DateService';
|
||||||
import { ResourceData } from '../types/ManagerTypes';
|
|
||||||
|
|
||||||
interface RawEventData {
|
interface RawEventData {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -22,7 +21,7 @@ interface RawEventData {
|
||||||
export class EventManager {
|
export class EventManager {
|
||||||
|
|
||||||
private events: CalendarEvent[] = [];
|
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 eventCache = new Map<string, CalendarEvent[]>(); // Cache for period queries
|
||||||
private lastCacheKey: string = '';
|
private lastCacheKey: string = '';
|
||||||
private dateService: DateService;
|
private dateService: DateService;
|
||||||
|
|
@ -52,13 +51,10 @@ export class EventManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimized mock data loading with better resource handling
|
* Optimized mock data loading
|
||||||
*/
|
*/
|
||||||
private async loadMockData(): Promise<void> {
|
private async loadMockData(): Promise<void> {
|
||||||
const calendarType = this.config.getCalendarMode();
|
const jsonFile = 'data/mock-events.json';
|
||||||
const jsonFile = calendarType === 'resource'
|
|
||||||
? '/data/mock-resource-events.json'
|
|
||||||
: '/data/mock-events.json';
|
|
||||||
|
|
||||||
const response = await fetch(jsonFile);
|
const response = await fetch(jsonFile);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|
@ -69,29 +65,14 @@ export class EventManager {
|
||||||
|
|
||||||
// Store raw data and process in one operation
|
// Store raw data and process in one operation
|
||||||
this.rawData = data;
|
this.rawData = data;
|
||||||
this.events = this.processCalendarData(calendarType, data);
|
this.events = this.processCalendarData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimized data processing with better type safety
|
* Optimized data processing with better type safety
|
||||||
*/
|
*/
|
||||||
private processCalendarData(calendarType: string, data: ResourceCalendarData | RawEventData[]): CalendarEvent[] {
|
private processCalendarData(data: RawEventData[]): CalendarEvent[] {
|
||||||
if (calendarType === 'resource') {
|
return data.map((event): CalendarEvent => ({
|
||||||
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 => ({
|
|
||||||
...event,
|
...event,
|
||||||
start: new Date(event.start),
|
start: new Date(event.start),
|
||||||
end: new Date(event.end),
|
end: new Date(event.end),
|
||||||
|
|
@ -116,30 +97,6 @@ export class EventManager {
|
||||||
return copy ? [...this.events] : this.events;
|
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
|
* Optimized event lookup with early return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { eventBus } from '../core/EventBus';
|
import { eventBus } from '../core/EventBus';
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
import { CalendarView } from '../types/CalendarTypes';
|
||||||
import { GridRenderer } from '../renderers/GridRenderer';
|
import { GridRenderer } from '../renderers/GridRenderer';
|
||||||
import { GridStyleManager } from '../renderers/GridStyleManager';
|
import { GridStyleManager } from '../renderers/GridStyleManager';
|
||||||
import { DateService } from '../utils/DateService';
|
import { DateService } from '../utils/DateService';
|
||||||
|
|
@ -16,7 +16,6 @@ import { DateService } from '../utils/DateService';
|
||||||
export class GridManager {
|
export class GridManager {
|
||||||
private container: HTMLElement | null = null;
|
private container: HTMLElement | null = null;
|
||||||
private currentDate: Date = new Date();
|
private currentDate: Date = new Date();
|
||||||
private resourceData: ResourceCalendarData | null = null;
|
|
||||||
private currentView: CalendarView = 'week';
|
private currentView: CalendarView = 'week';
|
||||||
private gridRenderer: GridRenderer;
|
private gridRenderer: GridRenderer;
|
||||||
private styleManager: GridStyleManager;
|
private styleManager: GridStyleManager;
|
||||||
|
|
@ -84,14 +83,6 @@ export class GridManager {
|
||||||
this.render();
|
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
|
* Main render method - delegates to GridRenderer
|
||||||
*/
|
*/
|
||||||
|
|
@ -101,13 +92,12 @@ export class GridManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update CSS variables first
|
// Update CSS variables first
|
||||||
this.styleManager.updateGridStyles(this.resourceData);
|
this.styleManager.updateGridStyles();
|
||||||
|
|
||||||
// Delegate to GridRenderer with current view context
|
// Delegate to GridRenderer with current view context
|
||||||
this.gridRenderer.renderGrid(
|
this.gridRenderer.renderGrid(
|
||||||
this.container,
|
this.container,
|
||||||
this.currentDate,
|
this.currentDate
|
||||||
this.resourceData
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Calculate period range
|
// Calculate period range
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { eventBus } from '../core/EventBus';
|
||||||
import { CalendarConfig } from '../core/CalendarConfig';
|
import { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { HeaderRenderer, HeaderRenderContext } from '../renderers/HeaderRenderer';
|
import { HeaderRenderer, HeaderRenderContext } from '../renderers/HeaderRenderer';
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
|
||||||
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
import { DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from '../types/EventTypes';
|
||||||
import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
||||||
|
|
||||||
|
|
@ -30,8 +29,8 @@ export class HeaderManager {
|
||||||
/**
|
/**
|
||||||
* Initialize header with initial date
|
* Initialize header with initial date
|
||||||
*/
|
*/
|
||||||
public initializeHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
public initializeHeader(currentDate: Date): void {
|
||||||
this.updateHeader(currentDate, resourceData);
|
this.updateHeader(currentDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -89,20 +88,20 @@ export class HeaderManager {
|
||||||
*/
|
*/
|
||||||
private setupNavigationListener(): void {
|
private setupNavigationListener(): void {
|
||||||
eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => {
|
eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => {
|
||||||
const { currentDate, resourceData } = (event as CustomEvent).detail;
|
const { currentDate } = (event as CustomEvent).detail;
|
||||||
this.updateHeader(currentDate, resourceData);
|
this.updateHeader(currentDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also listen for date changes (including initial setup)
|
// Also listen for date changes (including initial setup)
|
||||||
eventBus.on(CoreEvents.DATE_CHANGED, (event) => {
|
eventBus.on(CoreEvents.DATE_CHANGED, (event) => {
|
||||||
const { currentDate } = (event as CustomEvent).detail;
|
const { currentDate } = (event as CustomEvent).detail;
|
||||||
this.updateHeader(currentDate, null);
|
this.updateHeader(currentDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for workweek header updates after grid rebuild
|
// Listen for workweek header updates after grid rebuild
|
||||||
eventBus.on('workweek:header-update', (event) => {
|
eventBus.on('workweek:header-update', (event) => {
|
||||||
const { currentDate } = (event as CustomEvent).detail;
|
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
|
* Update header content for navigation
|
||||||
*/
|
*/
|
||||||
private updateHeader(currentDate: Date, resourceData: ResourceCalendarData | null = null): void {
|
private updateHeader(currentDate: Date): void {
|
||||||
console.log('🎯 HeaderManager.updateHeader called', {
|
console.log('🎯 HeaderManager.updateHeader called', {
|
||||||
currentDate,
|
currentDate,
|
||||||
hasResourceData: !!resourceData,
|
|
||||||
rendererType: this.headerRenderer.constructor.name
|
rendererType: this.headerRenderer.constructor.name
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -129,8 +127,7 @@ export class HeaderManager {
|
||||||
// Render new header content using injected renderer
|
// Render new header content using injected renderer
|
||||||
const context: HeaderRenderContext = {
|
const context: HeaderRenderContext = {
|
||||||
currentWeek: currentDate,
|
currentWeek: currentDate,
|
||||||
config: this.config,
|
config: this.config
|
||||||
resourceData: resourceData
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('🎨 HeaderManager: Calling renderer.render()', context);
|
console.log('🎨 HeaderManager: Calling renderer.render()', context);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Column rendering strategy interface and implementations
|
// Column rendering strategy interface and implementations
|
||||||
|
|
||||||
import { CalendarConfig } from '../core/CalendarConfig';
|
import { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
|
||||||
import { DateService } from '../utils/DateService';
|
import { DateService } from '../utils/DateService';
|
||||||
import { WorkHoursManager } from '../managers/WorkHoursManager';
|
import { WorkHoursManager } from '../managers/WorkHoursManager';
|
||||||
|
|
||||||
|
|
@ -18,7 +17,6 @@ export interface ColumnRenderer {
|
||||||
export interface ColumnRenderContext {
|
export interface ColumnRenderContext {
|
||||||
currentWeek: Date;
|
currentWeek: Date;
|
||||||
config: CalendarConfig;
|
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 { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { ResourceCalendarData, CalendarView } from '../types/CalendarTypes';
|
import { CalendarView } from '../types/CalendarTypes';
|
||||||
import { ColumnRenderer, ColumnRenderContext } from './ColumnRenderer';
|
import { ColumnRenderer, ColumnRenderContext } from './ColumnRenderer';
|
||||||
import { eventBus } from '../core/EventBus';
|
import { eventBus } from '../core/EventBus';
|
||||||
import { DateService } from '../utils/DateService';
|
import { DateService } from '../utils/DateService';
|
||||||
|
|
@ -30,7 +30,6 @@ export class GridRenderer {
|
||||||
public renderGrid(
|
public renderGrid(
|
||||||
grid: HTMLElement,
|
grid: HTMLElement,
|
||||||
currentDate: Date,
|
currentDate: Date,
|
||||||
resourceData: ResourceCalendarData | null,
|
|
||||||
view: CalendarView = 'week'
|
view: CalendarView = 'week'
|
||||||
): void {
|
): void {
|
||||||
|
|
||||||
|
|
@ -43,12 +42,12 @@ export class GridRenderer {
|
||||||
|
|
||||||
// Only clear and rebuild if grid is empty (first render)
|
// Only clear and rebuild if grid is empty (first render)
|
||||||
if (grid.children.length === 0) {
|
if (grid.children.length === 0) {
|
||||||
this.createCompleteGridStructure(grid, currentDate, resourceData, view);
|
this.createCompleteGridStructure(grid, currentDate, view);
|
||||||
// Setup grid-related event listeners on first render
|
// Setup grid-related event listeners on first render
|
||||||
// this.setupGridEventListeners();
|
// this.setupGridEventListeners();
|
||||||
} else {
|
} else {
|
||||||
// Optimized update - only refresh dynamic content
|
// 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(
|
private createCompleteGridStructure(
|
||||||
grid: HTMLElement,
|
grid: HTMLElement,
|
||||||
currentDate: Date,
|
currentDate: Date,
|
||||||
resourceData: ResourceCalendarData | null,
|
|
||||||
view: CalendarView
|
view: CalendarView
|
||||||
): void {
|
): void {
|
||||||
// Create all elements in memory first for better performance
|
// Create all elements in memory first for better performance
|
||||||
|
|
@ -74,7 +72,7 @@ export class GridRenderer {
|
||||||
fragment.appendChild(timeAxis);
|
fragment.appendChild(timeAxis);
|
||||||
|
|
||||||
// Create grid container with caching
|
// Create grid container with caching
|
||||||
const gridContainer = this.createOptimizedGridContainer(currentDate, resourceData, view);
|
const gridContainer = this.createOptimizedGridContainer(currentDate, view);
|
||||||
this.cachedGridContainer = gridContainer;
|
this.cachedGridContainer = gridContainer;
|
||||||
fragment.appendChild(gridContainer);
|
fragment.appendChild(gridContainer);
|
||||||
|
|
||||||
|
|
@ -105,7 +103,6 @@ export class GridRenderer {
|
||||||
|
|
||||||
private createOptimizedGridContainer(
|
private createOptimizedGridContainer(
|
||||||
currentDate: Date,
|
currentDate: Date,
|
||||||
resourceData: ResourceCalendarData | null,
|
|
||||||
view: CalendarView
|
view: CalendarView
|
||||||
): HTMLElement {
|
): HTMLElement {
|
||||||
const gridContainer = document.createElement('swp-grid-container');
|
const gridContainer = document.createElement('swp-grid-container');
|
||||||
|
|
@ -124,7 +121,7 @@ export class GridRenderer {
|
||||||
|
|
||||||
// Create column container
|
// Create column container
|
||||||
const columnContainer = document.createElement('swp-day-columns');
|
const columnContainer = document.createElement('swp-day-columns');
|
||||||
this.renderColumnContainer(columnContainer, currentDate, resourceData, view);
|
this.renderColumnContainer(columnContainer, currentDate, view);
|
||||||
timeGrid.appendChild(columnContainer);
|
timeGrid.appendChild(columnContainer);
|
||||||
|
|
||||||
scrollableContent.appendChild(timeGrid);
|
scrollableContent.appendChild(timeGrid);
|
||||||
|
|
@ -142,13 +139,11 @@ export class GridRenderer {
|
||||||
private renderColumnContainer(
|
private renderColumnContainer(
|
||||||
columnContainer: HTMLElement,
|
columnContainer: HTMLElement,
|
||||||
currentDate: Date,
|
currentDate: Date,
|
||||||
resourceData: ResourceCalendarData | null,
|
|
||||||
view: CalendarView
|
view: CalendarView
|
||||||
): void {
|
): void {
|
||||||
const context: ColumnRenderContext = {
|
const context: ColumnRenderContext = {
|
||||||
currentWeek: currentDate, // ColumnRenderer expects currentWeek property
|
currentWeek: currentDate, // ColumnRenderer expects currentWeek property
|
||||||
config: this.config,
|
config: this.config
|
||||||
resourceData: resourceData
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.columnRenderer.render(columnContainer, context);
|
this.columnRenderer.render(columnContainer, context);
|
||||||
|
|
@ -160,14 +155,13 @@ export class GridRenderer {
|
||||||
private updateGridContent(
|
private updateGridContent(
|
||||||
grid: HTMLElement,
|
grid: HTMLElement,
|
||||||
currentDate: Date,
|
currentDate: Date,
|
||||||
resourceData: ResourceCalendarData | null,
|
|
||||||
view: CalendarView
|
view: CalendarView
|
||||||
): void {
|
): void {
|
||||||
// Update column container if needed
|
// Update column container if needed
|
||||||
const columnContainer = grid.querySelector('swp-day-columns');
|
const columnContainer = grid.querySelector('swp-day-columns');
|
||||||
if (columnContainer) {
|
if (columnContainer) {
|
||||||
columnContainer.innerHTML = '';
|
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);
|
const weekEnd = this.dateService.addDays(weekStart, 6);
|
||||||
|
|
||||||
// Use SAME method as initial load - respects workweek and resource settings
|
// Use SAME method as initial load - respects workweek settings
|
||||||
const newGrid = this.createOptimizedGridContainer(weekStart, null, 'week');
|
const newGrid = this.createOptimizedGridContainer(weekStart, 'week');
|
||||||
|
|
||||||
// Position new grid for animation - NO transform here, let Animation API handle it
|
// Position new grid for animation - NO transform here, let Animation API handle it
|
||||||
newGrid.style.position = 'absolute';
|
newGrid.style.position = 'absolute';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { CalendarConfig } from '../core/CalendarConfig';
|
import { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
|
||||||
|
|
||||||
interface GridSettings {
|
interface GridSettings {
|
||||||
hourHeight: number;
|
hourHeight: number;
|
||||||
|
|
@ -25,17 +24,16 @@ export class GridStyleManager {
|
||||||
/**
|
/**
|
||||||
* Update all grid CSS variables
|
* Update all grid CSS variables
|
||||||
*/
|
*/
|
||||||
public updateGridStyles(resourceData: ResourceCalendarData | null = null): void {
|
public updateGridStyles(): void {
|
||||||
const root = document.documentElement;
|
const root = document.documentElement;
|
||||||
const gridSettings = this.config.getGridSettings();
|
const gridSettings = this.config.getGridSettings();
|
||||||
const calendar = document.querySelector('swp-calendar') as HTMLElement;
|
const calendar = document.querySelector('swp-calendar') as HTMLElement;
|
||||||
const calendarType = this.config.getCalendarMode();
|
|
||||||
|
|
||||||
// Set CSS variables for time and grid measurements
|
// Set CSS variables for time and grid measurements
|
||||||
this.setTimeVariables(root, gridSettings);
|
this.setTimeVariables(root, gridSettings);
|
||||||
|
|
||||||
// Set column count based on calendar type
|
// Set column count based on view
|
||||||
const columnCount = this.calculateColumnCount(calendarType, resourceData);
|
const columnCount = this.calculateColumnCount();
|
||||||
root.style.setProperty('--grid-columns', columnCount.toString());
|
root.style.setProperty('--grid-columns', columnCount.toString());
|
||||||
|
|
||||||
// Set column width based on fitToWidth setting
|
// Set column width based on fitToWidth setting
|
||||||
|
|
@ -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 {
|
private calculateColumnCount(): number {
|
||||||
if (calendarType === 'resource' && resourceData) {
|
const dateSettings = this.config.getDateViewSettings();
|
||||||
return resourceData.resources.length;
|
const workWeekSettings = this.config.getWorkWeekSettings();
|
||||||
} else if (calendarType === 'date') {
|
|
||||||
const dateSettings = this.config.getDateViewSettings();
|
|
||||||
const workWeekSettings = this.config.getWorkWeekSettings();
|
|
||||||
|
|
||||||
switch (dateSettings.period) {
|
switch (dateSettings.period) {
|
||||||
case 'day':
|
case 'day':
|
||||||
return 1;
|
return 1;
|
||||||
case 'week':
|
case 'week':
|
||||||
return workWeekSettings.totalDays;
|
return workWeekSettings.totalDays;
|
||||||
case 'month':
|
case 'month':
|
||||||
return workWeekSettings.totalDays; // Use work week for month view too
|
return workWeekSettings.totalDays; // Use work week for month view too
|
||||||
default:
|
default:
|
||||||
return workWeekSettings.totalDays;
|
return workWeekSettings.totalDays;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.config.getWorkWeekSettings().totalDays; // Default to work week
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Header rendering strategy interface and implementations
|
// Header rendering strategy interface and implementations
|
||||||
|
|
||||||
import { CalendarConfig } from '../core/CalendarConfig';
|
import { CalendarConfig } from '../core/CalendarConfig';
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
|
||||||
import { DateService } from '../utils/DateService';
|
import { DateService } from '../utils/DateService';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -18,7 +17,6 @@ export interface HeaderRenderer {
|
||||||
export interface HeaderRenderContext {
|
export interface HeaderRenderContext {
|
||||||
currentWeek: Date;
|
currentWeek: Date;
|
||||||
config: CalendarConfig;
|
config: CalendarConfig;
|
||||||
resourceData?: ResourceCalendarData | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,31 +60,3 @@ export class DateHeaderRenderer implements HeaderRenderer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Allows clean separation between week view, month view, day view etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context object passed to strategy methods
|
* Context object passed to strategy methods
|
||||||
*/
|
*/
|
||||||
export interface ViewContext {
|
export interface ViewContext {
|
||||||
currentDate: Date;
|
currentDate: Date;
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
resourceData: ResourceCalendarData | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,27 +3,11 @@
|
||||||
// Time period view types (how much time to display)
|
// Time period view types (how much time to display)
|
||||||
export type ViewPeriod = 'day' | 'week' | 'month';
|
export type ViewPeriod = 'day' | 'week' | 'month';
|
||||||
|
|
||||||
// Calendar mode types (how to organize the data)
|
|
||||||
export type CalendarMode = 'date' | 'resource';
|
|
||||||
|
|
||||||
// Type aliases
|
// Type aliases
|
||||||
export type CalendarView = ViewPeriod;
|
export type CalendarView = ViewPeriod;
|
||||||
|
|
||||||
export type SyncStatus = 'synced' | 'pending' | 'error';
|
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 {
|
export interface RenderContext {
|
||||||
container: HTMLElement;
|
container: HTMLElement;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
|
|
@ -39,13 +23,6 @@ export interface CalendarEvent {
|
||||||
allDay: boolean;
|
allDay: boolean;
|
||||||
syncStatus: SyncStatus;
|
syncStatus: SyncStatus;
|
||||||
|
|
||||||
// Resource information (only present in resource calendar mode)
|
|
||||||
resource?: {
|
|
||||||
name: string;
|
|
||||||
displayName: string;
|
|
||||||
employeeId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
recurringId?: string;
|
recurringId?: string;
|
||||||
metadata?: Record<string, any>;
|
metadata?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ export interface EventManager extends IManager {
|
||||||
loadData(): Promise<void>;
|
loadData(): Promise<void>;
|
||||||
getEvents(): CalendarEvent[];
|
getEvents(): CalendarEvent[];
|
||||||
getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[];
|
getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[];
|
||||||
getResourceData(): ResourceData | null;
|
|
||||||
navigateToEvent(eventId: string): boolean;
|
navigateToEvent(eventId: string): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +41,6 @@ export interface EventRenderingService extends IManager {
|
||||||
export interface GridManager extends IManager {
|
export interface GridManager extends IManager {
|
||||||
render(): Promise<void>;
|
render(): Promise<void>;
|
||||||
getDisplayDates(): Date[];
|
getDisplayDates(): Date[];
|
||||||
setResourceData(resourceData: import('./CalendarTypes').ResourceCalendarData | null): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ScrollManager extends IManager {
|
export interface ScrollManager extends IManager {
|
||||||
|
|
@ -76,20 +74,3 @@ export interface AllDayManager extends IManager {
|
||||||
export interface ResizeHandleManager extends IManager {
|
export interface ResizeHandleManager extends IManager {
|
||||||
// ResizeHandleManager handles hover effects for resize handles
|
// 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));
|
min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width));
|
||||||
/* Dynamic width */
|
/* Dynamic width */
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
border-bottom: 1px solid var(--color-border);
|
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
|
@ -198,9 +197,6 @@ swp-calendar-header {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
/* Firefox - hide scrollbar but keep space */
|
|
||||||
scrollbar-width: auto;
|
|
||||||
/* Normal width to match content scrollbar */
|
|
||||||
|
|
||||||
/* All-day events container */
|
/* All-day events container */
|
||||||
swp-allday-container {
|
swp-allday-container {
|
||||||
|
|
@ -211,12 +207,10 @@ swp-calendar-header {
|
||||||
grid-auto-rows: var(--single-row-height);
|
grid-auto-rows: var(--single-row-height);
|
||||||
/* Each row is exactly SINGLE_ROW_HEIGHT */
|
/* Each row is exactly SINGLE_ROW_HEIGHT */
|
||||||
gap: 2px 0px;
|
gap: 2px 0px;
|
||||||
padding: 2px 0px 5px 0px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollbar-color: transparent transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WebKit browsers (Chrome, Safari, Edge) - hide scrollbar but keep space */
|
/* WebKit browsers (Chrome, Safari, Edge) - hide scrollbar but keep space */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue