Adds resource filtering and view customization
Enhances calendar view with dynamic resource selection Enables users to filter and customize calendar views by resources Introduces new event for view updates and dynamic rendering Supports flexible calendar view configuration
This commit is contained in:
parent
8d938c721c
commit
66dfe9f2ef
3 changed files with 61 additions and 5 deletions
|
|
@ -74,5 +74,6 @@ export const CoreEvents = {
|
||||||
CALENDAR_CMD_NAVIGATE_NEXT: 'calendar:cmd:navigate:next',
|
CALENDAR_CMD_NAVIGATE_NEXT: 'calendar:cmd:navigate:next',
|
||||||
CALENDAR_CMD_DRAWER_TOGGLE: 'calendar:cmd:drawer:toggle',
|
CALENDAR_CMD_DRAWER_TOGGLE: 'calendar:cmd:drawer:toggle',
|
||||||
CALENDAR_CMD_RENDER: 'calendar:cmd:render',
|
CALENDAR_CMD_RENDER: 'calendar:cmd:render',
|
||||||
CALENDAR_CMD_WORKWEEK_CHANGE: 'calendar:cmd:workweek:change'
|
CALENDAR_CMD_WORKWEEK_CHANGE: 'calendar:cmd:workweek:change',
|
||||||
|
CALENDAR_CMD_VIEW_UPDATE: 'calendar:cmd:view:update'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ export class CalendarApp {
|
||||||
private weekOffset = 0;
|
private weekOffset = 0;
|
||||||
private currentViewId = 'simple';
|
private currentViewId = 'simple';
|
||||||
private workweekPreset: IWorkweekPreset | null = null;
|
private workweekPreset: IWorkweekPreset | null = null;
|
||||||
|
private groupingOverrides: Map<string, string[]> = new Map();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private orchestrator: CalendarOrchestrator,
|
private orchestrator: CalendarOrchestrator,
|
||||||
|
|
@ -102,6 +103,12 @@ export class CalendarApp {
|
||||||
const { presetId } = e.detail;
|
const { presetId } = e.detail;
|
||||||
this.handleWorkweekChange(presetId);
|
this.handleWorkweekChange(presetId);
|
||||||
}) as EventListener);
|
}) as EventListener);
|
||||||
|
|
||||||
|
// View update via EventBus
|
||||||
|
this.eventBus.on(CoreEvents.CALENDAR_CMD_VIEW_UPDATE, ((e: CustomEvent) => {
|
||||||
|
const { type, values } = e.detail;
|
||||||
|
this.handleViewUpdate(type, values);
|
||||||
|
}) as EventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleRenderCommand(viewId: string): Promise<void> {
|
private async handleRenderCommand(viewId: string): Promise<void> {
|
||||||
|
|
@ -131,6 +138,12 @@ export class CalendarApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleViewUpdate(type: string, values: string[]): Promise<void> {
|
||||||
|
this.groupingOverrides.set(type, values);
|
||||||
|
await this.render();
|
||||||
|
this.emitStatus('rendered', { viewId: this.currentViewId });
|
||||||
|
}
|
||||||
|
|
||||||
private async render(): Promise<void> {
|
private async render(): Promise<void> {
|
||||||
const storedConfig = await this.viewConfigService.getById(this.currentViewId);
|
const storedConfig = await this.viewConfigService.getById(this.currentViewId);
|
||||||
if (!storedConfig) {
|
if (!storedConfig) {
|
||||||
|
|
@ -144,12 +157,21 @@ export class CalendarApp {
|
||||||
? this.dateService.getWeekDates(this.weekOffset, 1)
|
? this.dateService.getWeekDates(this.weekOffset, 1)
|
||||||
: this.dateService.getWorkWeekDates(this.weekOffset, workDays);
|
: this.dateService.getWorkWeekDates(this.weekOffset, workDays);
|
||||||
|
|
||||||
// Clone config and populate dates
|
// Clone config and apply overrides
|
||||||
const viewConfig: ViewConfig = {
|
const viewConfig: ViewConfig = {
|
||||||
...storedConfig,
|
...storedConfig,
|
||||||
groupings: storedConfig.groupings.map(g =>
|
groupings: storedConfig.groupings.map(g => {
|
||||||
g.type === 'date' ? { ...g, values: dates } : g
|
// Apply date values
|
||||||
)
|
if (g.type === 'date') {
|
||||||
|
return { ...g, values: dates };
|
||||||
|
}
|
||||||
|
// Apply grouping overrides
|
||||||
|
const override = this.groupingOverrides.get(g.type);
|
||||||
|
if (override) {
|
||||||
|
return { ...g, values: override };
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.orchestrator.render(viewConfig, this.container);
|
await this.orchestrator.render(viewConfig, this.container);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { DataSeeder } from '../workers/DataSeeder';
|
||||||
import { AuditService } from '../storage/audit/AuditService';
|
import { AuditService } from '../storage/audit/AuditService';
|
||||||
import { CalendarApp } from '../core/CalendarApp';
|
import { CalendarApp } from '../core/CalendarApp';
|
||||||
import { DateService } from '../core/DateService';
|
import { DateService } from '../core/DateService';
|
||||||
|
import { ResourceService } from '../storage/resources/ResourceService';
|
||||||
import { IEventBus } from '../types/CalendarTypes';
|
import { IEventBus } from '../types/CalendarTypes';
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
|
|
||||||
|
|
@ -16,6 +17,7 @@ export class DemoApp {
|
||||||
private auditService: AuditService,
|
private auditService: AuditService,
|
||||||
private calendarApp: CalendarApp,
|
private calendarApp: CalendarApp,
|
||||||
private dateService: DateService,
|
private dateService: DateService,
|
||||||
|
private resourceService: ResourceService,
|
||||||
private eventBus: IEventBus
|
private eventBus: IEventBus
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
@ -42,6 +44,7 @@ export class DemoApp {
|
||||||
this.setupDrawerToggle();
|
this.setupDrawerToggle();
|
||||||
this.setupViewSwitching();
|
this.setupViewSwitching();
|
||||||
this.setupWorkweekSelector();
|
this.setupWorkweekSelector();
|
||||||
|
await this.setupResourceSelector();
|
||||||
|
|
||||||
// Listen for calendar status events
|
// Listen for calendar status events
|
||||||
this.setupStatusListeners();
|
this.setupStatusListeners();
|
||||||
|
|
@ -70,12 +73,19 @@ export class DemoApp {
|
||||||
const view = (chip as HTMLElement).dataset.view;
|
const view = (chip as HTMLElement).dataset.view;
|
||||||
if (view) {
|
if (view) {
|
||||||
this.currentView = view;
|
this.currentView = view;
|
||||||
|
this.updateSelectorVisibility();
|
||||||
this.eventBus.emit(CoreEvents.CALENDAR_CMD_RENDER, { viewId: view });
|
this.eventBus.emit(CoreEvents.CALENDAR_CMD_RENDER, { viewId: view });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateSelectorVisibility(): void {
|
||||||
|
const selector = document.querySelector('swp-resource-selector');
|
||||||
|
const showSelector = this.currentView === 'picker' || this.currentView === 'day';
|
||||||
|
selector?.classList.toggle('hidden', !showSelector);
|
||||||
|
}
|
||||||
|
|
||||||
private setupDrawerToggle(): void {
|
private setupDrawerToggle(): void {
|
||||||
document.getElementById('btn-drawer')!.onclick = () => {
|
document.getElementById('btn-drawer')!.onclick = () => {
|
||||||
this.eventBus.emit(CoreEvents.CALENDAR_CMD_DRAWER_TOGGLE);
|
this.eventBus.emit(CoreEvents.CALENDAR_CMD_DRAWER_TOGGLE);
|
||||||
|
|
@ -90,6 +100,29 @@ export class DemoApp {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async setupResourceSelector(): Promise<void> {
|
||||||
|
const resources = await this.resourceService.getAll();
|
||||||
|
const container = document.querySelector('.resource-checkboxes') as HTMLElement;
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
resources.forEach(r => {
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.innerHTML = `
|
||||||
|
<input type="checkbox" value="${r.id}" checked>
|
||||||
|
${r.displayName}
|
||||||
|
`;
|
||||||
|
container.appendChild(label);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addEventListener('change', () => {
|
||||||
|
const checked = container.querySelectorAll('input:checked') as NodeListOf<HTMLInputElement>;
|
||||||
|
const values = Array.from(checked).map(cb => cb.value);
|
||||||
|
this.eventBus.emit(CoreEvents.CALENDAR_CMD_VIEW_UPDATE, { type: 'resource', values });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private setupStatusListeners(): void {
|
private setupStatusListeners(): void {
|
||||||
this.container.addEventListener('calendar:status:ready', () => {
|
this.container.addEventListener('calendar:status:ready', () => {
|
||||||
console.log('[DemoApp] Calendar ready');
|
console.log('[DemoApp] Calendar ready');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue