Moving away from Azure Devops #1

Merged
Janus007 merged 113 commits from refac into master 2026-02-03 00:04:27 +01:00
3 changed files with 92 additions and 4 deletions
Showing only changes of commit d88956f47b - Show all commits

View file

@ -2,13 +2,15 @@ import { IRenderer, IRenderContext } from './IGroupingRenderer';
import { buildPipeline } from './RenderBuilder'; import { buildPipeline } from './RenderBuilder';
import { EventRenderer } from '../features/event/EventRenderer'; import { EventRenderer } from '../features/event/EventRenderer';
import { ScheduleRenderer } from '../features/schedule/ScheduleRenderer'; import { ScheduleRenderer } from '../features/schedule/ScheduleRenderer';
import { HeaderDrawerRenderer } from '../features/headerdrawer/HeaderDrawerRenderer';
import { ViewConfig } from './ViewConfig'; import { ViewConfig } from './ViewConfig';
export class CalendarOrchestrator { export class CalendarOrchestrator {
constructor( constructor(
private allRenderers: IRenderer[], private allRenderers: IRenderer[],
private eventRenderer: EventRenderer, private eventRenderer: EventRenderer,
private scheduleRenderer: ScheduleRenderer private scheduleRenderer: ScheduleRenderer,
private headerDrawerRenderer: HeaderDrawerRenderer
) {} ) {}
async render(viewConfig: ViewConfig, container: HTMLElement): Promise<void> { async render(viewConfig: ViewConfig, container: HTMLElement): Promise<void> {
@ -48,8 +50,11 @@ export class CalendarOrchestrator {
// Render schedule unavailable zones (før events) // Render schedule unavailable zones (før events)
await this.scheduleRenderer.render(container, filter); await this.scheduleRenderer.render(container, filter);
// Render events med hele filter (date + resource) // Render timed events in grid
await this.eventRenderer.render(container, filter); await this.eventRenderer.render(container, filter);
// Render allDay events in header drawer
await this.headerDrawerRenderer.render(container, filter);
} }
private selectRenderers(viewConfig: ViewConfig): IRenderer[] { private selectRenderers(viewConfig: ViewConfig): IRenderer[] {

View file

@ -1,7 +1,9 @@
import { IEventBus } from '../../types/CalendarTypes'; import { IEventBus, ICalendarEvent } from '../../types/CalendarTypes';
import { IGridConfig } from '../../core/IGridConfig'; import { IGridConfig } from '../../core/IGridConfig';
import { CoreEvents } from '../../constants/CoreEvents'; import { CoreEvents } from '../../constants/CoreEvents';
import { HeaderDrawerManager } from '../../core/HeaderDrawerManager'; import { HeaderDrawerManager } from '../../core/HeaderDrawerManager';
import { EventService } from '../../storage/events/EventService';
import { DateService } from '../../core/DateService';
import { import {
IDragEnterHeaderPayload, IDragEnterHeaderPayload,
IDragMoveHeaderPayload, IDragMoveHeaderPayload,
@ -26,11 +28,90 @@ export class HeaderDrawerRenderer {
constructor( constructor(
private eventBus: IEventBus, private eventBus: IEventBus,
private gridConfig: IGridConfig, private gridConfig: IGridConfig,
private headerDrawerManager: HeaderDrawerManager private headerDrawerManager: HeaderDrawerManager,
private eventService: EventService,
private dateService: DateService
) { ) {
this.setupListeners(); this.setupListeners();
} }
/**
* Render allDay events into the header drawer
*/
async render(container: HTMLElement, filter: Record<string, string[]>): Promise<void> {
const drawer = container.querySelector('swp-header-drawer');
if (!drawer) return;
const visibleDates = filter['date'] || [];
if (visibleDates.length === 0) return;
// Fetch events for date range
const startDate = new Date(visibleDates[0]);
const endDate = new Date(visibleDates[visibleDates.length - 1]);
endDate.setHours(23, 59, 59, 999);
const events = await this.eventService.getByDateRange(startDate, endDate);
// Filter to allDay events only (allDay !== false)
const allDayEvents = events.filter(event => event.allDay !== false);
// Clear existing items
drawer.innerHTML = '';
// Render each allDay event
allDayEvents.forEach(event => {
const item = this.createHeaderItem(event, visibleDates);
if (item) drawer.appendChild(item);
});
// Expand drawer if there are items
if (allDayEvents.length > 0) {
this.headerDrawerManager.expand();
}
}
/**
* Create a header item element for an allDay event
*/
private createHeaderItem(event: ICalendarEvent, visibleDates: string[]): HTMLElement | null {
const dateKey = this.dateService.getDateKey(event.start);
const colIndex = visibleDates.indexOf(dateKey);
if (colIndex === -1) return null; // Event not in visible range
const item = document.createElement('swp-header-item');
item.dataset.eventId = event.id;
item.dataset.itemType = 'event';
item.dataset.date = dateKey;
item.textContent = event.title;
// Color class
const colorClass = this.getColorClass(event);
if (colorClass) item.classList.add(colorClass);
// Grid position (1-indexed)
const col = colIndex + 1;
item.style.gridArea = `1 / ${col} / 2 / ${col + 1}`;
return item;
}
/**
* Get color class based on event metadata or type
*/
private getColorClass(event: ICalendarEvent): string {
if (event.metadata?.color) {
return `is-${event.metadata.color}`;
}
const typeColors: Record<string, string> = {
'customer': 'is-blue',
'vacation': 'is-green',
'break': 'is-amber',
'meeting': 'is-purple',
'blocked': 'is-red'
};
return typeColors[event.type] || 'is-blue';
}
/** /**
* Setup event listeners for drag events * Setup event listeners for drag events
*/ */

View file

@ -41,11 +41,13 @@ export class EventPersistenceManager {
} }
// Update and save - start/end already calculated in SwpEvent // Update and save - start/end already calculated in SwpEvent
// If dropped in header, mark as allDay
const updatedEvent: ICalendarEvent = { const updatedEvent: ICalendarEvent = {
...event, ...event,
start: swpEvent.start, start: swpEvent.start,
end: swpEvent.end, end: swpEvent.end,
resourceId: swpEvent.resourceId ?? event.resourceId, resourceId: swpEvent.resourceId ?? event.resourceId,
allDay: payload.target === 'header' ? true : event.allDay,
syncStatus: 'pending' syncStatus: 'pending'
}; };