Implements dynamic renderer injection
Uses dependency injection to dynamically resolve renderers based on the calendar mode. This change decouples the HeaderManager from specific renderer implementations, allowing for more flexible configuration and easier addition of new calendar types. The appropriate renderer is bound to a token in the DI container at startup.
This commit is contained in:
parent
f7c67e6253
commit
bf4b9b5064
4 changed files with 58 additions and 17 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
import { Container } from 'brandi';
|
import { Container } from 'brandi';
|
||||||
import { TOKENS } from './tokens';
|
import { TOKENS } from './tokens';
|
||||||
import { eventBus } from '../core/EventBus';
|
import { eventBus } from '../core/EventBus';
|
||||||
|
import { calendarConfig } from '../core/CalendarConfig';
|
||||||
|
|
||||||
// Import all managers
|
// Import all managers
|
||||||
import { EventManager } from '../managers/EventManager';
|
import { EventManager } from '../managers/EventManager';
|
||||||
|
|
@ -22,6 +23,11 @@ import { EdgeScrollManager } from '../managers/EdgeScrollManager';
|
||||||
import { DragHoverManager } from '../managers/DragHoverManager';
|
import { DragHoverManager } from '../managers/DragHoverManager';
|
||||||
import { HeaderManager } from '../managers/HeaderManager';
|
import { HeaderManager } from '../managers/HeaderManager';
|
||||||
|
|
||||||
|
// Import renderers
|
||||||
|
import { DateHeaderRenderer, ResourceHeaderRenderer } from '../renderers/HeaderRenderer';
|
||||||
|
import { DateColumnRenderer, ResourceColumnRenderer } from '../renderers/ColumnRenderer';
|
||||||
|
import { DateEventRenderer } from '../renderers/EventRenderer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and configure the DI container
|
* Create and configure the DI container
|
||||||
* Using manual instantiation instead of automatic injection
|
* Using manual instantiation instead of automatic injection
|
||||||
|
|
@ -32,6 +38,24 @@ export function createContainer(): Container {
|
||||||
// Bind core services as constant
|
// Bind core services as constant
|
||||||
container.bind(TOKENS.eventBus).toConstant(eventBus);
|
container.bind(TOKENS.eventBus).toConstant(eventBus);
|
||||||
|
|
||||||
|
// Determine calendar mode at startup and bind appropriate renderers
|
||||||
|
const calendarMode = calendarConfig.getCalendarMode();
|
||||||
|
console.log('🔧 DI Container: Calendar mode detected:', calendarMode);
|
||||||
|
|
||||||
|
if (calendarMode === 'resource') {
|
||||||
|
// Resource mode renderers
|
||||||
|
console.log('🔧 DI Container: Binding DateHeaderRenderer for resource mode (TEST)');
|
||||||
|
container.bind(TOKENS.headerRenderer).toConstant(new DateHeaderRenderer());
|
||||||
|
container.bind(TOKENS.columnRenderer).toConstant(new DateColumnRenderer());
|
||||||
|
container.bind(TOKENS.eventRendererStrategy).toConstant(new DateEventRenderer()); // TODO: ResourceEventRenderer
|
||||||
|
} else {
|
||||||
|
// Date mode renderers (default)
|
||||||
|
console.log('🔧 DI Container: Binding DateHeaderRenderer for date mode');
|
||||||
|
container.bind(TOKENS.headerRenderer).toConstant(new DateHeaderRenderer());
|
||||||
|
container.bind(TOKENS.columnRenderer).toConstant(new DateColumnRenderer());
|
||||||
|
container.bind(TOKENS.eventRendererStrategy).toConstant(new DateEventRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
// Create instances manually and bind as constants (singletons)
|
// Create instances manually and bind as constants (singletons)
|
||||||
// This is simpler than using decorators or complex factory setup
|
// This is simpler than using decorators or complex factory setup
|
||||||
|
|
||||||
|
|
@ -68,7 +92,7 @@ export function createContainer(): Container {
|
||||||
const dragHoverManager = new DragHoverManager(eventBus);
|
const dragHoverManager = new DragHoverManager(eventBus);
|
||||||
container.bind(TOKENS.dragHoverManager).toConstant(dragHoverManager);
|
container.bind(TOKENS.dragHoverManager).toConstant(dragHoverManager);
|
||||||
|
|
||||||
const headerManager = new HeaderManager();
|
const headerManager = new HeaderManager(container.get(TOKENS.headerRenderer));
|
||||||
container.bind(TOKENS.headerManager).toConstant(headerManager);
|
container.bind(TOKENS.headerManager).toConstant(headerManager);
|
||||||
|
|
||||||
// CalendarManager depends on multiple managers
|
// CalendarManager depends on multiple managers
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ import { ResizeHandleManager } from '../managers/ResizeHandleManager';
|
||||||
import { EdgeScrollManager } from '../managers/EdgeScrollManager';
|
import { EdgeScrollManager } from '../managers/EdgeScrollManager';
|
||||||
import { DragHoverManager } from '../managers/DragHoverManager';
|
import { DragHoverManager } from '../managers/DragHoverManager';
|
||||||
import { HeaderManager } from '../managers/HeaderManager';
|
import { HeaderManager } from '../managers/HeaderManager';
|
||||||
|
import { HeaderRenderer } from '../renderers/HeaderRenderer';
|
||||||
|
import { ColumnRenderer } from '../renderers/ColumnRenderer';
|
||||||
|
import { EventRendererStrategy } from '../renderers/EventRenderer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DI Tokens - Type-safe identifiers for dependency injection
|
* DI Tokens - Type-safe identifiers for dependency injection
|
||||||
|
|
@ -26,6 +29,11 @@ export const TOKENS = {
|
||||||
// Core services
|
// Core services
|
||||||
eventBus: token<IEventBus>('eventBus'),
|
eventBus: token<IEventBus>('eventBus'),
|
||||||
|
|
||||||
|
// Renderers (polymorphic - resolved based on calendar mode)
|
||||||
|
headerRenderer: token<HeaderRenderer>('headerRenderer'),
|
||||||
|
columnRenderer: token<ColumnRenderer>('columnRenderer'),
|
||||||
|
eventRendererStrategy: token<EventRendererStrategy>('eventRendererStrategy'),
|
||||||
|
|
||||||
// Managers
|
// Managers
|
||||||
eventManager: token<EventManager>('eventManager'),
|
eventManager: token<EventManager>('eventManager'),
|
||||||
eventRenderer: token<EventRenderingService>('eventRenderer'),
|
eventRenderer: token<EventRenderingService>('eventRenderer'),
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ export class ManagerFactory {
|
||||||
const resizeHandleManager = new ResizeHandleManager();
|
const resizeHandleManager = new ResizeHandleManager();
|
||||||
const edgeScrollManager = new EdgeScrollManager(eventBus);
|
const edgeScrollManager = new EdgeScrollManager(eventBus);
|
||||||
const dragHoverManager = new DragHoverManager(eventBus);
|
const dragHoverManager = new DragHoverManager(eventBus);
|
||||||
const headerManager = new HeaderManager();
|
// HeaderManager now requires HeaderRenderer via DI - will be created in Brandi container
|
||||||
|
// const headerManager = new HeaderManager();
|
||||||
|
|
||||||
// CalendarManager depends on all other managers
|
// CalendarManager depends on all other managers
|
||||||
const calendarManager = new CalendarManager(
|
const calendarManager = new CalendarManager(
|
||||||
|
|
@ -71,7 +72,7 @@ export class ManagerFactory {
|
||||||
resizeHandleManager,
|
resizeHandleManager,
|
||||||
edgeScrollManager,
|
edgeScrollManager,
|
||||||
dragHoverManager,
|
dragHoverManager,
|
||||||
headerManager
|
headerManager: null as any // HeaderManager created in Brandi container
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { eventBus } from '../core/EventBus';
|
import { eventBus } from '../core/EventBus';
|
||||||
import { calendarConfig } from '../core/CalendarConfig';
|
import { calendarConfig } from '../core/CalendarConfig';
|
||||||
import { CalendarTypeFactory } from '../factories/CalendarTypeFactory';
|
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { HeaderRenderContext } from '../renderers/HeaderRenderer';
|
import { HeaderRenderer, HeaderRenderContext } from '../renderers/HeaderRenderer';
|
||||||
import { ResourceCalendarData } from '../types/CalendarTypes';
|
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';
|
||||||
|
|
@ -10,10 +9,14 @@ import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils';
|
||||||
/**
|
/**
|
||||||
* HeaderManager - Handles all header-related event logic
|
* HeaderManager - Handles all header-related event logic
|
||||||
* Separates event handling from rendering concerns
|
* Separates event handling from rendering concerns
|
||||||
|
* Uses dependency injection for renderer strategy
|
||||||
*/
|
*/
|
||||||
export class HeaderManager {
|
export class HeaderManager {
|
||||||
|
private headerRenderer: HeaderRenderer;
|
||||||
|
|
||||||
|
constructor(headerRenderer: HeaderRenderer) {
|
||||||
|
this.headerRenderer = headerRenderer;
|
||||||
|
|
||||||
constructor() {
|
|
||||||
// Bind handler methods for event listeners
|
// Bind handler methods for event listeners
|
||||||
this.handleDragMouseEnterHeader = this.handleDragMouseEnterHeader.bind(this);
|
this.handleDragMouseEnterHeader = this.handleDragMouseEnterHeader.bind(this);
|
||||||
this.handleDragMouseLeaveHeader = this.handleDragMouseLeaveHeader.bind(this);
|
this.handleDragMouseLeaveHeader = this.handleDragMouseLeaveHeader.bind(this);
|
||||||
|
|
@ -62,10 +65,7 @@ export class HeaderManager {
|
||||||
cloneElement: !!cloneElement
|
cloneElement: !!cloneElement
|
||||||
});
|
});
|
||||||
|
|
||||||
if (targetDate) {
|
// Header renderer already injected - ready to use if needed
|
||||||
const calendarType = calendarConfig.getCalendarMode();
|
|
||||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -109,23 +109,31 @@ 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, resourceData: ResourceCalendarData | null = null): void {
|
||||||
|
console.log('🎯 HeaderManager.updateHeader called', {
|
||||||
|
currentDate,
|
||||||
|
hasResourceData: !!resourceData,
|
||||||
|
rendererType: this.headerRenderer.constructor.name
|
||||||
|
});
|
||||||
|
|
||||||
const calendarHeader = this.getOrCreateCalendarHeader();
|
const calendarHeader = this.getOrCreateCalendarHeader();
|
||||||
if (!calendarHeader) return;
|
if (!calendarHeader) {
|
||||||
|
console.warn('❌ HeaderManager: No calendar header found!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear existing content
|
// Clear existing content
|
||||||
calendarHeader.innerHTML = '';
|
calendarHeader.innerHTML = '';
|
||||||
|
|
||||||
// Render new header content
|
// Render new header content using injected renderer
|
||||||
const calendarType = calendarConfig.getCalendarMode();
|
|
||||||
const headerRenderer = CalendarTypeFactory.getHeaderRenderer(calendarType);
|
|
||||||
|
|
||||||
const context: HeaderRenderContext = {
|
const context: HeaderRenderContext = {
|
||||||
currentWeek: currentDate,
|
currentWeek: currentDate,
|
||||||
config: calendarConfig,
|
config: calendarConfig,
|
||||||
resourceData: resourceData
|
resourceData: resourceData
|
||||||
};
|
};
|
||||||
|
|
||||||
headerRenderer.render(calendarHeader, context);
|
console.log('🎨 HeaderManager: Calling renderer.render()', context);
|
||||||
|
this.headerRenderer.render(calendarHeader, context);
|
||||||
|
console.log('✅ HeaderManager: Renderer completed');
|
||||||
|
|
||||||
// Setup event listeners on the new content
|
// Setup event listeners on the new content
|
||||||
this.setupHeaderDragListeners();
|
this.setupHeaderDragListeners();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue