Moving away from Azure Devops #1
5 changed files with 526 additions and 43 deletions
|
|
@ -24,7 +24,7 @@ import {
|
||||||
export class CalendarApp {
|
export class CalendarApp {
|
||||||
private animator!: NavigationAnimator;
|
private animator!: NavigationAnimator;
|
||||||
private container!: HTMLElement;
|
private container!: HTMLElement;
|
||||||
private weekOffset = 0;
|
private dayOffset = 0;
|
||||||
private currentViewId = 'simple';
|
private currentViewId = 'simple';
|
||||||
private workweekPreset: IWorkweekPreset | null = null;
|
private workweekPreset: IWorkweekPreset | null = null;
|
||||||
private groupingOverrides: Map<string, string[]> = new Map();
|
private groupingOverrides: Map<string, string[]> = new Map();
|
||||||
|
|
@ -126,13 +126,15 @@ export class CalendarApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleNavigatePrev(): Promise<void> {
|
private async handleNavigatePrev(): Promise<void> {
|
||||||
this.weekOffset--;
|
const step = this.workweekPreset?.periodDays ?? 7;
|
||||||
|
this.dayOffset -= step;
|
||||||
await this.animator.slide('right', () => this.render());
|
await this.animator.slide('right', () => this.render());
|
||||||
this.emitStatus('rendered', { viewId: this.currentViewId });
|
this.emitStatus('rendered', { viewId: this.currentViewId });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleNavigateNext(): Promise<void> {
|
private async handleNavigateNext(): Promise<void> {
|
||||||
this.weekOffset++;
|
const step = this.workweekPreset?.periodDays ?? 7;
|
||||||
|
this.dayOffset += step;
|
||||||
await this.animator.slide('left', () => this.render());
|
await this.animator.slide('left', () => this.render());
|
||||||
this.emitStatus('rendered', { viewId: this.currentViewId });
|
this.emitStatus('rendered', { viewId: this.currentViewId });
|
||||||
}
|
}
|
||||||
|
|
@ -159,11 +161,15 @@ export class CalendarApp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate date values based on workweek and offset
|
// Populate date values based on workweek preset and day offset
|
||||||
const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5];
|
const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5];
|
||||||
const dates = this.currentViewId === 'day'
|
const periodDays = this.workweekPreset?.periodDays ?? 7;
|
||||||
? this.dateService.getWeekDates(this.weekOffset, 1)
|
|
||||||
: this.dateService.getWorkWeekDates(this.weekOffset, workDays);
|
// For single-day navigation (periodDays=1), show consecutive days from offset
|
||||||
|
// For week navigation (periodDays=7), show workDays from the week containing offset
|
||||||
|
const dates = periodDays === 1
|
||||||
|
? this.dateService.getDatesFromOffset(this.dayOffset, workDays.length)
|
||||||
|
: this.dateService.getWorkDaysFromOffset(this.dayOffset, workDays);
|
||||||
|
|
||||||
// Clone config and apply overrides
|
// Clone config and apply overrides
|
||||||
const viewConfig: ViewConfig = {
|
const viewConfig: ViewConfig = {
|
||||||
|
|
|
||||||
|
|
@ -41,21 +41,30 @@ export class DateService {
|
||||||
return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date);
|
return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWeekDates(offset = 0, days = 7): string[] {
|
/**
|
||||||
const monday = this.baseDate.startOf('week').add(1, 'day').add(offset, 'week');
|
* Get dates starting from a day offset
|
||||||
return Array.from({ length: days }, (_, i) =>
|
* @param dayOffset - Day offset from base date
|
||||||
monday.add(i, 'day').format('YYYY-MM-DD')
|
* @param count - Number of consecutive days to return
|
||||||
|
* @returns Array of date strings in YYYY-MM-DD format
|
||||||
|
*/
|
||||||
|
getDatesFromOffset(dayOffset: number, count: number): string[] {
|
||||||
|
const startDate = this.baseDate.add(dayOffset, 'day');
|
||||||
|
return Array.from({ length: count }, (_, i) =>
|
||||||
|
startDate.add(i, 'day').format('YYYY-MM-DD')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get dates for specific weekdays within a week
|
* Get specific weekdays from the week containing the offset date
|
||||||
* @param offset - Week offset from base date (0 = current week)
|
* @param dayOffset - Day offset from base date
|
||||||
* @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday)
|
* @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday)
|
||||||
* @returns Array of date strings in YYYY-MM-DD format
|
* @returns Array of date strings in YYYY-MM-DD format
|
||||||
*/
|
*/
|
||||||
getWorkWeekDates(offset: number, workDays: number[]): string[] {
|
getWorkDaysFromOffset(dayOffset: number, workDays: number[]): string[] {
|
||||||
const monday = this.baseDate.startOf('week').add(1, 'day').add(offset, 'week');
|
// Get the date at offset, then find its week's Monday
|
||||||
|
const targetDate = this.baseDate.add(dayOffset, 'day');
|
||||||
|
const monday = targetDate.startOf('week').add(1, 'day');
|
||||||
|
|
||||||
return workDays.map(isoDay => {
|
return workDays.map(isoDay => {
|
||||||
// ISO: 1=Monday, 7=Sunday → days from Monday: 0-6
|
// ISO: 1=Monday, 7=Sunday → days from Monday: 0-6
|
||||||
const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1;
|
const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1;
|
||||||
|
|
@ -63,6 +72,15 @@ export class DateService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy methods for backwards compatibility
|
||||||
|
getWeekDates(weekOffset = 0, days = 7): string[] {
|
||||||
|
return this.getDatesFromOffset(weekOffset * 7, days);
|
||||||
|
}
|
||||||
|
|
||||||
|
getWorkWeekDates(weekOffset: number, workDays: number[]): string[] {
|
||||||
|
return this.getWorkDaysFromOffset(weekOffset * 7, workDays);
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// FORMATTING
|
// FORMATTING
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ export interface IWorkweekPreset {
|
||||||
id: string;
|
id: string;
|
||||||
workDays: number[];
|
workDays: number[];
|
||||||
label: string;
|
label: string;
|
||||||
|
periodDays: number; // Navigation step in days (1 = day, 7 = week)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,262 @@
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV24-001",
|
||||||
|
"title": "Herreklipning",
|
||||||
|
"start": "2025-11-24T09:00:00",
|
||||||
|
"end": "2025-11-24T09:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N01",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST001",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "blue" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV24-002",
|
||||||
|
"title": "Balayage",
|
||||||
|
"start": "2025-11-24T10:00:00",
|
||||||
|
"end": "2025-11-24T12:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N02",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST002",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "purple" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV24-003",
|
||||||
|
"title": "Klipning dame",
|
||||||
|
"start": "2025-11-24T14:00:00",
|
||||||
|
"end": "2025-11-24T15:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N03",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST003",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "teal" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV25-001",
|
||||||
|
"title": "Farve behandling",
|
||||||
|
"start": "2025-11-25T09:00:00",
|
||||||
|
"end": "2025-11-25T11:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N04",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST004",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "orange" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV25-002",
|
||||||
|
"title": "Permanent",
|
||||||
|
"start": "2025-11-25T12:00:00",
|
||||||
|
"end": "2025-11-25T14:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N05",
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"customerId": "CUST005",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "indigo" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV26-001",
|
||||||
|
"title": "Highlights",
|
||||||
|
"start": "2025-11-26T10:00:00",
|
||||||
|
"end": "2025-11-26T12:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N06",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST006",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "lime" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV26-002",
|
||||||
|
"title": "Børneklip",
|
||||||
|
"start": "2025-11-26T14:00:00",
|
||||||
|
"end": "2025-11-26T14:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N07",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST007",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "cyan" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV27-001",
|
||||||
|
"title": "Olaplex behandling",
|
||||||
|
"start": "2025-11-27T09:00:00",
|
||||||
|
"end": "2025-11-27T10:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N08",
|
||||||
|
"resourceId": "EMP005",
|
||||||
|
"customerId": "CUST008",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "pink" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV27-002",
|
||||||
|
"title": "Skæg trim",
|
||||||
|
"start": "2025-11-27T11:00:00",
|
||||||
|
"end": "2025-11-27T11:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N09",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST009",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "teal" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-NOV28-001",
|
||||||
|
"title": "Extensions",
|
||||||
|
"start": "2025-11-28T09:00:00",
|
||||||
|
"end": "2025-11-28T12:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N10",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST010",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "deep-purple" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC01-001",
|
||||||
|
"title": "Klipning og føn",
|
||||||
|
"start": "2025-12-01T10:00:00",
|
||||||
|
"end": "2025-12-01T11:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N11",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST011",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "blue" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC01-002",
|
||||||
|
"title": "Farve korrektion",
|
||||||
|
"start": "2025-12-01T13:00:00",
|
||||||
|
"end": "2025-12-01T16:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N12",
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"customerId": "CUST012",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "magenta" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC02-001",
|
||||||
|
"title": "Bryllupsfrisure prøve",
|
||||||
|
"start": "2025-12-02T09:00:00",
|
||||||
|
"end": "2025-12-02T11:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N13",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST013",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "green" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC02-002",
|
||||||
|
"title": "Herreklip express",
|
||||||
|
"start": "2025-12-02T14:00:00",
|
||||||
|
"end": "2025-12-02T14:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N14",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST014",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "amber" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC03-001",
|
||||||
|
"title": "Keratin behandling",
|
||||||
|
"start": "2025-12-03T10:00:00",
|
||||||
|
"end": "2025-12-03T13:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N15",
|
||||||
|
"resourceId": "EMP005",
|
||||||
|
"customerId": "CUST001",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "violet" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC03-002",
|
||||||
|
"title": "Vask og styling",
|
||||||
|
"start": "2025-12-03T15:00:00",
|
||||||
|
"end": "2025-12-03T15:45:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N16",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST002",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "light-green" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC04-001",
|
||||||
|
"title": "Balayage kort hår",
|
||||||
|
"start": "2025-12-04T09:00:00",
|
||||||
|
"end": "2025-12-04T10:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N17",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST003",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "purple" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC04-002",
|
||||||
|
"title": "Ferie",
|
||||||
|
"start": "2025-12-04T00:00:00",
|
||||||
|
"end": "2025-12-05T23:59:59",
|
||||||
|
"type": "vacation",
|
||||||
|
"allDay": true,
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "red" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC05-001",
|
||||||
|
"title": "Dameklip langt hår",
|
||||||
|
"start": "2025-12-05T11:00:00",
|
||||||
|
"end": "2025-12-05T12:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N18",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST004",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "pink" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC05-002",
|
||||||
|
"title": "Highlights delvis",
|
||||||
|
"start": "2025-12-05T14:00:00",
|
||||||
|
"end": "2025-12-05T15:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-N19",
|
||||||
|
"resourceId": "EMP005",
|
||||||
|
"customerId": "CUST005",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "lime" }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC08-001",
|
"id": "EVT-DEC08-001",
|
||||||
"title": "Balayage langt hår",
|
"title": "Balayage langt hår",
|
||||||
|
|
@ -11,7 +269,7 @@
|
||||||
"resourceId": "EMP001",
|
"resourceId": "EMP001",
|
||||||
"customerId": "CUST001",
|
"customerId": "CUST001",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 60, "color": "purple" }
|
"metadata": { "color": "purple" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC08-002",
|
"id": "EVT-DEC08-002",
|
||||||
|
|
@ -25,7 +283,7 @@
|
||||||
"resourceId": "EMP001",
|
"resourceId": "EMP001",
|
||||||
"customerId": "CUST002",
|
"customerId": "CUST002",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 90, "color": "pink" }
|
"metadata": { "color": "pink" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC08-003",
|
"id": "EVT-DEC08-003",
|
||||||
|
|
@ -39,7 +297,7 @@
|
||||||
"resourceId": "EMP002",
|
"resourceId": "EMP002",
|
||||||
"customerId": "CUST003",
|
"customerId": "CUST003",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 120, "color": "indigo" }
|
"metadata": { "color": "indigo" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC08-004",
|
"id": "EVT-DEC08-004",
|
||||||
|
|
@ -53,7 +311,7 @@
|
||||||
"resourceId": "EMP002",
|
"resourceId": "EMP002",
|
||||||
"customerId": "CUST004",
|
"customerId": "CUST004",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 120, "color": "orange" }
|
"metadata": { "color": "orange" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC09-001",
|
"id": "EVT-DEC09-001",
|
||||||
|
|
@ -67,21 +325,19 @@
|
||||||
"resourceId": "EMP003",
|
"resourceId": "EMP003",
|
||||||
"customerId": "CUST005",
|
"customerId": "CUST005",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 30, "color": "teal" }
|
"metadata": { "color": "teal" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC09-002",
|
"id": "EVT-DEC09-002",
|
||||||
"title": "Skæg trimning",
|
"title": "Kursus",
|
||||||
"description": "Skæg trim og styling",
|
"description": "Ekstern kursusdag",
|
||||||
"start": "2025-12-09T00:00:00",
|
"start": "2025-12-09T00:00:00",
|
||||||
"end": "2025-12-10T23:59:59",
|
"end": "2025-12-10T23:59:59",
|
||||||
"type": "customer",
|
"type": "blocked",
|
||||||
"allDay": true,
|
"allDay": true,
|
||||||
"bookingId": "BOOK-006",
|
|
||||||
"resourceId": "EMP003",
|
"resourceId": "EMP003",
|
||||||
"customerId": "CUST006",
|
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 30, "color": "cyan" }
|
"metadata": { "color": "cyan" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC09-003",
|
"id": "EVT-DEC09-003",
|
||||||
|
|
@ -95,7 +351,7 @@
|
||||||
"resourceId": "EMP004",
|
"resourceId": "EMP004",
|
||||||
"customerId": "CUST007",
|
"customerId": "CUST007",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 120, "color": "green" }
|
"metadata": { "color": "green" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC10-001",
|
"id": "EVT-DEC10-001",
|
||||||
|
|
@ -109,7 +365,7 @@
|
||||||
"resourceId": "EMP005",
|
"resourceId": "EMP005",
|
||||||
"customerId": "CUST008",
|
"customerId": "CUST008",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 120, "color": "lime" }
|
"metadata": { "color": "lime" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC10-002",
|
"id": "EVT-DEC10-002",
|
||||||
|
|
@ -121,7 +377,7 @@
|
||||||
"allDay": false,
|
"allDay": false,
|
||||||
"resourceId": "EMP005",
|
"resourceId": "EMP005",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 30, "color": "amber" }
|
"metadata": { "color": "amber" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC10-003",
|
"id": "EVT-DEC10-003",
|
||||||
|
|
@ -135,7 +391,7 @@
|
||||||
"resourceId": "EMP001",
|
"resourceId": "EMP001",
|
||||||
"customerId": "CUST009",
|
"customerId": "CUST009",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 90, "color": "blue" }
|
"metadata": { "color": "blue" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC11-001",
|
"id": "EVT-DEC11-001",
|
||||||
|
|
@ -149,7 +405,7 @@
|
||||||
"resourceId": "EMP002",
|
"resourceId": "EMP002",
|
||||||
"customerId": "CUST010",
|
"customerId": "CUST010",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 180, "color": "deep-purple" }
|
"metadata": { "color": "deep-purple" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC11-002",
|
"id": "EVT-DEC11-002",
|
||||||
|
|
@ -163,19 +419,19 @@
|
||||||
"resourceId": "EMP003",
|
"resourceId": "EMP003",
|
||||||
"customerId": "CUST011",
|
"customerId": "CUST011",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 30, "color": "light-blue" }
|
"metadata": { "color": "light-blue" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC11-003",
|
"id": "EVT-DEC11-003",
|
||||||
"title": "Frisør møde",
|
"title": "Team møde",
|
||||||
"description": "Team møde",
|
"description": "Morgen briefing",
|
||||||
"start": "2025-12-11T08:00:00",
|
"start": "2025-12-11T08:00:00",
|
||||||
"end": "2025-12-11T08:30:00",
|
"end": "2025-12-11T08:30:00",
|
||||||
"type": "meeting",
|
"type": "meeting",
|
||||||
"allDay": false,
|
"allDay": false,
|
||||||
"resourceId": "EMP001",
|
"resourceId": "EMP001",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 30, "color": "red" }
|
"metadata": { "color": "red" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC12-001",
|
"id": "EVT-DEC12-001",
|
||||||
|
|
@ -189,7 +445,7 @@
|
||||||
"resourceId": "EMP004",
|
"resourceId": "EMP004",
|
||||||
"customerId": "CUST012",
|
"customerId": "CUST012",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 180, "color": "violet" }
|
"metadata": { "color": "violet" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC12-002",
|
"id": "EVT-DEC12-002",
|
||||||
|
|
@ -203,7 +459,7 @@
|
||||||
"resourceId": "EMP005",
|
"resourceId": "EMP005",
|
||||||
"customerId": "CUST013",
|
"customerId": "CUST013",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 45, "color": "light-green" }
|
"metadata": { "color": "light-green" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "EVT-DEC12-003",
|
"id": "EVT-DEC12-003",
|
||||||
|
|
@ -217,6 +473,197 @@
|
||||||
"resourceId": "EMP001",
|
"resourceId": "EMP001",
|
||||||
"customerId": "CUST014",
|
"customerId": "CUST014",
|
||||||
"syncStatus": "synced",
|
"syncStatus": "synced",
|
||||||
"metadata": { "duration": 180, "color": "magenta" }
|
"metadata": { "color": "magenta" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC15-001",
|
||||||
|
"title": "Juleklipning",
|
||||||
|
"start": "2025-12-15T09:00:00",
|
||||||
|
"end": "2025-12-15T10:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F01",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST001",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "red" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC15-002",
|
||||||
|
"title": "Balayage jul",
|
||||||
|
"start": "2025-12-15T11:00:00",
|
||||||
|
"end": "2025-12-15T13:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F02",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST002",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "purple" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC15-003",
|
||||||
|
"title": "Herreklip",
|
||||||
|
"start": "2025-12-15T14:00:00",
|
||||||
|
"end": "2025-12-15T14:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F03",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST003",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "blue" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC16-001",
|
||||||
|
"title": "Farve og klip",
|
||||||
|
"start": "2025-12-16T10:00:00",
|
||||||
|
"end": "2025-12-16T12:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F04",
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"customerId": "CUST004",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "orange" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC16-002",
|
||||||
|
"title": "Permanent",
|
||||||
|
"start": "2025-12-16T13:00:00",
|
||||||
|
"end": "2025-12-16T15:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F05",
|
||||||
|
"resourceId": "EMP005",
|
||||||
|
"customerId": "CUST005",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "indigo" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC17-001",
|
||||||
|
"title": "Julefrokost",
|
||||||
|
"start": "2025-12-17T12:00:00",
|
||||||
|
"end": "2025-12-17T14:00:00",
|
||||||
|
"type": "meeting",
|
||||||
|
"allDay": false,
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "green" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC17-002",
|
||||||
|
"title": "Extensions fjernelse",
|
||||||
|
"start": "2025-12-17T09:00:00",
|
||||||
|
"end": "2025-12-17T11:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F06",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST006",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "deep-purple" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC18-001",
|
||||||
|
"title": "Highlights jul",
|
||||||
|
"start": "2025-12-18T10:00:00",
|
||||||
|
"end": "2025-12-18T12:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F07",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST007",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "lime" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC18-002",
|
||||||
|
"title": "Børneklip jul",
|
||||||
|
"start": "2025-12-18T14:00:00",
|
||||||
|
"end": "2025-12-18T14:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F08",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST008",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "cyan" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC19-001",
|
||||||
|
"title": "Festfrisure",
|
||||||
|
"start": "2025-12-19T09:00:00",
|
||||||
|
"end": "2025-12-19T10:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F09",
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"customerId": "CUST009",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "pink" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC19-002",
|
||||||
|
"title": "Julestyling",
|
||||||
|
"start": "2025-12-19T11:00:00",
|
||||||
|
"end": "2025-12-19T12:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F10",
|
||||||
|
"resourceId": "EMP005",
|
||||||
|
"customerId": "CUST010",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "amber" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC19-003",
|
||||||
|
"title": "Klipning og farve",
|
||||||
|
"start": "2025-12-19T14:00:00",
|
||||||
|
"end": "2025-12-19T16:30:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F11",
|
||||||
|
"resourceId": "EMP001",
|
||||||
|
"customerId": "CUST011",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "violet" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC22-001",
|
||||||
|
"title": "Sidste jul klip",
|
||||||
|
"start": "2025-12-22T09:00:00",
|
||||||
|
"end": "2025-12-22T10:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F12",
|
||||||
|
"resourceId": "EMP002",
|
||||||
|
"customerId": "CUST012",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "red" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC22-002",
|
||||||
|
"title": "Juleaften forberedelse",
|
||||||
|
"start": "2025-12-22T11:00:00",
|
||||||
|
"end": "2025-12-22T13:00:00",
|
||||||
|
"type": "customer",
|
||||||
|
"allDay": false,
|
||||||
|
"bookingId": "BOOK-F13",
|
||||||
|
"resourceId": "EMP003",
|
||||||
|
"customerId": "CUST013",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "green" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "EVT-DEC22-003",
|
||||||
|
"title": "Juleferie start",
|
||||||
|
"start": "2025-12-22T00:00:00",
|
||||||
|
"end": "2025-12-27T23:59:59",
|
||||||
|
"type": "vacation",
|
||||||
|
"allDay": true,
|
||||||
|
"resourceId": "EMP004",
|
||||||
|
"syncStatus": "synced",
|
||||||
|
"metadata": { "color": "light-blue" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,38 @@
|
||||||
"standard": {
|
"standard": {
|
||||||
"id": "standard",
|
"id": "standard",
|
||||||
"workDays": [1, 2, 3, 4, 5],
|
"workDays": [1, 2, 3, 4, 5],
|
||||||
"label": "Man-Fre"
|
"label": "Man-Fre",
|
||||||
|
"periodDays": 7
|
||||||
},
|
},
|
||||||
"compressed": {
|
"compressed": {
|
||||||
"id": "compressed",
|
"id": "compressed",
|
||||||
"workDays": [1, 2, 3],
|
"workDays": [1, 2, 3],
|
||||||
"label": "Man-Ons"
|
"label": "Man-Ons",
|
||||||
|
"periodDays": 7
|
||||||
},
|
},
|
||||||
"midweek": {
|
"midweek": {
|
||||||
"id": "midweek",
|
"id": "midweek",
|
||||||
"workDays": [4, 5],
|
"workDays": [4, 5],
|
||||||
"label": "Tors-Fre"
|
"label": "Tors-Fre",
|
||||||
|
"periodDays": 7
|
||||||
},
|
},
|
||||||
"weekend": {
|
"weekend": {
|
||||||
"id": "weekend",
|
"id": "weekend",
|
||||||
"workDays": [6, 7],
|
"workDays": [6, 7],
|
||||||
"label": "Weekend"
|
"label": "Weekend",
|
||||||
|
"periodDays": 7
|
||||||
},
|
},
|
||||||
"fullweek": {
|
"fullweek": {
|
||||||
"id": "fullweek",
|
"id": "fullweek",
|
||||||
"workDays": [1, 2, 3, 4, 5, 6, 7],
|
"workDays": [1, 2, 3, 4, 5, 6, 7],
|
||||||
"label": "Alle dage"
|
"label": "Alle dage",
|
||||||
|
"periodDays": 7
|
||||||
|
},
|
||||||
|
"day": {
|
||||||
|
"id": "day",
|
||||||
|
"workDays": [1],
|
||||||
|
"label": "Dag",
|
||||||
|
"periodDays": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultPreset": "standard",
|
"defaultPreset": "standard",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue