Moving away from Azure Devops #1

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

View file

@ -9,6 +9,7 @@ import { TeamRenderer } from './features/team/TeamRenderer';
import { RendererRegistry } from './core/RendererRegistry'; import { RendererRegistry } from './core/RendererRegistry';
import { CalendarOrchestrator } from './core/CalendarOrchestrator'; import { CalendarOrchestrator } from './core/CalendarOrchestrator';
import { TimeAxisRenderer } from './features/timeaxis/TimeAxisRenderer'; import { TimeAxisRenderer } from './features/timeaxis/TimeAxisRenderer';
import { ScrollManager } from './core/ScrollManager';
import { MockTeamStore, MockResourceStore } from './demo/MockStores'; import { MockTeamStore, MockResourceStore } from './demo/MockStores';
import { DemoApp } from './demo/DemoApp'; import { DemoApp } from './demo/DemoApp';
@ -45,6 +46,7 @@ export function createV2Container(): Container {
// CalendarOrchestrator modtager IGroupingStore[] automatisk (array injection) // CalendarOrchestrator modtager IGroupingStore[] automatisk (array injection)
builder.registerType(CalendarOrchestrator).as<CalendarOrchestrator>(); builder.registerType(CalendarOrchestrator).as<CalendarOrchestrator>();
builder.registerType(TimeAxisRenderer).as<TimeAxisRenderer>(); builder.registerType(TimeAxisRenderer).as<TimeAxisRenderer>();
builder.registerType(ScrollManager).as<ScrollManager>();
// Demo app // Demo app
builder.registerType(DemoApp).as<DemoApp>(); builder.registerType(DemoApp).as<DemoApp>();

View file

@ -0,0 +1,23 @@
export class ScrollManager {
private scrollableContent!: HTMLElement;
private timeAxisContent!: HTMLElement;
private calendarHeader!: HTMLElement;
init(container: HTMLElement): void {
this.scrollableContent = container.querySelector('swp-scrollable-content')!;
this.timeAxisContent = container.querySelector('swp-time-axis-content')!;
this.calendarHeader = container.querySelector('swp-calendar-header')!;
this.scrollableContent.addEventListener('scroll', () => this.onScroll());
}
private onScroll(): void {
const { scrollTop, scrollLeft } = this.scrollableContent;
// Synkroniser time-axis vertikalt
this.timeAxisContent.style.transform = `translateY(-${scrollTop}px)`;
// Synkroniser header horisontalt
this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`;
}
}

View file

@ -2,6 +2,7 @@ import { CalendarOrchestrator } from '../core/CalendarOrchestrator';
import { TimeAxisRenderer } from '../features/timeaxis/TimeAxisRenderer'; import { TimeAxisRenderer } from '../features/timeaxis/TimeAxisRenderer';
import { NavigationAnimator } from '../core/NavigationAnimator'; import { NavigationAnimator } from '../core/NavigationAnimator';
import { DateService } from '../core/DateService'; import { DateService } from '../core/DateService';
import { ScrollManager } from '../core/ScrollManager';
import { ViewConfig } from '../core/ViewConfig'; import { ViewConfig } from '../core/ViewConfig';
export class DemoApp { export class DemoApp {
@ -13,7 +14,8 @@ export class DemoApp {
constructor( constructor(
private orchestrator: CalendarOrchestrator, private orchestrator: CalendarOrchestrator,
private timeAxisRenderer: TimeAxisRenderer, private timeAxisRenderer: TimeAxisRenderer,
private dateService: DateService private dateService: DateService,
private scrollManager: ScrollManager
) {} ) {}
init(): void { init(): void {
@ -49,6 +51,9 @@ export class DemoApp {
// Render time axis // Render time axis
this.timeAxisRenderer.render(document.getElementById('time-axis') as HTMLElement); this.timeAxisRenderer.render(document.getElementById('time-axis') as HTMLElement);
// Init scroll synkronisering
this.scrollManager.init(this.container);
// Setup event handlers // Setup event handlers
this.setupNavigation(); this.setupNavigation();
this.setupViewSwitchers(); this.setupViewSwitchers();

View file

@ -2,6 +2,8 @@
--hour-height: 60px; --hour-height: 60px;
--time-axis-width: 60px; --time-axis-width: 60px;
--grid-columns: 5; --grid-columns: 5;
--day-start-hour: 0;
--day-end-hour: 24;
--color-border: #e0e0e0; --color-border: #e0e0e0;
--color-surface: #fff; --color-surface: #fff;
--color-text-secondary: #666; --color-text-secondary: #666;
@ -68,6 +70,7 @@ swp-calendar-container {
grid-template-columns: var(--time-axis-width) 1fr; grid-template-columns: var(--time-axis-width) 1fr;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
overflow: hidden; overflow: hidden;
height: 100%;
} }
/* Time axis */ /* Time axis */
@ -78,6 +81,7 @@ swp-time-axis {
grid-template-rows: subgrid; grid-template-rows: subgrid;
border-right: 1px solid var(--color-border); border-right: 1px solid var(--color-border);
background: var(--color-surface); background: var(--color-surface);
overflow: hidden;
} }
swp-header-spacer { swp-header-spacer {
@ -85,8 +89,8 @@ swp-header-spacer {
} }
swp-time-axis-content { swp-time-axis-content {
display: flex; display: grid;
flex-direction: column; grid-auto-rows: var(--hour-height);
overflow: hidden; overflow: hidden;
} }
@ -108,19 +112,31 @@ swp-grid-container {
} }
/* Viewport/Track for slide animation */ /* Viewport/Track for slide animation */
swp-header-viewport, swp-header-viewport {
swp-content-viewport {
overflow: hidden; overflow: hidden;
} }
swp-header-track, swp-content-viewport {
swp-content-track { overflow: hidden;
min-height: 0; /* Tillader at krympe i grid */
}
swp-header-track {
display: flex; display: flex;
} }
swp-header-track > swp-calendar-header, swp-content-track {
display: flex;
height: 100%;
}
swp-header-track > swp-calendar-header {
flex: 0 0 100%;
}
swp-content-track > swp-scrollable-content { swp-content-track > swp-scrollable-content {
flex: 0 0 100%; flex: 0 0 100%;
height: 100%;
} }
/* Header */ /* Header */
@ -129,6 +145,16 @@ swp-calendar-header {
grid-template-columns: repeat(var(--grid-columns), 1fr); grid-template-columns: repeat(var(--grid-columns), 1fr);
grid-auto-rows: auto; grid-auto-rows: auto;
background: var(--color-surface); background: var(--color-surface);
overflow-y: scroll;
overflow-x: hidden;
}
swp-calendar-header::-webkit-scrollbar {
background: transparent;
}
swp-calendar-header::-webkit-scrollbar-thumb {
background: transparent;
} }
swp-calendar-header[data-levels="date"] > swp-day-header { grid-row: 1; } swp-calendar-header[data-levels="date"] > swp-day-header { grid-row: 1; }
@ -182,7 +208,7 @@ swp-scrollable-content {
swp-time-grid { swp-time-grid {
display: block; display: block;
position: relative; position: relative;
min-height: calc(15 * var(--hour-height)); min-height: calc((var(--day-end-hour) - var(--day-start-hour)) * var(--hour-height));
} }
swp-grid-lines { swp-grid-lines {