@open-rlb/ng-bootstrap 3.3.12 → 3.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,13 +3,13 @@ import { input, booleanAttribute, output, viewChild, ChangeDetectionStrategy, Co
3
3
  import * as i2$1 from '@angular/router';
4
4
  import { RouterLink, RouterLinkActive, RouterModule } from '@angular/router';
5
5
  import { Collapse, Carousel, Dropdown, Modal, Toast, Offcanvas, ScrollSpy, Popover, Tooltip } from 'bootstrap';
6
- import { NgTemplateOutlet, TitleCasePipe, NgClass, formatDate, JsonPipe, CommonModule } from '@angular/common';
6
+ import { NgTemplateOutlet, NgClass, formatDate, TitleCasePipe, JsonPipe, CommonModule } from '@angular/common';
7
7
  import { Subject, of, map, shareReplay, take, filter, switchMap, Subscription, debounceTime, distinctUntilChanged, Observable, lastValueFrom, takeUntil } from 'rxjs';
8
8
  import * as i2 from '@angular/cdk/layout';
9
9
  import * as i1 from '@angular/forms';
10
10
  import { FormsModule, NgControl, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
11
- import { DateTz } from '@open-rlb/date-tz';
12
11
  import { DateTz as DateTz$1 } from '@open-rlb/date-tz/date-tz';
12
+ import { DateTz } from '@open-rlb/date-tz';
13
13
  import { CdkDropListGroup, CdkDropList, CdkDrag, CdkDragPlaceholder, CdkDragPreview } from '@angular/cdk/drag-drop';
14
14
  import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
15
15
  import { TranslatePipe, TranslateModule } from '@ngx-translate/core';
@@ -2513,12 +2513,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2513
2513
  args: [{ selector: 'rlb-fab', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ButtonComponent], template: "<button rlb-button [color]=\"color()\" [disabled]=\"disabled()\" [outline]=\"outline()\"\n class=\"fab-button d-flex align-items-center justify-content-center\" [class]=\"[sizeClass(), positionClass()]\">\n <ng-content></ng-content>\n</button>", styles: [".fab-button{border-radius:50%;box-shadow:0 4px 12px #00000040;z-index:1050;transition:transform .2s ease,box-shadow .2s ease;padding:0}.fab-button:hover{transform:scale(1.08);box-shadow:0 6px 18px #00000059}.fab-button:active{transform:scale(.95)}:host{width:fit-content;display:block}.fab-xs{width:32px;height:32px;font-size:1rem}.fab-sm{width:44px;height:44px;font-size:1.2rem}.fab-md{width:56px;height:56px;font-size:1.4rem}.fab-lg{width:68px;height:68px;font-size:1.7rem}.fab-bottom-right{bottom:24px;right:24px}.fab-bottom-left{bottom:24px;left:24px}.fab-top-right{top:24px;right:24px}.fab-top-left{top:24px;left:24px}\n"] }]
2514
2514
  }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], outline: [{ type: i0.Input, args: [{ isSignal: true, alias: "outline", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
2515
2515
 
2516
- const DEFAULT_CALENDAR_LAYOUT = {
2517
- rowHeight: 110,
2518
- maxBodyHeight: 30,
2519
- minHeaderHeight: 3.5
2520
- };
2521
-
2522
2516
  function isSameDay(a, b) {
2523
2517
  return a.yearUTC === b.yearUTC &&
2524
2518
  a.monthUTC === b.monthUTC &&
@@ -2566,105 +2560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2566
2560
  args: [{ name: 'dtz' }]
2567
2561
  }] });
2568
2562
 
2569
- class MonthFormatterPipe {
2570
- constructor() {
2571
- this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
2572
- }
2573
- transform(value) {
2574
- if (!value)
2575
- return '';
2576
- const parts = value.trim().split(' ');
2577
- if (parts.length < 2)
2578
- return value;
2579
- const day = parts[0];
2580
- const monthIndex = parseInt(parts[1], 10) - 1;
2581
- if (isNaN(monthIndex) || monthIndex < 0 || monthIndex > 11) {
2582
- return value;
2583
- }
2584
- const month = this.months[monthIndex];
2585
- const rest = parts.slice(2).join(' ');
2586
- return `${day} ${month}${rest ? ' ' + rest : ''}`;
2587
- }
2588
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2589
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, isStandalone: true, name: "monthFormatter" }); }
2590
- }
2591
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, decorators: [{
2592
- type: Pipe,
2593
- args: [{ name: 'monthFormatter' }]
2594
- }] });
2595
-
2596
- class CalendarHeaderComponent {
2597
- constructor() {
2598
- this.view = input('month', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
2599
- this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
2600
- this.dateChange = output();
2601
- this.viewChange = output();
2602
- }
2603
- next() {
2604
- switch (this.view()) {
2605
- case 'week':
2606
- const nextWeek = addDays(this.currentDate(), 7);
2607
- this.dateChange.emit(new DateTz(nextWeek));
2608
- break;
2609
- case 'month':
2610
- const nextMonth = new DateTz(this.currentDate()).set(1, 'day').add(1, 'month');
2611
- this.dateChange.emit(new DateTz(nextMonth));
2612
- break;
2613
- case 'day':
2614
- const nextDay = addDays(this.currentDate(), 1);
2615
- this.dateChange.emit(new DateTz(nextDay));
2616
- break;
2617
- default:
2618
- break;
2619
- }
2620
- }
2621
- prev() {
2622
- switch (this.view()) {
2623
- case 'week':
2624
- const pastWeek = addDays(this.currentDate(), -7);
2625
- this.dateChange.emit(new DateTz(pastWeek));
2626
- break;
2627
- case 'month':
2628
- const pastMonth = new DateTz(this.currentDate()).set(1, 'day').add(-1, 'month');
2629
- this.dateChange.emit(new DateTz(pastMonth));
2630
- break;
2631
- case 'day':
2632
- const nextDay = addDays(this.currentDate(), -1);
2633
- this.dateChange.emit(new DateTz(nextDay));
2634
- break;
2635
- default:
2636
- break;
2637
- }
2638
- }
2639
- today() {
2640
- switch (this.view()) {
2641
- case 'week':
2642
- default:
2643
- const today = getToday();
2644
- this.dateChange.emit(today);
2645
- break;
2646
- }
2647
- }
2648
- setView(view) {
2649
- this.viewChange.emit(view);
2650
- }
2651
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2652
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: CalendarHeaderComponent, isStandalone: true, selector: "rlb-calendar-header", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateChange: "dateChange", viewChange: "viewChange" }, ngImport: i0, template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: DropdownComponent, selector: "rlb-dropdown", inputs: ["direction"] }, { kind: "directive", type: DropdownDirective, selector: "a[rlb-dropdown], button[rlb-dropdown], span[rlb-badge][rlb-dropdown]", inputs: ["offset", "auto-close"], outputs: ["status-changed"] }, { kind: "component", type: DropdownContainerComponent, selector: "ul[rlb-dropdown-menu], rlb-dropdown-container", inputs: ["placement", "placement-sm", "placement-md", "placement-lg", "placement-xl", "placement-xxl"] }, { kind: "component", type: DropdownMenuItemComponent, selector: "li[rlb-dropdown-item]", inputs: ["active", "disabled", "header", "divider", "link", "text-wrap"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: MonthFormatterPipe, name: "monthFormatter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2653
- }
2654
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarHeaderComponent, decorators: [{
2655
- type: Component,
2656
- args: [{ selector: 'rlb-calendar-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2657
- ButtonComponent,
2658
- DropdownComponent,
2659
- DropdownDirective,
2660
- DropdownContainerComponent,
2661
- DropdownMenuItemComponent,
2662
- TitleCasePipe,
2663
- DateTzPipe,
2664
- MonthFormatterPipe,
2665
- ], template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>" }]
2666
- }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], viewChange: [{ type: i0.Output, args: ["viewChange"] }] } });
2667
-
2668
2563
  class CalendarEventComponent {
2669
2564
  constructor() {
2670
2565
  this.event = input.required(...(ngDevMode ? [{ debugName: "event" }] : /* istanbul ignore next */ []));
@@ -2763,6 +2658,7 @@ class CalendarWeekGridComponent {
2763
2658
  this.view = input.required(...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
2764
2659
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
2765
2660
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
2661
+ this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
2766
2662
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
2767
2663
  this.eventClick = output({ alias: 'event-click' });
2768
2664
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -2878,6 +2774,22 @@ class CalendarWeekGridComponent {
2878
2774
  this.nowInterval = null;
2879
2775
  }
2880
2776
  }
2777
+ getIntervalsForDay(day) {
2778
+ const dayOfWeek = new DateTz$1(day).dayOfWeek; // 0=Sun, 1=Mon...
2779
+ return this.intervals().filter(interval => interval.dayWeek === dayOfWeek);
2780
+ }
2781
+ getIntervalTop(interval) {
2782
+ const seconds = interval.hourStart ?? 0;
2783
+ return (seconds / 3600) * this.layout().rowHeight;
2784
+ }
2785
+ getIntervalHeight(interval) {
2786
+ const start = interval.hourStart ?? 0;
2787
+ const stop = interval.hourStop ?? 86400;
2788
+ return ((stop - start) / 3600) * this.layout().rowHeight;
2789
+ }
2790
+ getIntervalColor(interval) {
2791
+ return `var(--bs-${interval.color || 'success'})`;
2792
+ }
2881
2793
  buildWeekGrid(currentDate) {
2882
2794
  const dayOfWeek = currentDate.dayOfWeek; // 0 = Sunday, 1 = Monday ...
2883
2795
  // Week init (monday)
@@ -3073,12 +2985,12 @@ class CalendarWeekGridComponent {
3073
2985
  });
3074
2986
  }
3075
2987
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarWeekGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3076
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarWeekGridComponent, isStandalone: true, selector: "rlb-calendar-week-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2988
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarWeekGridComponent, isStandalone: true, selector: "rlb-calendar-week-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container d-flex h-100 w-100 position-absolute top-0 start-0 z-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\">\n @for (interval of getIntervalsForDay(day); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.intervals-container .day-column{flex:1 1 0px;width:0;min-width:120px}.intervals-container .day-column:last-child{border-right:none!important}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3077
2989
  }
3078
2990
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarWeekGridComponent, decorators: [{
3079
2991
  type: Component,
3080
- args: [{ selector: 'rlb-calendar-week-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DateTzPipe, DayOfWeekPipe], template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
3081
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
2992
+ args: [{ selector: 'rlb-calendar-week-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DateTzPipe, DayOfWeekPipe], template: "<div class=\"calendar-wrapper d-flex flex-column\">\n\n <!-- HEADER WRAPPER -->\n <div #headerRow class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\"\n [style.padding-right.px]=\"scrollbarWidth()\">\n\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n\n <div class=\"days-header d-flex flex-grow-1\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-cell text-center p-2 border-end\" [class.text-primary]=\"isToday(day)\"\n [class.fw-bold]=\"isToday(day)\" [class.bg-primary]=\"isToday(day)\">\n <div class=\"small text-uppercase text-body-secondary\">{{ day | dayOfWeek: 'short' }}</div>\n <div class=\"h5 m-0\">{{ day | dtz:'DD' }}</div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n (scroll)=\"onBodyScroll($event)\" [style.max-height.rem]=\"layout().maxBodyHeight\">\n\n <div class=\"body-row d-flex position-relative\">\n\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container d-flex h-100 w-100 position-absolute top-0 start-0 z-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\">\n @for (interval of getIntervalsForDay(day); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n @for (day of days(); track day.timestamp) {\n <div class=\"day-column position-relative border-end h-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of getEventsForDay(day); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" [cdkDragDisabled]=\"event.isOverflowIndicator\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day)) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102;box-shadow:0 4px 6px -4px #0000001a}.header-row{width:fit-content;min-width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px;overflow:hidden}.day-cell:last-child{border-right:none!important}.calendar-body{scroll-behavior:auto}.body-row{width:fit-content;min-width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.day-column{border-color:var(--bs-border-color)!important;flex:1 1 0px;width:0;min-width:120px}.day-column:last-child{border-right:none!important}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.intervals-container .day-column{flex:1 1 0px;width:0;min-width:120px}.intervals-container .day-column:last-child{border-right:none!important}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
2993
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3082
2994
 
3083
2995
  const MAX_EVENTS_PER_CELL = 3;
3084
2996
  const DAYS_IN_GRID = 42; // 6 weeks * 7 days
@@ -3087,6 +2999,7 @@ class CalendarMonthGridComponent {
3087
2999
  this.view = input.required(...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
3088
3000
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3089
3001
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3002
+ this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3090
3003
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3091
3004
  this.eventClick = output({ alias: 'event-click' });
3092
3005
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3132,6 +3045,15 @@ class CalendarMonthGridComponent {
3132
3045
  isToday(date) {
3133
3046
  return isToday(date);
3134
3047
  }
3048
+ hasInterval(date) {
3049
+ const dayOfWeek = new DateTz(date).dayOfWeek;
3050
+ return this.intervals().some(interval => interval.dayWeek === dayOfWeek);
3051
+ }
3052
+ getIntervalColor(date) {
3053
+ const dayOfWeek = new DateTz(date).dayOfWeek;
3054
+ const interval = this.intervals().find(i => i.dayWeek === dayOfWeek);
3055
+ return interval ? `var(--bs-${interval.color || 'success'})` : '';
3056
+ }
3135
3057
  isCurrentMonth(date) {
3136
3058
  return date.month === this.currentDate().month;
3137
3059
  }
@@ -3333,18 +3255,19 @@ class CalendarMonthGridComponent {
3333
3255
  this.eventChange.emit(updatedEvent);
3334
3256
  }
3335
3257
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarMonthGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3336
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarMonthGridComponent, isStandalone: true, selector: "rlb-calendar-month-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\" cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarMonthGridComponent, isStandalone: true, selector: "rlb-calendar-month-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }, { propertyName: "headerRowRef", first: true, predicate: ["headerRow"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\"\n [class.has-interval]=\"hasInterval(slot.date)\"\n [style.--interval-color]=\"getIntervalColor(slot.date)\"\n cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.has-interval{background-image:linear-gradient(to right,color-mix(in srgb,var(--interval-color) 12%,transparent) 0%,transparent 100%);border-left:3px solid var(--interval-color)!important}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3337
3259
  }
3338
3260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarMonthGridComponent, decorators: [{
3339
3261
  type: Component,
3340
- args: [{ selector: 'rlb-calendar-month-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, CdkDragPreview, DateTzPipe, DayOfWeekPipe], template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\" cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"] }]
3341
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3262
+ args: [{ selector: 'rlb-calendar-month-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, CdkDragPreview, DateTzPipe, DayOfWeekPipe], template: "<div class=\"d-flex flex-column w-100 bg-body user-select-none month-view-root\">\n <!-- 1. Header Row (Fixed) -->\n <div #headerRow class=\"d-flex flex-shrink-0 border-bottom bg-body-tertiary overflow-hidden\"\n [style.min-height.rem]=\"layout().minHeaderHeight\" [style.padding-right.px]=\"scrollbarWidth()\">\n @for (day of weekDaysHeader(); track day) {\n <div class=\"flex-fill text-center py-2 border-end fw-bold text-secondary text-uppercase w-0 my-auto h6\">\n {{ day | dayOfWeek:'short' }}\n </div>\n }\n </div>\n\n <!-- SCROLL CONTAINER -->\n <div #scrollBody class=\"calendar-scroller flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\" (scroll)=\"onBodyScroll($event)\">\n\n <!-- 2. Grid Body (Scrollable) -->\n <div class=\"d-flex flex-column flex-grow-1 border-start min-height-0\">\n\n <div class=\"d-flex flex-column\" cdkDropListGroup>\n @for (week of weeks(); track week) {\n <div class=\"d-flex border-bottom min-h-row\" style=\"flex: 1 0 auto;\" [style.min-height.px]=\"layout().rowHeight\">\n @for (slot of week; track slot) {\n <div class=\"flex-fill border-end p-1 d-flex flex-column position-relative\" style=\"width: 0\"\n [class.bg-light]=\"!isCurrentMonth(slot.date)\"\n [class.has-interval]=\"hasInterval(slot.date)\"\n [style.--interval-color]=\"getIntervalColor(slot.date)\"\n cdkDropList [cdkDropListData]=\"slot.date\"\n (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n <!-- Date Number -->\n <div class=\"d-flex justify-content-center mb-1\">\n <span class=\"day-number d-flex align-items-center justify-content-center\"\n [class.today]=\"isToday(slot.date)\">\n {{ slot.date | dtz:'DD' }}\n </span>\n </div>\n <!-- Events Stack -->\n <div class=\"d-flex flex-column gap-1 w-100\">\n @for (event of slot.events; track trackByEvent($index, event)) {\n <!-- Spacer -->\n @if (event.isSpacer) {\n <div class=\"event-spacer\"></div>\n }\n <!-- Event -->\n @if (!event.isSpacer) {\n <rlb-calendar-event [event]=\"event\" class=\"w-100\" cdkDrag [cdkDragData]=\"event\"\n (event-click)=\"eventClick.emit($event)\" [view]=\"view()\">\n <!-- Drag Preview (Optional but nice) -->\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n <ng-template cdkDragPreview matchSize class=\"rlb-calendar-drag-preview\">\n <rlb-calendar-event [event]=\"event\" [view]=\"view()\" style=\"box-sizing: border-box;\">\n </rlb-calendar-event>\n </ng-template>\n </rlb-calendar-event>\n }\n }\n </div>\n <!-- Overflow (+N more) -->\n @if (slot.hasOverflow) {\n <div class=\"mt-1 small text-secondary text-center cursor-pointer p-1 rounded hover-bg\"\n (click)=\"$event.stopPropagation(); eventContainerClick.emit(slot.overflowEvents)\">\n +{{ slot.overflowCount }} more\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.min-height-0{min-height:0!important}.border-end:last-child{border-right:0!important}.day-number{width:24px;height:24px;border-radius:50%;font-size:.85rem;font-weight:500;transition:background-color .2s}.day-number.today{background-color:var(--bs-primary);color:#fff}.event-spacer{height:20px;width:100%;pointer-events:none}.hover-bg:hover{background-color:var(--bs-secondary-bg-subtle)}.cursor-pointer{cursor:pointer}.has-interval{background-image:linear-gradient(to right,color-mix(in srgb,var(--interval-color) 12%,transparent) 0%,transparent 100%);border-left:3px solid var(--interval-color)!important}.cdk-drag-preview{box-shadow:0 .5rem 1rem #0000004d;border-radius:var(--bs-border-radius-sm)}\n"] }]
3263
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }], headerRowRef: [{ type: i0.ViewChild, args: ['headerRow', { isSignal: true }] }] } });
3342
3264
 
3343
3265
  class CalendarDayGridComponent {
3344
3266
  constructor() {
3345
3267
  this.view = input.required(...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
3346
3268
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3347
3269
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3270
+ this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3348
3271
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3349
3272
  this.eventClick = output({ alias: 'event-click' });
3350
3273
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3440,6 +3363,22 @@ class CalendarDayGridComponent {
3440
3363
  clearInterval(this.nowInterval);
3441
3364
  }
3442
3365
  }
3366
+ getIntervalsForDay() {
3367
+ const dayOfWeek = new DateTz$1(this.day()).dayOfWeek;
3368
+ return this.intervals().filter(interval => interval.dayWeek === dayOfWeek);
3369
+ }
3370
+ getIntervalTop(interval) {
3371
+ const seconds = interval.hourStart ?? 0;
3372
+ return (seconds / 3600) * this.layout().rowHeight;
3373
+ }
3374
+ getIntervalHeight(interval) {
3375
+ const start = interval.hourStart ?? 0;
3376
+ const stop = interval.hourStop ?? 86400;
3377
+ return ((stop - start) / 3600) * this.layout().rowHeight;
3378
+ }
3379
+ getIntervalColor(interval) {
3380
+ return `var(--bs-${interval.color || 'success'})`;
3381
+ }
3443
3382
  buildDayGrid(currentDate) {
3444
3383
  this.day.set(new DateTz$1(currentDate.timestamp, 'UTC'));
3445
3384
  this.startNowTimer();
@@ -3577,18 +3516,19 @@ class CalendarDayGridComponent {
3577
3516
  });
3578
3517
  }
3579
3518
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarDayGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarDayGridComponent, isStandalone: true, selector: "rlb-calendar-day-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3519
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarDayGridComponent, isStandalone: true, selector: "rlb-calendar-day-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, viewQueries: [{ propertyName: "scrollBodyRef", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container position-absolute w-100 h-100 top-0 start-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (interval of getIntervalsForDay(); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.z-0{z-index:0}.z-1{z-index:1}\n"], dependencies: [{ kind: "directive", type: CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: CalendarEventComponent, selector: "rlb-calendar-event", inputs: ["event", "view"], outputs: ["event-click", "event-container-click"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DayOfWeekPipe, name: "dayOfWeek" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3581
3520
  }
3582
3521
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarDayGridComponent, decorators: [{
3583
3522
  type: Component,
3584
- args: [{ selector: 'rlb-calendar-day-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DayOfWeekPipe], template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
3585
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
3523
+ args: [{ selector: 'rlb-calendar-day-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkDropListGroup, CdkDropList, CalendarEventComponent, CdkDrag, CdkDragPlaceholder, DayOfWeekPipe], template: "@if (day()) {\n<div class=\"calendar-wrapper d-flex flex-column\">\n <!-- HEADER WRAPPER -->\n <!-- For day view, we just show the date at top? Or maybe just keep it simple with body since main header has date -->\n <!-- Mimicking structure of Week View but single column -->\n <div class=\"header-container overflow-hidden flex-shrink-0 border-bottom bg-body-tertiary\">\n <div class=\"header-row d-flex\" [style.min-height.rem]=\"layout().minHeaderHeight\">\n <div class=\"time-gutter border-end flex-shrink-0\"></div>\n <div class=\"day-cell p-2 flex-grow-1\" [class.text-primary]=\"isToday(day())\" [class.fw-bold]=\"isToday(day())\"\n [class.bg-primary]=\"isToday(day())\">\n <div class=\"small text-uppercase text-body-secondary h-100 d-flex align-items-center justify-content-center\">{{\n day() | dayOfWeek: 'long' }}</div>\n </div>\n </div>\n </div>\n <!-- BODY WRAPPER -->\n <div #scrollBody class=\"calendar-body flex-grow-1 overflow-auto bg-body position-relative\"\n [style.max-height.rem]=\"layout().maxBodyHeight\">\n <div class=\"body-row d-flex position-relative\">\n <!-- SIDEBAR (Sticky Left) -->\n <div class=\"time-sidebar sticky-start flex-shrink-0 border-end\">\n @for (time of timeSlots(); track time; let i = $index) {\n <div class=\"time-slot-label small text-body-secondary d-flex align-items-start justify-content-center\"\n [style.height.px]=\"layout().rowHeight\">\n @if (i !== 0) {\n <span style=\"transform: translateY(-50%)\">\n {{ time }}\n </span>\n }\n </div>\n }\n </div>\n <!-- GRID AND EVENTS -->\n <div class=\"grid-layer flex-grow-1 position-relative\">\n <!-- LAYER 1: Grid -->\n <div class=\"background-grid position-absolute w-100 h-100 top-0 start-0 z-0\">\n @for (time of timeSlots(); track time) {\n <div class=\"grid-row border-bottom\" [style.height.px]=\"layout().rowHeight\">\n </div>\n }\n </div>\n <!-- Layer 1.5: Intervals (background highlights) -->\n <div class=\"intervals-container position-absolute w-100 h-100 top-0 start-0\" style=\"z-index: 0; pointer-events: none;\">\n @for (interval of getIntervalsForDay(); track $index) {\n <div class=\"calendar-interval position-absolute w-100\"\n [style.top.px]=\"getIntervalTop(interval)\"\n [style.height.px]=\"getIntervalHeight(interval)\"\n [style.background-color]=\"getIntervalColor(interval)\">\n </div>\n }\n </div>\n\n <!-- Layer 2: Events -->\n <div class=\"events-container d-flex h-100 w-100 position-relative z-1\" cdkDropListGroup>\n <div class=\"day-column position-relative h-100 w-100\" cdkDropList [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"day()\" (cdkDropListDropped)=\"onEventDrop($event)\" (click)=\"eventClick.emit(undefined)\">\n @for (event of processedEvents(); track trackByEventId($index, event)) {\n <rlb-calendar-event [view]=\"view()\" [event]=\"event\" [style.top.px]=\"calculateEventTop(event)\"\n [style.height.px]=\"calculateEventHeight(event)\" [style.left.%]=\"event.left\" [style.width.%]=\"event.width\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\" cdkDrag\n [cdkDragData]=\"event\" class=\"position-absolute\">\n <div *cdkDragPlaceholder style=\"opacity: 0\"></div>\n </rlb-calendar-event>\n }\n @if (isToday(day())) {\n <div class=\"now-line\" [style.top.px]=\"getNowTop()\">\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n", styles: [":host{display:block;height:100%}.calendar-wrapper{background-color:var(--bs-body-bg);border:1px solid var(--bs-border-color);border-radius:var(--bs-border-radius);overflow:hidden;height:100%}.header-container{background-color:var(--bs-body-bg);z-index:102}.header-row{width:100%}.time-gutter{width:60px;border-color:var(--bs-border-color)!important}.day-cell{border-color:var(--bs-border-color)!important}.calendar-body{scroll-behavior:auto}.body-row{width:100%}.sticky-start{position:sticky;left:0;z-index:50;background-color:var(--bs-body-bg)}.time-sidebar{width:60px;border-color:var(--bs-border-color)!important}.grid-row{border-color:var(--bs-border-color)!important;box-sizing:border-box}.grid-row:after{content:\"\";position:absolute;width:100%;border-bottom:1px dotted currentColor;opacity:.15;top:50%;left:0;pointer-events:none}.now-line{position:absolute;left:0;right:0;height:2px;background-color:var(--bs-danger);z-index:10;pointer-events:none}.now-line:before{content:\"\";position:absolute;left:-5px;top:-4px;width:10px;height:10px;background-color:var(--bs-danger);border-radius:50%}.calendar-interval{opacity:.1;pointer-events:none;border-radius:0}.z-0{z-index:0}.z-1{z-index:1}\n"] }]
3524
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }], scrollBodyRef: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
3586
3525
 
3587
3526
  class CalendarGrid {
3588
3527
  constructor() {
3589
3528
  this.view = input.required(...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
3590
3529
  this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3591
3530
  this.events = input([], ...(ngDevMode ? [{ debugName: "events" }] : /* istanbul ignore next */ []));
3531
+ this.intervals = input([], ...(ngDevMode ? [{ debugName: "intervals" }] : /* istanbul ignore next */ []));
3592
3532
  this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
3593
3533
  this.eventClick = output({ alias: 'event-click' });
3594
3534
  this.eventContainerClick = output({ alias: 'event-container-click' });
@@ -3596,7 +3536,7 @@ class CalendarGrid {
3596
3536
  }
3597
3537
  ngOnDestroy() { }
3598
3538
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3599
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarGrid, isStandalone: true, selector: "rlb-calendar-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, ngImport: i0, template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n", styles: [""], dependencies: [{ kind: "component", type: CalendarWeekGridComponent, selector: "rlb-calendar-week-grid", inputs: ["view", "currentDate", "events", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarMonthGridComponent, selector: "rlb-calendar-month-grid", inputs: ["view", "currentDate", "events", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarDayGridComponent, selector: "rlb-calendar-day-grid", inputs: ["view", "currentDate", "events", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3539
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarGrid, isStandalone: true, selector: "rlb-calendar-grid", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { eventClick: "event-click", eventContainerClick: "event-container-click", eventChange: "event-change" }, ngImport: i0, template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n", styles: [""], dependencies: [{ kind: "component", type: CalendarWeekGridComponent, selector: "rlb-calendar-week-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarMonthGridComponent, selector: "rlb-calendar-month-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }, { kind: "component", type: CalendarDayGridComponent, selector: "rlb-calendar-day-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3600
3540
  }
3601
3541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarGrid, decorators: [{
3602
3542
  type: Component,
@@ -3604,8 +3544,113 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
3604
3544
  CalendarWeekGridComponent,
3605
3545
  CalendarMonthGridComponent,
3606
3546
  CalendarDayGridComponent,
3607
- ], template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n" }]
3608
- }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }] } });
3547
+ ], template: "@switch (view()) {\n@case ('week') {\n<rlb-calendar-week-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('month') {\n<rlb-calendar-month-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@case ('day') {\n<rlb-calendar-day-grid [view]=\"view()\" [currentDate]=\"currentDate()\" [events]=\"events()\" [intervals]=\"intervals()\" [layout]=\"layout()\"\n (event-click)=\"eventClick.emit($event)\" (event-container-click)=\"eventContainerClick.emit($event)\"\n (event-change)=\"eventChange.emit($event)\" />\n}\n@default {\nnot implemented yet\n}\n}\n" }]
3548
+ }], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], eventContainerClick: [{ type: i0.Output, args: ["event-container-click"] }], eventChange: [{ type: i0.Output, args: ["event-change"] }] } });
3549
+
3550
+ class MonthFormatterPipe {
3551
+ constructor() {
3552
+ this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
3553
+ }
3554
+ transform(value) {
3555
+ if (!value)
3556
+ return '';
3557
+ const parts = value.trim().split(' ');
3558
+ if (parts.length < 2)
3559
+ return value;
3560
+ const day = parts[0];
3561
+ const monthIndex = parseInt(parts[1], 10) - 1;
3562
+ if (isNaN(monthIndex) || monthIndex < 0 || monthIndex > 11) {
3563
+ return value;
3564
+ }
3565
+ const month = this.months[monthIndex];
3566
+ const rest = parts.slice(2).join(' ');
3567
+ return `${day} ${month}${rest ? ' ' + rest : ''}`;
3568
+ }
3569
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3570
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, isStandalone: true, name: "monthFormatter" }); }
3571
+ }
3572
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MonthFormatterPipe, decorators: [{
3573
+ type: Pipe,
3574
+ args: [{ name: 'monthFormatter' }]
3575
+ }] });
3576
+
3577
+ class CalendarHeaderComponent {
3578
+ constructor() {
3579
+ this.view = input('month', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
3580
+ this.currentDate = input.required(...(ngDevMode ? [{ debugName: "currentDate" }] : /* istanbul ignore next */ []));
3581
+ this.dateChange = output();
3582
+ this.viewChange = output();
3583
+ }
3584
+ next() {
3585
+ switch (this.view()) {
3586
+ case 'week':
3587
+ const nextWeek = addDays(this.currentDate(), 7);
3588
+ this.dateChange.emit(new DateTz(nextWeek));
3589
+ break;
3590
+ case 'month':
3591
+ const nextMonth = new DateTz(this.currentDate()).set(1, 'day').add(1, 'month');
3592
+ this.dateChange.emit(new DateTz(nextMonth));
3593
+ break;
3594
+ case 'day':
3595
+ const nextDay = addDays(this.currentDate(), 1);
3596
+ this.dateChange.emit(new DateTz(nextDay));
3597
+ break;
3598
+ default:
3599
+ break;
3600
+ }
3601
+ }
3602
+ prev() {
3603
+ switch (this.view()) {
3604
+ case 'week':
3605
+ const pastWeek = addDays(this.currentDate(), -7);
3606
+ this.dateChange.emit(new DateTz(pastWeek));
3607
+ break;
3608
+ case 'month':
3609
+ const pastMonth = new DateTz(this.currentDate()).set(1, 'day').add(-1, 'month');
3610
+ this.dateChange.emit(new DateTz(pastMonth));
3611
+ break;
3612
+ case 'day':
3613
+ const nextDay = addDays(this.currentDate(), -1);
3614
+ this.dateChange.emit(new DateTz(nextDay));
3615
+ break;
3616
+ default:
3617
+ break;
3618
+ }
3619
+ }
3620
+ today() {
3621
+ switch (this.view()) {
3622
+ case 'week':
3623
+ default:
3624
+ const today = getToday();
3625
+ this.dateChange.emit(today);
3626
+ break;
3627
+ }
3628
+ }
3629
+ setView(view) {
3630
+ this.viewChange.emit(view);
3631
+ }
3632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3633
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: CalendarHeaderComponent, isStandalone: true, selector: "rlb-calendar-header", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateChange: "dateChange", viewChange: "viewChange" }, ngImport: i0, template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[rlb-button], a[rlb-button]", inputs: ["color", "size", "disabled", "outline", "isLink"] }, { kind: "component", type: DropdownComponent, selector: "rlb-dropdown", inputs: ["direction"] }, { kind: "directive", type: DropdownDirective, selector: "a[rlb-dropdown], button[rlb-dropdown], span[rlb-badge][rlb-dropdown]", inputs: ["offset", "auto-close"], outputs: ["status-changed"] }, { kind: "component", type: DropdownContainerComponent, selector: "ul[rlb-dropdown-menu], rlb-dropdown-container", inputs: ["placement", "placement-sm", "placement-md", "placement-lg", "placement-xl", "placement-xxl"] }, { kind: "component", type: DropdownMenuItemComponent, selector: "li[rlb-dropdown-item]", inputs: ["active", "disabled", "header", "divider", "link", "text-wrap"] }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: DateTzPipe, name: "dtz" }, { kind: "pipe", type: MonthFormatterPipe, name: "monthFormatter" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3634
+ }
3635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarHeaderComponent, decorators: [{
3636
+ type: Component,
3637
+ args: [{ selector: 'rlb-calendar-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3638
+ ButtonComponent,
3639
+ DropdownComponent,
3640
+ DropdownDirective,
3641
+ DropdownContainerComponent,
3642
+ DropdownMenuItemComponent,
3643
+ TitleCasePipe,
3644
+ DateTzPipe,
3645
+ MonthFormatterPipe,
3646
+ ], template: "<div class=\"d-flex justify-content-between align-items-center mb-3\">\n\t<div class=\"d-flex gap-1\">\n\t\t<button rlb-button outline (click)=\"prev()\">\n\t\t\t<i class=\"bi bi-chevron-left\"></i>\n\t\t</button>\n\t\t<button rlb-button outline (click)=\"today()\">Today</button>\n\t\t<button rlb-button outline (click)=\"next()\">\n\t\t\t<i class=\"bi-chevron-right\"></i>\n\t\t</button>\n\t</div>\n\n\t<h5 class=\"mb-0\">{{ currentDate() | dtz:'DD MM yyyy' | monthFormatter }} {{ currentDate().timezone }}</h5>\n\n\t<rlb-dropdown>\n\t\t<button rlb-button outline rlb-dropdown>{{ view() | titlecase }}</button>\n\t\t<ul rlb-dropdown-menu [placement]=\"'right'\">\n\t\t\t<li rlb-dropdown-item (click)=\"setView('day')\">Day</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('week')\">Week</li>\n\t\t\t<li rlb-dropdown-item (click)=\"setView('month')\">Month</li>\n\t\t</ul>\n\t</rlb-dropdown>\n</div>" }]
3647
+ }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentDate", required: true }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], viewChange: [{ type: i0.Output, args: ["viewChange"] }] } });
3648
+
3649
+ const DEFAULT_CALENDAR_LAYOUT = {
3650
+ rowHeight: 110,
3651
+ maxBodyHeight: 30,
3652
+ minHeaderHeight: 3.5
3653
+ };
3609
3654
 
3610
3655
  class ToastRegistryOptions {
3611
3656
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ToastRegistryOptions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -3848,6 +3893,8 @@ class CalendarComponent {
3848
3893
  this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), alias: 'loading', transform: booleanAttribute });
3849
3894
  this.showToolbar = input(true, { ...(ngDevMode ? { debugName: "showToolbar" } : /* istanbul ignore next */ {}), alias: 'show-toolbar',
3850
3895
  transform: booleanAttribute });
3896
+ this.intervals = input([], { ...(ngDevMode ? { debugName: "intervals" } : /* istanbul ignore next */ {}), alias: 'intervals' });
3897
+ this.manageEvents = input(true, { ...(ngDevMode ? { debugName: "manageEvents" } : /* istanbul ignore next */ {}), alias: 'manage-events', transform: booleanAttribute });
3851
3898
  this.layout = input({}, { ...(ngDevMode ? { debugName: "layout" } : /* istanbul ignore next */ {}), alias: 'layout' });
3852
3899
  this.mergedLayout = computed(() => ({
3853
3900
  ...DEFAULT_CALENDAR_LAYOUT,
@@ -3856,6 +3903,7 @@ class CalendarComponent {
3856
3903
  this.dateChange = output({ alias: 'date-change' });
3857
3904
  this.viewChange = output({ alias: 'view-change' });
3858
3905
  this.eventClick = output({ alias: 'event-click' });
3906
+ this.containerEventClick = output({ alias: 'container-event-click' });
3859
3907
  }
3860
3908
  // DnD event
3861
3909
  onEventChange(eventToEdit) {
@@ -3875,6 +3923,11 @@ class CalendarComponent {
3875
3923
  }
3876
3924
  }
3877
3925
  onEventContainerClick(events) {
3926
+ if (events) {
3927
+ this.containerEventClick.emit(events);
3928
+ }
3929
+ if (!this.manageEvents())
3930
+ return;
3878
3931
  this.modals
3879
3932
  .openModal('rlb-calendar-overlow-events-container', {
3880
3933
  title: 'Overflow events',
@@ -3942,6 +3995,8 @@ class CalendarComponent {
3942
3995
  if (eventToEdit) {
3943
3996
  this.eventClick.emit(eventToEdit);
3944
3997
  }
3998
+ if (!this.manageEvents())
3999
+ return;
3945
4000
  this.openEditEventDialog(eventToEdit)
3946
4001
  .pipe(switchMap(modalResult => {
3947
4002
  const newEvent = modalResult.result;
@@ -4018,7 +4073,7 @@ class CalendarComponent {
4018
4073
  .pipe(take(1));
4019
4074
  }
4020
4075
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarComponent, deps: [{ token: ModalService }, { token: UniqueIdService }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Component }); }
4021
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarComponent, isStandalone: true, selector: "rlb-calendar", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "current-date", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "show-toolbar", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", events: "eventsChange", currentDate: "current-dateChange", dateChange: "date-change", viewChange: "view-change", eventClick: "event-click" }, ngImport: i0, template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CalendarHeaderComponent, selector: "rlb-calendar-header", inputs: ["view", "currentDate"], outputs: ["dateChange", "viewChange"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }, { kind: "component", type: CalendarGrid, selector: "rlb-calendar-grid", inputs: ["view", "currentDate", "events", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4076
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: CalendarComponent, isStandalone: true, selector: "rlb-calendar", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, currentDate: { classPropertyName: "currentDate", publicName: "current-date", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "show-toolbar", isSignal: true, isRequired: false, transformFunction: null }, intervals: { classPropertyName: "intervals", publicName: "intervals", isSignal: true, isRequired: false, transformFunction: null }, manageEvents: { classPropertyName: "manageEvents", publicName: "manage-events", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", events: "eventsChange", currentDate: "current-dateChange", dateChange: "date-change", viewChange: "view-change", eventClick: "event-click", containerEventClick: "container-event-click" }, ngImport: i0, template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: CalendarHeaderComponent, selector: "rlb-calendar-header", inputs: ["view", "currentDate"], outputs: ["dateChange", "viewChange"] }, { kind: "component", type: ProgressComponent, selector: "rlb-progress", inputs: ["max", "min", "value", "height", "animated", "striped", "infinite", "aria-label", "showValue", "color", "text-color"] }, { kind: "component", type: CalendarGrid, selector: "rlb-calendar-grid", inputs: ["view", "currentDate", "events", "intervals", "layout"], outputs: ["event-click", "event-container-click", "event-change"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4022
4077
  }
4023
4078
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CalendarComponent, decorators: [{
4024
4079
  type: Component,
@@ -4026,8 +4081,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4026
4081
  CalendarHeaderComponent,
4027
4082
  ProgressComponent,
4028
4083
  CalendarGrid,
4029
- ], template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n" }]
4030
- }], ctorParameters: () => [{ type: ModalService }, { type: UniqueIdService }, { type: ToastService }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }, { type: i0.Output, args: ["eventsChange"] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "current-date", required: false }] }, { type: i0.Output, args: ["current-dateChange"] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "show-toolbar", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], dateChange: [{ type: i0.Output, args: ["date-change"] }], viewChange: [{ type: i0.Output, args: ["view-change"] }], eventClick: [{ type: i0.Output, args: ["event-click"] }] } });
4084
+ ], template: "<div class=\"rlb-calendar\">\n\n @if (showToolbar()) {\n <rlb-calendar-header\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n (viewChange)=\"setView($event)\"\n (dateChange)=\"setDate($event)\"\n >\n </rlb-calendar-header>\n }\n\n @if (loading()) {\n <rlb-progress [infinite]=\"true\" [animated]=\"true\" [height]=\"3\" [showValue]=\"false\">\n </rlb-progress>\n } @else {\n <rlb-calendar-grid\n [events]=\"events()\"\n [intervals]=\"intervals()\"\n [view]=\"view()\"\n [currentDate]=\"currentDate()\"\n [layout]=\"mergedLayout()\"\n (event-click)=\"onEventClick($event)\"\n (event-container-click)=\"onEventContainerClick($event)\"\n (event-change)=\"onEventChange($event)\"\n >\n </rlb-calendar-grid>\n }\n</div>\n" }]
4085
+ }], ctorParameters: () => [{ type: ModalService }, { type: UniqueIdService }, { type: ToastService }], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }, { type: i0.Output, args: ["eventsChange"] }], currentDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "current-date", required: false }] }, { type: i0.Output, args: ["current-dateChange"] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "show-toolbar", required: false }] }], intervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "intervals", required: false }] }], manageEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "manage-events", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], dateChange: [{ type: i0.Output, args: ["date-change"] }], viewChange: [{ type: i0.Output, args: ["view-change"] }], eventClick: [{ type: i0.Output, args: ["event-click"] }], containerEventClick: [{ type: i0.Output, args: ["container-event-click"] }] } });
4031
4086
 
4032
4087
  const CALENDAR_COMPONENTS = [
4033
4088
  CalendarComponent,