@masterteam/timeline 0.0.9 → 0.0.11

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.
@@ -9,15 +9,14 @@ import { Tooltip } from 'primeng/tooltip';
9
9
  import { Icon } from '@masterteam/icons';
10
10
  import * as i1$1 from '@angular/forms';
11
11
  import { FormsModule } from '@angular/forms';
12
- import { Button } from '@masterteam/components/button';
13
12
  import { SelectField } from '@masterteam/components/select-field';
14
13
 
15
14
  class TimelineGanttTemplateDirective {
16
15
  templateRef = inject(TemplateRef);
17
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
18
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: TimelineGanttTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineGantt]", ngImport: i0 });
16
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
17
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: TimelineGanttTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineGantt]", ngImport: i0 });
19
18
  }
20
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttTemplateDirective, decorators: [{
19
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttTemplateDirective, decorators: [{
21
20
  type: Directive,
22
21
  args: [{
23
22
  selector: 'ng-template[mtTimelineGantt]',
@@ -28,10 +27,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
28
27
  class TimelineColumnTemplateDirective {
29
28
  key = '';
30
29
  templateRef = inject(TemplateRef);
31
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineColumnTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
32
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: TimelineColumnTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineColumn]", inputs: { key: ["mtTimelineColumn", "key"] }, ngImport: i0 });
30
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineColumnTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
31
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: TimelineColumnTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineColumn]", inputs: { key: ["mtTimelineColumn", "key"] }, ngImport: i0 });
33
32
  }
34
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineColumnTemplateDirective, decorators: [{
33
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineColumnTemplateDirective, decorators: [{
35
34
  type: Directive,
36
35
  args: [{
37
36
  selector: 'ng-template[mtTimelineColumn]',
@@ -44,10 +43,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
44
43
 
45
44
  class TimelinePopoverTemplateDirective {
46
45
  templateRef = inject(TemplateRef);
47
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelinePopoverTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
48
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: TimelinePopoverTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelinePopover]", ngImport: i0 });
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelinePopoverTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
47
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: TimelinePopoverTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelinePopover]", ngImport: i0 });
49
48
  }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelinePopoverTemplateDirective, decorators: [{
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelinePopoverTemplateDirective, decorators: [{
51
50
  type: Directive,
52
51
  args: [{
53
52
  selector: 'ng-template[mtTimelinePopover]',
@@ -57,10 +56,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
57
56
 
58
57
  class TimelineProgressTemplateDirective {
59
58
  templateRef = inject(TemplateRef);
60
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineProgressTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
61
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: TimelineProgressTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineProgress]", ngImport: i0 });
59
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineProgressTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
60
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: TimelineProgressTemplateDirective, isStandalone: true, selector: "ng-template[mtTimelineProgress]", ngImport: i0 });
62
61
  }
63
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineProgressTemplateDirective, decorators: [{
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineProgressTemplateDirective, decorators: [{
64
63
  type: Directive,
65
64
  args: [{
66
65
  selector: 'ng-template[mtTimelineProgress]',
@@ -77,13 +76,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
77
76
  */
78
77
  class TimelineDefaultPopover {
79
78
  // Resolved timeline row currently selected by user.
80
- item = input.required(...(ngDevMode ? [{ debugName: "item" }] : []));
79
+ item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
81
80
  // Requests parent popover host to close.
82
81
  requestClose = output();
83
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineDefaultPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
84
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: TimelineDefaultPopover, isStandalone: true, selector: "mt-timeline-default-popover", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { requestClose: "requestClose" }, ngImport: i0, template: "<!-- Default details view shown inside PrimeNG popover. -->\r\n<div class=\"w-[22.5rem]\" *transloco=\"let t; prefix: 'timeline'\">\r\n <div class=\"mb-3 flex items-center justify-between\">\r\n <h4 class=\"text-sm font-semibold\">{{ t(\"level-details\") }}</h4>\r\n <button\r\n type=\"button\"\r\n class=\"rounded border border-surface px-2 py-1 text-xs\"\r\n (click)=\"requestClose.emit()\"\r\n >\r\n {{ t(\"close\") }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid gap-2 text-sm sm:grid-cols-2\">\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"name\") }}:</span> {{ item().title }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"level\") }}:</span>\r\n {{ item().levelDescription }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"owner\") }}:</span> {{ item().owner }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"status\") }}:</span>\r\n <span [style.color]=\"item().statusColor\">{{ item().statusName }}</span>\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"progress\") }}:</span>\r\n {{ item().progressLabel }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"range\") }}:</span> {{ item().phase }}\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
82
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineDefaultPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
83
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: TimelineDefaultPopover, isStandalone: true, selector: "mt-timeline-default-popover", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { requestClose: "requestClose" }, ngImport: i0, template: "<!-- Default details view shown inside PrimeNG popover. -->\r\n<div class=\"w-[22.5rem]\" *transloco=\"let t; prefix: 'timeline'\">\r\n <div class=\"mb-3 flex items-center justify-between\">\r\n <h4 class=\"text-sm font-semibold\">{{ t(\"level-details\") }}</h4>\r\n <button\r\n type=\"button\"\r\n class=\"rounded border border-surface px-2 py-1 text-xs\"\r\n (click)=\"requestClose.emit()\"\r\n >\r\n {{ t(\"close\") }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid gap-2 text-sm sm:grid-cols-2\">\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"name\") }}:</span> {{ item().title }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"level\") }}:</span>\r\n {{ item().levelDescription }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"owner\") }}:</span> {{ item().owner }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"status\") }}:</span>\r\n <span [style.color]=\"item().statusColor\">{{ item().statusName }}</span>\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"progress\") }}:</span>\r\n {{ item().progressLabel }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"range\") }}:</span> {{ item().phase }}\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
85
84
  }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineDefaultPopover, decorators: [{
85
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineDefaultPopover, decorators: [{
87
86
  type: Component,
88
87
  args: [{ selector: 'mt-timeline-default-popover', standalone: true, imports: [TranslocoDirective], template: "<!-- Default details view shown inside PrimeNG popover. -->\r\n<div class=\"w-[22.5rem]\" *transloco=\"let t; prefix: 'timeline'\">\r\n <div class=\"mb-3 flex items-center justify-between\">\r\n <h4 class=\"text-sm font-semibold\">{{ t(\"level-details\") }}</h4>\r\n <button\r\n type=\"button\"\r\n class=\"rounded border border-surface px-2 py-1 text-xs\"\r\n (click)=\"requestClose.emit()\"\r\n >\r\n {{ t(\"close\") }}\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid gap-2 text-sm sm:grid-cols-2\">\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"name\") }}:</span> {{ item().title }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"level\") }}:</span>\r\n {{ item().levelDescription }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"owner\") }}:</span> {{ item().owner }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"status\") }}:</span>\r\n <span [style.color]=\"item().statusColor\">{{ item().statusName }}</span>\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"progress\") }}:</span>\r\n {{ item().progressLabel }}\r\n </div>\r\n <div>\r\n <span class=\"font-semibold\">{{ t(\"range\") }}:</span> {{ item().phase }}\r\n </div>\r\n </div>\r\n</div>\r\n" }]
89
88
  }], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], requestClose: [{ type: i0.Output, args: ["requestClose"] }] } });
@@ -110,14 +109,14 @@ class TimelineGanttHeader {
110
109
  'Nov',
111
110
  'Dec',
112
111
  ];
113
- timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : []));
114
- resolvedColumns = input([], ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : []));
115
- orderedGanttSegments = input([], ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : []));
116
- ganttCanvasWidth = input(0, ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : []));
117
- effectiveGanttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "effectiveGanttSegmentWidthPx" }] : []));
118
- zoomToFit = input(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : []));
119
- renderColumns = input(true, ...(ngDevMode ? [{ debugName: "renderColumns" }] : []));
120
- renderTimeline = input(true, ...(ngDevMode ? [{ debugName: "renderTimeline" }] : []));
112
+ timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : /* istanbul ignore next */ []));
113
+ resolvedColumns = input([], ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : /* istanbul ignore next */ []));
114
+ orderedGanttSegments = input([], ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : /* istanbul ignore next */ []));
115
+ ganttCanvasWidth = input(0, ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : /* istanbul ignore next */ []));
116
+ effectiveGanttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "effectiveGanttSegmentWidthPx" }] : /* istanbul ignore next */ []));
117
+ zoomToFit = input(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : /* istanbul ignore next */ []));
118
+ renderColumns = input(true, ...(ngDevMode ? [{ debugName: "renderColumns" }] : /* istanbul ignore next */ []));
119
+ renderTimeline = input(true, ...(ngDevMode ? [{ debugName: "renderTimeline" }] : /* istanbul ignore next */ []));
121
120
  // Converts monthly segments from "M N" to calendar abbreviations.
122
121
  resolveSegmentTitle(segment) {
123
122
  if (this.timelineMode() !== 'monthly') {
@@ -140,10 +139,10 @@ class TimelineGanttHeader {
140
139
  resolveSegmentTooltip(segment) {
141
140
  return this.resolveSegmentTitleAttr(segment);
142
141
  }
143
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
144
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TimelineGanttHeader, isStandalone: true, selector: "mt-timeline-gantt-header", inputs: { timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, resolvedColumns: { classPropertyName: "resolvedColumns", publicName: "resolvedColumns", isSignal: true, isRequired: false, transformFunction: null }, orderedGanttSegments: { classPropertyName: "orderedGanttSegments", publicName: "orderedGanttSegments", isSignal: true, isRequired: false, transformFunction: null }, ganttCanvasWidth: { classPropertyName: "ganttCanvasWidth", publicName: "ganttCanvasWidth", isSignal: true, isRequired: false, transformFunction: null }, effectiveGanttSegmentWidthPx: { classPropertyName: "effectiveGanttSegmentWidthPx", publicName: "effectiveGanttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, renderColumns: { classPropertyName: "renderColumns", publicName: "renderColumns", isSignal: true, isRequired: false, transformFunction: null }, renderTimeline: { classPropertyName: "renderTimeline", publicName: "renderTimeline", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block min-w-0" }, ngImport: i0, template: "<!-- Sticky metadata columns + timeline period header. -->\r\n<div class=\"flex border-b border-surface bg-surface-50\">\r\n <!-- Left sticky columns (title/status/custom columns). -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"shrink-0 border-e border-surface bg-surface-50 p-3 text-xs font-semibold uppercase text-surface-600\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.text-start]=\"column.position === 'start'\"\r\n [class.text-center]=\"column.position === 'center'\"\r\n [class.text-end]=\"column.position === 'end'\"\r\n >\r\n {{ column.header }}\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Time scale columns (month/quarter/half/year). -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"flex shrink-0 items-center bg-surface-50\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n >\r\n @for (column of orderedGanttSegments(); track $index) {\r\n <div\r\n class=\"shrink-0 overflow-hidden border-e border-surface px-2 py-3 text-center text-xs font-semibold uppercase text-surface-600 whitespace-nowrap\"\r\n [style.width.px]=\"effectiveGanttSegmentWidthPx()\"\r\n [pTooltip]=\"resolveSegmentTooltip(column)\"\r\n tooltipPosition=\"top\"\r\n [tooltipDisabled]=\"!zoomToFit()\"\r\n >\r\n {{ resolveSegmentTitle(column) }}\r\n @if (\r\n shouldRenderSegmentYear() &&\r\n column.year !== undefined &&\r\n column.year !== null\r\n ) {\r\n {{ column.year }}\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
142
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
143
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TimelineGanttHeader, isStandalone: true, selector: "mt-timeline-gantt-header", inputs: { timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, resolvedColumns: { classPropertyName: "resolvedColumns", publicName: "resolvedColumns", isSignal: true, isRequired: false, transformFunction: null }, orderedGanttSegments: { classPropertyName: "orderedGanttSegments", publicName: "orderedGanttSegments", isSignal: true, isRequired: false, transformFunction: null }, ganttCanvasWidth: { classPropertyName: "ganttCanvasWidth", publicName: "ganttCanvasWidth", isSignal: true, isRequired: false, transformFunction: null }, effectiveGanttSegmentWidthPx: { classPropertyName: "effectiveGanttSegmentWidthPx", publicName: "effectiveGanttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, renderColumns: { classPropertyName: "renderColumns", publicName: "renderColumns", isSignal: true, isRequired: false, transformFunction: null }, renderTimeline: { classPropertyName: "renderTimeline", publicName: "renderTimeline", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block min-w-0" }, ngImport: i0, template: "<!-- Sticky metadata columns + timeline period header. -->\r\n<div class=\"flex border-b border-surface bg-surface-50\">\r\n <!-- Left sticky columns (title/status/custom columns). -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"shrink-0 border-e border-surface bg-surface-50 p-3 text-xs font-semibold uppercase text-surface-600\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.text-start]=\"column.position === 'start'\"\r\n [class.text-center]=\"column.position === 'center'\"\r\n [class.text-end]=\"column.position === 'end'\"\r\n >\r\n {{ column.header }}\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Time scale columns (month/quarter/half/year). -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"flex shrink-0 items-center bg-surface-50\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n >\r\n @for (column of orderedGanttSegments(); track $index) {\r\n <div\r\n class=\"shrink-0 overflow-hidden border-e border-surface px-2 py-3 text-center text-xs font-semibold uppercase text-surface-600 whitespace-nowrap\"\r\n [style.width.px]=\"effectiveGanttSegmentWidthPx()\"\r\n [pTooltip]=\"resolveSegmentTooltip(column)\"\r\n tooltipPosition=\"top\"\r\n [tooltipDisabled]=\"!zoomToFit()\"\r\n >\r\n {{ resolveSegmentTitle(column) }}\r\n @if (\r\n shouldRenderSegmentYear() &&\r\n column.year !== undefined &&\r\n column.year !== null\r\n ) {\r\n {{ column.year }}\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
145
144
  }
146
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttHeader, decorators: [{
145
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttHeader, decorators: [{
147
146
  type: Component,
148
147
  args: [{ selector: 'mt-timeline-gantt-header', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, Tooltip], host: { class: 'block min-w-0' }, template: "<!-- Sticky metadata columns + timeline period header. -->\r\n<div class=\"flex border-b border-surface bg-surface-50\">\r\n <!-- Left sticky columns (title/status/custom columns). -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"shrink-0 border-e border-surface bg-surface-50 p-3 text-xs font-semibold uppercase text-surface-600\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.text-start]=\"column.position === 'start'\"\r\n [class.text-center]=\"column.position === 'center'\"\r\n [class.text-end]=\"column.position === 'end'\"\r\n >\r\n {{ column.header }}\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Time scale columns (month/quarter/half/year). -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"flex shrink-0 items-center bg-surface-50\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n >\r\n @for (column of orderedGanttSegments(); track $index) {\r\n <div\r\n class=\"shrink-0 overflow-hidden border-e border-surface px-2 py-3 text-center text-xs font-semibold uppercase text-surface-600 whitespace-nowrap\"\r\n [style.width.px]=\"effectiveGanttSegmentWidthPx()\"\r\n [pTooltip]=\"resolveSegmentTooltip(column)\"\r\n tooltipPosition=\"top\"\r\n [tooltipDisabled]=\"!zoomToFit()\"\r\n >\r\n {{ resolveSegmentTitle(column) }}\r\n @if (\r\n shouldRenderSegmentYear() &&\r\n column.year !== undefined &&\r\n column.year !== null\r\n ) {\r\n {{ column.year }}\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n" }]
149
148
  }], propDecorators: { timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }], resolvedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "resolvedColumns", required: false }] }], orderedGanttSegments: [{ type: i0.Input, args: [{ isSignal: true, alias: "orderedGanttSegments", required: false }] }], ganttCanvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttCanvasWidth", required: false }] }], effectiveGanttSegmentWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "effectiveGanttSegmentWidthPx", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }], renderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderColumns", required: false }] }], renderTimeline: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderTimeline", required: false }] }] } });
@@ -160,14 +159,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
160
159
  * already-resolved row geometry and style values.
161
160
  */
162
161
  class TimelineGanttRow {
163
- item = input.required(...(ngDevMode ? [{ debugName: "item" }] : []));
164
- resolvedColumns = input([], ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : []));
165
- ganttCanvasWidth = input(0, ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : []));
166
- laneInsetPx = input(12, ...(ngDevMode ? [{ debugName: "laneInsetPx" }] : []));
167
- renderColumns = input(true, ...(ngDevMode ? [{ debugName: "renderColumns" }] : []));
168
- renderTimeline = input(true, ...(ngDevMode ? [{ debugName: "renderTimeline" }] : []));
169
- columnTemplatesByKey = input(new Map(), ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : []));
170
- progressTemplateDirective = input(null, ...(ngDevMode ? [{ debugName: "progressTemplateDirective" }] : []));
162
+ item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
163
+ resolvedColumns = input([], ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : /* istanbul ignore next */ []));
164
+ ganttCanvasWidth = input(0, ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : /* istanbul ignore next */ []));
165
+ laneInsetPx = input(12, ...(ngDevMode ? [{ debugName: "laneInsetPx" }] : /* istanbul ignore next */ []));
166
+ renderColumns = input(true, ...(ngDevMode ? [{ debugName: "renderColumns" }] : /* istanbul ignore next */ []));
167
+ renderTimeline = input(true, ...(ngDevMode ? [{ debugName: "renderTimeline" }] : /* istanbul ignore next */ []));
168
+ columnTemplatesByKey = input(new Map(), ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : /* istanbul ignore next */ []));
169
+ progressTemplateDirective = input(null, ...(ngDevMode ? [{ debugName: "progressTemplateDirective" }] : /* istanbul ignore next */ []));
171
170
  toggleCollapse = output();
172
171
  progressClick = output();
173
172
  // Forwards collapse toggles to container component.
@@ -278,10 +277,10 @@ class TimelineGanttRow {
278
277
  return current[key];
279
278
  }, item);
280
279
  }
281
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
282
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TimelineGanttRow, isStandalone: true, selector: "mt-timeline-gantt-row", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, resolvedColumns: { classPropertyName: "resolvedColumns", publicName: "resolvedColumns", isSignal: true, isRequired: false, transformFunction: null }, ganttCanvasWidth: { classPropertyName: "ganttCanvasWidth", publicName: "ganttCanvasWidth", isSignal: true, isRequired: false, transformFunction: null }, laneInsetPx: { classPropertyName: "laneInsetPx", publicName: "laneInsetPx", isSignal: true, isRequired: false, transformFunction: null }, renderColumns: { classPropertyName: "renderColumns", publicName: "renderColumns", isSignal: true, isRequired: false, transformFunction: null }, renderTimeline: { classPropertyName: "renderTimeline", publicName: "renderTimeline", isSignal: true, isRequired: false, transformFunction: null }, columnTemplatesByKey: { classPropertyName: "columnTemplatesByKey", publicName: "columnTemplatesByKey", isSignal: true, isRequired: false, transformFunction: null }, progressTemplateDirective: { classPropertyName: "progressTemplateDirective", publicName: "progressTemplateDirective", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleCollapse: "toggleCollapse", progressClick: "progressClick" }, host: { classAttribute: "block min-w-0" }, ngImport: i0, template: "<!-- One gantt data row: sticky metadata cells + progress lane. -->\r\n<div class=\"relative flex\">\r\n <!-- Left sticky metadata cells. -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"flex h-16 shrink-0 items-center overflow-hidden border-e border-b border-surface bg-content p-3\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.justify-start]=\"column.position === 'start'\"\r\n [class.justify-center]=\"column.position === 'center'\"\r\n [class.justify-end]=\"column.position === 'end'\"\r\n >\r\n <!-- Per-column custom template, when provided by consumer. -->\r\n @if (resolveColumnTemplate(column); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"getColumnTemplateContext(column, item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in fallback renderers by column configuration. -->\r\n @if (column.isTreeColumn) {\r\n <div\r\n class=\"flex min-w-0 items-center gap-2\"\r\n [style.padding-inline-start.px]=\"item().levelDepth * 16\"\r\n >\r\n @if (item().hasChildren) {\r\n <mt-icon\r\n class=\"cursor-pointer\"\r\n (click)=\"onToggleCollapse(item())\"\r\n [icon]=\"collapseIcon(item())\"\r\n ></mt-icon>\r\n } @else {\r\n <span class=\"inline-block w-5\"></span>\r\n }\r\n <span class=\"truncate text-sm font-semibold\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n </div>\r\n } @else {\r\n <span class=\"truncate text-sm\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Right timeline canvas cell for progress track/fill. -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"relative z-0 h-16 shrink-0 overflow-hidden border-b border-surface py-4\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n [style.z-index]=\"1\"\r\n >\r\n <div class=\"h-8\"></div>\r\n <!-- Consumer custom progress template. -->\r\n @if (progressTemplateDirective(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template.templateRef\"\r\n [ngTemplateOutletContext]=\"getProgressTemplateContext(item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in progress renderer. -->\r\n <div\r\n class=\"absolute top-1/2 h-7 -translate-y-1/2 cursor-pointer overflow-hidden rounded-full\"\r\n [style.left.px]=\"\r\n isRtl() ? null : item().startOffsetPx + laneInsetPx()\r\n \"\r\n [style.right.px]=\"\r\n isRtl() ? item().startOffsetPx + laneInsetPx() : null\r\n \"\r\n [style.width.px]=\"item().trackWidthPx\"\r\n [style.background-color]=\"item().progressTrackColor\"\r\n [style.z-index]=\"1\"\r\n [attr.title]=\"item().progressLabel\"\r\n (click)=\"onProgressClick(item(), $event)\"\r\n >\r\n @if (item().progressFillWidthPx > 0) {\r\n <div\r\n class=\"h-full rounded-full\"\r\n [style.width.px]=\"item().progressFillWidthPx\"\r\n [style.min-width.px]=\"resolveProgressFillMinWidthPx(item())\"\r\n [style.background-color]=\"item().statusColor\"\r\n ></div>\r\n }\r\n\r\n @if (shouldRenderProgressLabel(item())) {\r\n <span\r\n class=\"pointer-events-none absolute top-1/2 z-[1] -translate-y-1/2 rounded-full bg-white px-2 py-0.5 text-[10px] font-semibold text-black shadow-sm\"\r\n [style.left.px]=\"isRtl() ? null : 8\"\r\n [style.right.px]=\"isRtl() ? 8 : null\"\r\n [attr.title]=\"item().progressLabel\"\r\n >\r\n {{ item().progressLabel }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
280
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
281
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TimelineGanttRow, isStandalone: true, selector: "mt-timeline-gantt-row", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, resolvedColumns: { classPropertyName: "resolvedColumns", publicName: "resolvedColumns", isSignal: true, isRequired: false, transformFunction: null }, ganttCanvasWidth: { classPropertyName: "ganttCanvasWidth", publicName: "ganttCanvasWidth", isSignal: true, isRequired: false, transformFunction: null }, laneInsetPx: { classPropertyName: "laneInsetPx", publicName: "laneInsetPx", isSignal: true, isRequired: false, transformFunction: null }, renderColumns: { classPropertyName: "renderColumns", publicName: "renderColumns", isSignal: true, isRequired: false, transformFunction: null }, renderTimeline: { classPropertyName: "renderTimeline", publicName: "renderTimeline", isSignal: true, isRequired: false, transformFunction: null }, columnTemplatesByKey: { classPropertyName: "columnTemplatesByKey", publicName: "columnTemplatesByKey", isSignal: true, isRequired: false, transformFunction: null }, progressTemplateDirective: { classPropertyName: "progressTemplateDirective", publicName: "progressTemplateDirective", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleCollapse: "toggleCollapse", progressClick: "progressClick" }, host: { classAttribute: "block min-w-0" }, ngImport: i0, template: "<!-- One gantt data row: sticky metadata cells + progress lane. -->\r\n<div class=\"relative flex\">\r\n <!-- Left sticky metadata cells. -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"flex h-16 shrink-0 items-center overflow-hidden border-e border-b border-surface bg-content p-3\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.justify-start]=\"column.position === 'start'\"\r\n [class.justify-center]=\"column.position === 'center'\"\r\n [class.justify-end]=\"column.position === 'end'\"\r\n >\r\n <!-- Per-column custom template, when provided by consumer. -->\r\n @if (resolveColumnTemplate(column); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"getColumnTemplateContext(column, item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in fallback renderers by column configuration. -->\r\n @if (column.isTreeColumn) {\r\n <div\r\n class=\"flex min-w-0 items-center gap-2\"\r\n [style.padding-inline-start.px]=\"item().levelDepth * 16\"\r\n >\r\n @if (item().hasChildren) {\r\n <mt-icon\r\n class=\"cursor-pointer\"\r\n (click)=\"onToggleCollapse(item())\"\r\n [icon]=\"collapseIcon(item())\"\r\n ></mt-icon>\r\n } @else {\r\n <span class=\"inline-block w-5\"></span>\r\n }\r\n <span class=\"truncate text-sm font-semibold\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n </div>\r\n } @else {\r\n <span class=\"truncate text-sm\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Right timeline canvas cell for progress track/fill. -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"relative z-0 h-16 shrink-0 overflow-hidden border-b border-surface py-4\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n [style.z-index]=\"1\"\r\n >\r\n <div class=\"h-8\"></div>\r\n <!-- Consumer custom progress template. -->\r\n @if (progressTemplateDirective(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template.templateRef\"\r\n [ngTemplateOutletContext]=\"getProgressTemplateContext(item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in progress renderer. -->\r\n <div\r\n class=\"absolute top-1/2 h-7 -translate-y-1/2 cursor-pointer overflow-hidden rounded-full\"\r\n [style.left.px]=\"\r\n isRtl() ? null : item().startOffsetPx + laneInsetPx()\r\n \"\r\n [style.right.px]=\"\r\n isRtl() ? item().startOffsetPx + laneInsetPx() : null\r\n \"\r\n [style.width.px]=\"item().trackWidthPx\"\r\n [style.background-color]=\"item().progressTrackColor\"\r\n [style.z-index]=\"1\"\r\n [attr.title]=\"item().progressLabel\"\r\n (click)=\"onProgressClick(item(), $event)\"\r\n >\r\n @if (item().progressFillWidthPx > 0) {\r\n <div\r\n class=\"h-full rounded-full\"\r\n [style.width.px]=\"item().progressFillWidthPx\"\r\n [style.min-width.px]=\"resolveProgressFillMinWidthPx(item())\"\r\n [style.background-color]=\"item().statusColor\"\r\n ></div>\r\n }\r\n\r\n @if (shouldRenderProgressLabel(item())) {\r\n <span\r\n class=\"pointer-events-none absolute top-1/2 z-[1] -translate-y-1/2 rounded-full bg-white px-2 py-0.5 text-[10px] font-semibold text-black shadow-sm\"\r\n [style.left.px]=\"isRtl() ? null : 8\"\r\n [style.right.px]=\"isRtl() ? 8 : null\"\r\n [attr.title]=\"item().progressLabel\"\r\n >\r\n {{ item().progressLabel }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
283
282
  }
284
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGanttRow, decorators: [{
283
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGanttRow, decorators: [{
285
284
  type: Component,
286
285
  args: [{ selector: 'mt-timeline-gantt-row', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, Icon, NgTemplateOutlet], host: { class: 'block min-w-0' }, template: "<!-- One gantt data row: sticky metadata cells + progress lane. -->\r\n<div class=\"relative flex\">\r\n <!-- Left sticky metadata cells. -->\r\n @if (renderColumns()) {\r\n @for (column of resolvedColumns(); track $index) {\r\n <div\r\n class=\"flex h-16 shrink-0 items-center overflow-hidden border-e border-b border-surface bg-content p-3\"\r\n [style.width.px]=\"column.widthPx\"\r\n [class.justify-start]=\"column.position === 'start'\"\r\n [class.justify-center]=\"column.position === 'center'\"\r\n [class.justify-end]=\"column.position === 'end'\"\r\n >\r\n <!-- Per-column custom template, when provided by consumer. -->\r\n @if (resolveColumnTemplate(column); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template\"\r\n [ngTemplateOutletContext]=\"getColumnTemplateContext(column, item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in fallback renderers by column configuration. -->\r\n @if (column.isTreeColumn) {\r\n <div\r\n class=\"flex min-w-0 items-center gap-2\"\r\n [style.padding-inline-start.px]=\"item().levelDepth * 16\"\r\n >\r\n @if (item().hasChildren) {\r\n <mt-icon\r\n class=\"cursor-pointer\"\r\n (click)=\"onToggleCollapse(item())\"\r\n [icon]=\"collapseIcon(item())\"\r\n ></mt-icon>\r\n } @else {\r\n <span class=\"inline-block w-5\"></span>\r\n }\r\n <span class=\"truncate text-sm font-semibold\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n </div>\r\n } @else {\r\n <span class=\"truncate text-sm\">\r\n {{ resolveColumnText(column, item()) }}\r\n </span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Right timeline canvas cell for progress track/fill. -->\r\n @if (renderTimeline()) {\r\n <div\r\n class=\"relative z-0 h-16 shrink-0 overflow-hidden border-b border-surface py-4\"\r\n [style.width.px]=\"ganttCanvasWidth()\"\r\n [style.z-index]=\"1\"\r\n >\r\n <div class=\"h-8\"></div>\r\n <!-- Consumer custom progress template. -->\r\n @if (progressTemplateDirective(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template.templateRef\"\r\n [ngTemplateOutletContext]=\"getProgressTemplateContext(item())\"\r\n ></ng-container>\r\n } @else {\r\n <!-- Built-in progress renderer. -->\r\n <div\r\n class=\"absolute top-1/2 h-7 -translate-y-1/2 cursor-pointer overflow-hidden rounded-full\"\r\n [style.left.px]=\"\r\n isRtl() ? null : item().startOffsetPx + laneInsetPx()\r\n \"\r\n [style.right.px]=\"\r\n isRtl() ? item().startOffsetPx + laneInsetPx() : null\r\n \"\r\n [style.width.px]=\"item().trackWidthPx\"\r\n [style.background-color]=\"item().progressTrackColor\"\r\n [style.z-index]=\"1\"\r\n [attr.title]=\"item().progressLabel\"\r\n (click)=\"onProgressClick(item(), $event)\"\r\n >\r\n @if (item().progressFillWidthPx > 0) {\r\n <div\r\n class=\"h-full rounded-full\"\r\n [style.width.px]=\"item().progressFillWidthPx\"\r\n [style.min-width.px]=\"resolveProgressFillMinWidthPx(item())\"\r\n [style.background-color]=\"item().statusColor\"\r\n ></div>\r\n }\r\n\r\n @if (shouldRenderProgressLabel(item())) {\r\n <span\r\n class=\"pointer-events-none absolute top-1/2 z-[1] -translate-y-1/2 rounded-full bg-white px-2 py-0.5 text-[10px] font-semibold text-black shadow-sm\"\r\n [style.left.px]=\"isRtl() ? null : 8\"\r\n [style.right.px]=\"isRtl() ? 8 : null\"\r\n [attr.title]=\"item().progressLabel\"\r\n >\r\n {{ item().progressLabel }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n" }]
287
286
  }], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], resolvedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "resolvedColumns", required: false }] }], ganttCanvasWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttCanvasWidth", required: false }] }], laneInsetPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "laneInsetPx", required: false }] }], renderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderColumns", required: false }] }], renderTimeline: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderTimeline", required: false }] }], columnTemplatesByKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnTemplatesByKey", required: false }] }], progressTemplateDirective: [{ type: i0.Input, args: [{ isSignal: true, alias: "progressTemplateDirective", required: false }] }], toggleCollapse: [{ type: i0.Output, args: ["toggleCollapse"] }], progressClick: [{ type: i0.Output, args: ["progressClick"] }] } });
@@ -308,41 +307,59 @@ class TimelineGantt {
308
307
  this.ganttScrollViewport = value;
309
308
  this.bindResizeObserver();
310
309
  }
310
+ columnsHeaderScrollViewport;
311
+ set columnsBodyScrollViewportRef(value) {
312
+ this.columnsBodyScrollViewport = value;
313
+ this.ganttBodyScrollTopPx.set(value?.nativeElement.scrollTop ?? 0);
314
+ }
315
+ timelineHeaderScrollViewport;
316
+ timelineBodyScrollViewport;
311
317
  ganttSplitContainer;
312
318
  ganttScrollViewport;
319
+ columnsBodyScrollViewport;
313
320
  resizeObserver;
314
321
  splitResizeObserver;
315
322
  // Width of the visible horizontal viewport used for adaptive segment sizing.
316
- ganttViewportWidth = signal(0, ...(ngDevMode ? [{ debugName: "ganttViewportWidth" }] : []));
317
- ganttContainerWidth = signal(0, ...(ngDevMode ? [{ debugName: "ganttContainerWidth" }] : []));
323
+ ganttViewportWidth = signal(0, ...(ngDevMode ? [{ debugName: "ganttViewportWidth" }] : /* istanbul ignore next */ []));
324
+ ganttContainerWidth = signal(0, ...(ngDevMode ? [{ debugName: "ganttContainerWidth" }] : /* istanbul ignore next */ []));
318
325
  splitterWidthPx = 10;
319
326
  timelineLaneInsetPx = 12;
320
327
  adaptiveSegmentMaxWidthPx = 320;
321
- columnsPaneUserWidthPx = signal(null, ...(ngDevMode ? [{ debugName: "columnsPaneUserWidthPx" }] : []));
322
- lastExpandedColumnsPaneWidthPx = signal(null, ...(ngDevMode ? [{ debugName: "lastExpandedColumnsPaneWidthPx" }] : []));
323
- isColumnsResizing = signal(false, ...(ngDevMode ? [{ debugName: "isColumnsResizing" }] : []));
324
- canResizeColumnsPane = computed(() => this.baseResolvedColumns().length > 0, ...(ngDevMode ? [{ debugName: "canResizeColumnsPane" }] : []));
328
+ ganttRowHeightPx = 64;
329
+ virtualScrollOverscanRows = 6;
330
+ columnsPaneUserWidthPx = signal(null, ...(ngDevMode ? [{ debugName: "columnsPaneUserWidthPx" }] : /* istanbul ignore next */ []));
331
+ lastExpandedColumnsPaneWidthPx = signal(null, ...(ngDevMode ? [{ debugName: "lastExpandedColumnsPaneWidthPx" }] : /* istanbul ignore next */ []));
332
+ ganttBodyScrollTopPx = signal(0, ...(ngDevMode ? [{ debugName: "ganttBodyScrollTopPx" }] : /* istanbul ignore next */ []));
333
+ isColumnsResizing = signal(false, ...(ngDevMode ? [{ debugName: "isColumnsResizing" }] : /* istanbul ignore next */ []));
334
+ canResizeColumnsPane = computed(() => this.baseResolvedColumns().length > 0, ...(ngDevMode ? [{ debugName: "canResizeColumnsPane" }] : /* istanbul ignore next */ []));
325
335
  resizeStartClientX = 0;
326
336
  resizeStartColumnsPaneWidthPx = 0;
327
- timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : []));
328
- columns = input(null, ...(ngDevMode ? [{ debugName: "columns" }] : []));
329
- ganttTitleColumnLabel = input('Portfolio Name', ...(ngDevMode ? [{ debugName: "ganttTitleColumnLabel" }] : []));
330
- ganttStatusColumnLabel = input('Status', ...(ngDevMode ? [{ debugName: "ganttStatusColumnLabel" }] : []));
331
- ganttInitiativeColumnWidthPx = input(288, ...(ngDevMode ? [{ debugName: "ganttInitiativeColumnWidthPx" }] : []));
332
- ganttStatusColumnWidthPx = input(160, ...(ngDevMode ? [{ debugName: "ganttStatusColumnWidthPx" }] : []));
333
- showGanttStatusColumn = input(false, ...(ngDevMode ? [{ debugName: "showGanttStatusColumn" }] : []));
334
- ganttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "ganttSegmentWidthPx" }] : []));
335
- defaultVisibleColumns = input(4, ...(ngDevMode ? [{ debugName: "defaultVisibleColumns" }] : []));
336
- columnsPaneMinWidthPx = input(0, ...(ngDevMode ? [{ debugName: "columnsPaneMinWidthPx" }] : []));
337
- columnsPaneMaxWidthPx = input(null, ...(ngDevMode ? [{ debugName: "columnsPaneMaxWidthPx" }] : []));
338
- zoomToFit = input(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : []));
339
- mappedGanttNodes = input([], ...(ngDevMode ? [{ debugName: "mappedGanttNodes" }] : []));
340
- orderedGanttSegments = input([], ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : []));
341
- collapsedGanttIds = input(new Set(), ...(ngDevMode ? [{ debugName: "collapsedGanttIds" }] : []));
342
- columnTemplatesByKey = input(new Map(), ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : []));
343
- progressTemplateDirective = input(null, ...(ngDevMode ? [{ debugName: "progressTemplateDirective" }] : []));
337
+ isSyncingColumnsScroll = false;
338
+ isSyncingTimelineScroll = false;
339
+ isSyncingVerticalScroll = false;
340
+ timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : /* istanbul ignore next */ []));
341
+ columns = input(null, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
342
+ ganttTitleColumnLabel = input('Portfolio Name', ...(ngDevMode ? [{ debugName: "ganttTitleColumnLabel" }] : /* istanbul ignore next */ []));
343
+ ganttStatusColumnLabel = input('Status', ...(ngDevMode ? [{ debugName: "ganttStatusColumnLabel" }] : /* istanbul ignore next */ []));
344
+ ganttInitiativeColumnWidthPx = input(288, ...(ngDevMode ? [{ debugName: "ganttInitiativeColumnWidthPx" }] : /* istanbul ignore next */ []));
345
+ ganttStatusColumnWidthPx = input(160, ...(ngDevMode ? [{ debugName: "ganttStatusColumnWidthPx" }] : /* istanbul ignore next */ []));
346
+ showGanttStatusColumn = input(false, ...(ngDevMode ? [{ debugName: "showGanttStatusColumn" }] : /* istanbul ignore next */ []));
347
+ ganttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "ganttSegmentWidthPx" }] : /* istanbul ignore next */ []));
348
+ defaultVisibleColumns = input(4, ...(ngDevMode ? [{ debugName: "defaultVisibleColumns" }] : /* istanbul ignore next */ []));
349
+ columnsPaneMinWidthPx = input(0, ...(ngDevMode ? [{ debugName: "columnsPaneMinWidthPx" }] : /* istanbul ignore next */ []));
350
+ columnsPaneMaxWidthPx = input(null, ...(ngDevMode ? [{ debugName: "columnsPaneMaxWidthPx" }] : /* istanbul ignore next */ []));
351
+ enableVirtualScroll = input(true, ...(ngDevMode ? [{ debugName: "enableVirtualScroll" }] : /* istanbul ignore next */ []));
352
+ virtualScrollThreshold = input(120, ...(ngDevMode ? [{ debugName: "virtualScrollThreshold" }] : /* istanbul ignore next */ []));
353
+ virtualScrollBodyHeightPx = input(640, ...(ngDevMode ? [{ debugName: "virtualScrollBodyHeightPx" }] : /* istanbul ignore next */ []));
354
+ zoomToFit = input(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : /* istanbul ignore next */ []));
355
+ mappedGanttNodes = input([], ...(ngDevMode ? [{ debugName: "mappedGanttNodes" }] : /* istanbul ignore next */ []));
356
+ orderedGanttSegments = input([], ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : /* istanbul ignore next */ []));
357
+ collapsedGanttIds = input(new Set(), ...(ngDevMode ? [{ debugName: "collapsedGanttIds" }] : /* istanbul ignore next */ []));
358
+ columnTemplatesByKey = input(new Map(), ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : /* istanbul ignore next */ []));
359
+ progressTemplateDirective = input(null, ...(ngDevMode ? [{ debugName: "progressTemplateDirective" }] : /* istanbul ignore next */ []));
344
360
  toggleCollapse = output();
345
361
  progressClick = output();
362
+ timelineViewportWidthChange = output();
346
363
  // Resolves the base columns contract before splitter-specific layout is applied.
347
364
  baseResolvedColumns = computed(() => {
348
365
  const providedColumns = this.columns();
@@ -360,8 +377,8 @@ class TimelineGantt {
360
377
  };
361
378
  return resolvedColumn;
362
379
  });
363
- }, ...(ngDevMode ? [{ debugName: "baseResolvedColumns" }] : []));
364
- baseColumnsWidthPx = computed(() => this.baseResolvedColumns().reduce((total, column) => total + column.baseWidthPx, 0), ...(ngDevMode ? [{ debugName: "baseColumnsWidthPx" }] : []));
380
+ }, ...(ngDevMode ? [{ debugName: "baseResolvedColumns" }] : /* istanbul ignore next */ []));
381
+ baseColumnsWidthPx = computed(() => this.baseResolvedColumns().reduce((total, column) => total + column.baseWidthPx, 0), ...(ngDevMode ? [{ debugName: "baseColumnsWidthPx" }] : /* istanbul ignore next */ []));
365
382
  preferredDefaultColumnsPaneWidthPx = computed(() => {
366
383
  const columns = this.baseResolvedColumns();
367
384
  if (!columns.length) {
@@ -378,7 +395,7 @@ class TimelineGantt {
378
395
  return columns
379
396
  .slice(0, Math.min(normalizedVisibleColumns, columns.length))
380
397
  .reduce((total, column) => total + column.baseWidthPx, 0);
381
- }, ...(ngDevMode ? [{ debugName: "preferredDefaultColumnsPaneWidthPx" }] : []));
398
+ }, ...(ngDevMode ? [{ debugName: "preferredDefaultColumnsPaneWidthPx" }] : /* istanbul ignore next */ []));
382
399
  // Column viewport and column content width are treated separately:
383
400
  // - splitter controls the viewport width
384
401
  // - columns keep base widths until there is extra space to relax into
@@ -390,13 +407,13 @@ class TimelineGantt {
390
407
  return columns;
391
408
  }
392
409
  return this.stretchColumnsToWidth(columns, paneWidthPx);
393
- }, ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : []));
394
- columnsContentWidthPx = computed(() => this.resolvedColumns().reduce((total, column) => total + column.widthPx, 0), ...(ngDevMode ? [{ debugName: "columnsContentWidthPx" }] : []));
410
+ }, ...(ngDevMode ? [{ debugName: "resolvedColumns" }] : /* istanbul ignore next */ []));
411
+ columnsContentWidthPx = computed(() => this.resolvedColumns().reduce((total, column) => total + column.widthPx, 0), ...(ngDevMode ? [{ debugName: "columnsContentWidthPx" }] : /* istanbul ignore next */ []));
395
412
  resolvedColumnsPaneWidthPx = computed(() => {
396
413
  const userWidth = this.columnsPaneUserWidthPx();
397
414
  const preferredWidth = userWidth ?? this.preferredDefaultColumnsPaneWidthPx();
398
415
  return this.clampColumnsPaneWidth(preferredWidth);
399
- }, ...(ngDevMode ? [{ debugName: "resolvedColumnsPaneWidthPx" }] : []));
416
+ }, ...(ngDevMode ? [{ debugName: "resolvedColumnsPaneWidthPx" }] : /* istanbul ignore next */ []));
400
417
  // Segment width expands to fill viewport when possible but never goes below base width.
401
418
  effectiveGanttSegmentWidthPx = computed(() => {
402
419
  const segmentCount = this.orderedGanttSegments().length;
@@ -413,14 +430,14 @@ class TimelineGantt {
413
430
  return Math.max(0, Math.min(candidateWidth, this.adaptiveSegmentMaxWidthPx));
414
431
  }
415
432
  return Math.max(baseWidth, Math.min(Math.floor(candidateWidth), this.adaptiveSegmentMaxWidthPx));
416
- }, ...(ngDevMode ? [{ debugName: "effectiveGanttSegmentWidthPx" }] : []));
433
+ }, ...(ngDevMode ? [{ debugName: "effectiveGanttSegmentWidthPx" }] : /* istanbul ignore next */ []));
417
434
  laneInsetPx = computed(() => {
418
435
  if (!this.zoomToFit()) {
419
436
  return this.timelineLaneInsetPx;
420
437
  }
421
438
  return Math.min(this.timelineLaneInsetPx, Math.max(0, this.effectiveGanttSegmentWidthPx() / 4));
422
- }, ...(ngDevMode ? [{ debugName: "laneInsetPx" }] : []));
423
- ganttCanvasWidth = computed(() => this.orderedGanttSegments().length * this.effectiveGanttSegmentWidthPx(), ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : []));
439
+ }, ...(ngDevMode ? [{ debugName: "laneInsetPx" }] : /* istanbul ignore next */ []));
440
+ ganttCanvasWidth = computed(() => this.orderedGanttSegments().length * this.effectiveGanttSegmentWidthPx(), ...(ngDevMode ? [{ debugName: "ganttCanvasWidth" }] : /* istanbul ignore next */ []));
424
441
  // Flattens the mapped hierarchy into rows using current collapse state.
425
442
  resolvedGanttItems = computed(() => {
426
443
  const segments = this.orderedGanttSegments();
@@ -432,7 +449,37 @@ class TimelineGantt {
432
449
  const out = [];
433
450
  this.flattenMapped(this.mappedGanttNodes(), 0, segments, firstSeq, lastSeq, this.collapsedGanttIds(), out);
434
451
  return out;
435
- }, ...(ngDevMode ? [{ debugName: "resolvedGanttItems" }] : []));
452
+ }, ...(ngDevMode ? [{ debugName: "resolvedGanttItems" }] : /* istanbul ignore next */ []));
453
+ resolvedVirtualScrollBodyHeightPx = computed(() => Math.max(this.ganttRowHeightPx, Math.floor(this.virtualScrollBodyHeightPx())), ...(ngDevMode ? [{ debugName: "resolvedVirtualScrollBodyHeightPx" }] : /* istanbul ignore next */ []));
454
+ isVirtualScrollActive = computed(() => {
455
+ const threshold = Math.max(0, Math.floor(this.virtualScrollThreshold()));
456
+ return (this.enableVirtualScroll() &&
457
+ this.resolvedGanttItems().length >= threshold &&
458
+ this.resolvedVirtualScrollBodyHeightPx() > 0);
459
+ }, ...(ngDevMode ? [{ debugName: "isVirtualScrollActive" }] : /* istanbul ignore next */ []));
460
+ virtualScrollWindow = computed(() => {
461
+ const totalItems = this.resolvedGanttItems().length;
462
+ if (!this.isVirtualScrollActive()) {
463
+ return { startIndex: 0, endIndex: totalItems };
464
+ }
465
+ const visibleRows = Math.max(1, Math.ceil(this.resolvedVirtualScrollBodyHeightPx() / this.ganttRowHeightPx));
466
+ const renderCount = visibleRows + this.virtualScrollOverscanRows * 2;
467
+ const maxStartIndex = Math.max(0, totalItems - renderCount);
468
+ const requestedStartIndex = Math.max(0, Math.floor(this.ganttBodyScrollTopPx() / this.ganttRowHeightPx) -
469
+ this.virtualScrollOverscanRows);
470
+ const startIndex = Math.min(requestedStartIndex, maxStartIndex);
471
+ const endIndex = Math.min(totalItems, startIndex + renderCount);
472
+ return { startIndex, endIndex };
473
+ }, ...(ngDevMode ? [{ debugName: "virtualScrollWindow" }] : /* istanbul ignore next */ []));
474
+ visibleResolvedGanttItems = computed(() => {
475
+ const { startIndex, endIndex } = this.virtualScrollWindow();
476
+ return this.resolvedGanttItems().slice(startIndex, endIndex);
477
+ }, ...(ngDevMode ? [{ debugName: "visibleResolvedGanttItems" }] : /* istanbul ignore next */ []));
478
+ virtualScrollTopSpacerHeightPx = computed(() => this.virtualScrollWindow().startIndex * this.ganttRowHeightPx, ...(ngDevMode ? [{ debugName: "virtualScrollTopSpacerHeightPx" }] : /* istanbul ignore next */ []));
479
+ virtualScrollBottomSpacerHeightPx = computed(() => {
480
+ const { endIndex } = this.virtualScrollWindow();
481
+ return Math.max(0, (this.resolvedGanttItems().length - endIndex) * this.ganttRowHeightPx);
482
+ }, ...(ngDevMode ? [{ debugName: "virtualScrollBottomSpacerHeightPx" }] : /* istanbul ignore next */ []));
436
483
  ngAfterViewInit() {
437
484
  this.bindResizeObserver();
438
485
  }
@@ -448,6 +495,24 @@ class TimelineGantt {
448
495
  onRowProgressClick(payload) {
449
496
  this.progressClick.emit(payload);
450
497
  }
498
+ onColumnsHeaderScroll(event) {
499
+ this.syncColumnsScroll(event.target, this.columnsBodyScrollViewport?.nativeElement);
500
+ }
501
+ onColumnsBodyScroll(event) {
502
+ const target = event.target;
503
+ this.ganttBodyScrollTopPx.set(target?.scrollTop ?? 0);
504
+ this.syncColumnsScroll(target, this.columnsHeaderScrollViewport?.nativeElement);
505
+ this.syncVerticalScroll(target, this.timelineBodyScrollViewport?.nativeElement);
506
+ }
507
+ onTimelineHeaderScroll(event) {
508
+ this.syncTimelineScroll(event.target, this.timelineBodyScrollViewport?.nativeElement);
509
+ }
510
+ onTimelineBodyScroll(event) {
511
+ const target = event.target;
512
+ this.ganttBodyScrollTopPx.set(target?.scrollTop ?? 0);
513
+ this.syncTimelineScroll(target, this.timelineHeaderScrollViewport?.nativeElement);
514
+ this.syncVerticalScroll(target, this.columnsBodyScrollViewport?.nativeElement);
515
+ }
451
516
  onSplitterPointerDown(event) {
452
517
  if (event.button !== 0 || !this.canResizeColumnsPane()) {
453
518
  return;
@@ -517,6 +582,7 @@ class TimelineGantt {
517
582
  return;
518
583
  }
519
584
  this.ganttViewportWidth.set(viewport.clientWidth);
585
+ this.timelineViewportWidthChange.emit(viewport.clientWidth);
520
586
  if (typeof ResizeObserver === 'undefined') {
521
587
  return;
522
588
  }
@@ -526,6 +592,7 @@ class TimelineGantt {
526
592
  this.ganttScrollViewport?.nativeElement.clientWidth ??
527
593
  0;
528
594
  this.ganttViewportWidth.set(width);
595
+ this.timelineViewportWidthChange.emit(width);
529
596
  });
530
597
  this.resizeObserver.observe(viewport);
531
598
  }
@@ -569,6 +636,45 @@ class TimelineGantt {
569
636
  window.removeEventListener('pointerup', this.onSplitterPointerUp);
570
637
  window.removeEventListener('pointercancel', this.onSplitterPointerUp);
571
638
  }
639
+ syncColumnsScroll(source, target) {
640
+ if (!source || !target || this.isSyncingColumnsScroll) {
641
+ return;
642
+ }
643
+ if (target.scrollLeft === source.scrollLeft) {
644
+ return;
645
+ }
646
+ this.isSyncingColumnsScroll = true;
647
+ target.scrollLeft = source.scrollLeft;
648
+ queueMicrotask(() => {
649
+ this.isSyncingColumnsScroll = false;
650
+ });
651
+ }
652
+ syncTimelineScroll(source, target) {
653
+ if (!source || !target || this.isSyncingTimelineScroll) {
654
+ return;
655
+ }
656
+ if (target.scrollLeft === source.scrollLeft) {
657
+ return;
658
+ }
659
+ this.isSyncingTimelineScroll = true;
660
+ target.scrollLeft = source.scrollLeft;
661
+ queueMicrotask(() => {
662
+ this.isSyncingTimelineScroll = false;
663
+ });
664
+ }
665
+ syncVerticalScroll(source, target) {
666
+ if (!source || !target || this.isSyncingVerticalScroll) {
667
+ return;
668
+ }
669
+ if (target.scrollTop === source.scrollTop) {
670
+ return;
671
+ }
672
+ this.isSyncingVerticalScroll = true;
673
+ target.scrollTop = source.scrollTop;
674
+ queueMicrotask(() => {
675
+ this.isSyncingVerticalScroll = false;
676
+ });
677
+ }
572
678
  applyColumnsPaneWidth(widthPx) {
573
679
  const clampedWidthPx = this.clampColumnsPaneWidth(widthPx);
574
680
  this.columnsPaneUserWidthPx.set(clampedWidthPx);
@@ -738,24 +844,36 @@ class TimelineGantt {
738
844
  'ltr';
739
845
  return dir.toLowerCase() === 'rtl';
740
846
  }
741
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGantt, deps: [], target: i0.ɵɵFactoryTarget.Component });
742
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TimelineGantt, isStandalone: true, selector: "mt-timeline-gantt", inputs: { timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ganttTitleColumnLabel: { classPropertyName: "ganttTitleColumnLabel", publicName: "ganttTitleColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnLabel: { classPropertyName: "ganttStatusColumnLabel", publicName: "ganttStatusColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttInitiativeColumnWidthPx: { classPropertyName: "ganttInitiativeColumnWidthPx", publicName: "ganttInitiativeColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnWidthPx: { classPropertyName: "ganttStatusColumnWidthPx", publicName: "ganttStatusColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, showGanttStatusColumn: { classPropertyName: "showGanttStatusColumn", publicName: "showGanttStatusColumn", isSignal: true, isRequired: false, transformFunction: null }, ganttSegmentWidthPx: { classPropertyName: "ganttSegmentWidthPx", publicName: "ganttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, defaultVisibleColumns: { classPropertyName: "defaultVisibleColumns", publicName: "defaultVisibleColumns", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMinWidthPx: { classPropertyName: "columnsPaneMinWidthPx", publicName: "columnsPaneMinWidthPx", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMaxWidthPx: { classPropertyName: "columnsPaneMaxWidthPx", publicName: "columnsPaneMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, mappedGanttNodes: { classPropertyName: "mappedGanttNodes", publicName: "mappedGanttNodes", isSignal: true, isRequired: false, transformFunction: null }, orderedGanttSegments: { classPropertyName: "orderedGanttSegments", publicName: "orderedGanttSegments", isSignal: true, isRequired: false, transformFunction: null }, collapsedGanttIds: { classPropertyName: "collapsedGanttIds", publicName: "collapsedGanttIds", isSignal: true, isRequired: false, transformFunction: null }, columnTemplatesByKey: { classPropertyName: "columnTemplatesByKey", publicName: "columnTemplatesByKey", isSignal: true, isRequired: false, transformFunction: null }, progressTemplateDirective: { classPropertyName: "progressTemplateDirective", publicName: "progressTemplateDirective", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleCollapse: "toggleCollapse", progressClick: "progressClick" }, viewQueries: [{ propertyName: "ganttSplitContainerRef", first: true, predicate: ["ganttSplitContainer"], descendants: true }, { propertyName: "ganttScrollViewportRef", first: true, predicate: ["ganttScrollViewport"], descendants: true }], ngImport: i0, template: "<!-- Gantt view shell: scroll viewport + sized timeline table. -->\r\n<div\r\n class=\"min-h-56 min-w-0 overflow-hidden py-2\"\r\n *transloco=\"let t; prefix: 'timeline'\"\r\n>\r\n <div\r\n class=\"flex min-w-0 border border-surface bg-content\"\r\n #ganttSplitContainer\r\n >\r\n <!-- Fixed metadata columns pane. -->\r\n <div\r\n class=\"shrink-0 overflow-hidden\"\r\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\r\n >\r\n <div class=\"mt-timeline-scroll h-full overflow-x-auto overflow-y-hidden\">\r\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\r\n <mt-timeline-gantt-header\r\n [timelineMode]=\"timelineMode()\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [ganttCanvasWidth]=\"0\"\r\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [renderTimeline]=\"false\"\r\n />\r\n\r\n <div>\r\n @for (item of resolvedGanttItems(); track $index) {\r\n <mt-timeline-gantt-row\r\n [item]=\"item\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [ganttCanvasWidth]=\"0\"\r\n [laneInsetPx]=\"laneInsetPx()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplateDirective()\"\r\n [renderTimeline]=\"false\"\r\n (toggleCollapse)=\"onToggleCollapse($event)\"\r\n (progressClick)=\"onRowProgressClick($event)\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (canResizeColumnsPane()) {\r\n <button\r\n type=\"button\"\r\n class=\"mt-timeline-splitter shrink-0\"\r\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\r\n (pointerdown)=\"onSplitterPointerDown($event)\"\r\n (dblclick)=\"onSplitterDoubleClick()\"\r\n (keydown)=\"onSplitterKeyDown($event)\"\r\n [attr.aria-label]=\"t('resize-columns')\"\r\n [title]=\"t('resize-columns-hint')\"\r\n ></button>\r\n }\r\n\r\n <!-- Scrollable timeline pane (horizontal scroll is limited to this area). -->\r\n <div\r\n class=\"mt-timeline-scroll min-w-0 flex-1 overflow-x-auto overflow-y-hidden\"\r\n #ganttScrollViewport\r\n >\r\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\r\n <mt-timeline-gantt-header\r\n [timelineMode]=\"timelineMode()\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\r\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [renderColumns]=\"false\"\r\n />\r\n\r\n <div>\r\n @for (item of resolvedGanttItems(); track $index) {\r\n <mt-timeline-gantt-row\r\n [item]=\"item\"\r\n [resolvedColumns]=\"[]\"\r\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\r\n [laneInsetPx]=\"laneInsetPx()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplateDirective()\"\r\n [renderColumns]=\"false\"\r\n (toggleCollapse)=\"onToggleCollapse($event)\"\r\n (progressClick)=\"onRowProgressClick($event)\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;min-width:0;max-width:100%}.mt-timeline-scroll{min-width:0;scrollbar-width:thin;scrollbar-color:var(--p-surface-400) transparent}.mt-timeline-scroll::-webkit-scrollbar{height:10px}.mt-timeline-scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-200) 30%,transparent);border-radius:9999px}.mt-timeline-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-surface-500) 60%,transparent);border-radius:9999px;border:2px solid transparent;background-clip:content-box}.mt-timeline-scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-surface-600) 65%,transparent);background-clip:content-box}.mt-timeline-splitter{position:relative;width:10px;min-width:10px;border:0;overflow:visible;background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%);cursor:col-resize;touch-action:none;transition:background .14s ease,opacity .14s ease,filter .14s ease}.mt-timeline-splitter:hover,.mt-timeline-splitter-active,.mt-timeline-splitter:focus-visible{background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%)}.mt-timeline-splitter:before{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:16px;height:42px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;border:1px solid color-mix(in srgb,var(--p-surface-300) 72%,transparent);background:var(--p-surface-0);box-shadow:0 6px 16px -14px color-mix(in srgb,var(--p-surface-400) 18%,transparent),0 2px 6px -4px color-mix(in srgb,black 16%,transparent);pointer-events:none;transition:opacity .14s ease,transform .14s ease,border-color .14s ease,box-shadow .14s ease}.mt-timeline-splitter:after{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:6px;height:16px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;background:linear-gradient(90deg,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 0,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 6px);pointer-events:none;transition:opacity .14s ease,transform .14s ease,background .14s ease}.mt-timeline-splitter:hover:before,.mt-timeline-splitter-active:before,.mt-timeline-splitter:focus-visible:before{border-color:color-mix(in srgb,var(--p-primary-color) 18%,var(--p-surface-200));box-shadow:0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}.mt-timeline-splitter:hover:after,.mt-timeline-splitter-active:after,.mt-timeline-splitter:focus-visible:after{background:linear-gradient(90deg,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 0,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 6px)}.mt-timeline-splitter:hover{filter:saturate(1.03)}.mt-timeline-splitter:focus-visible{outline:none}.mt-timeline-splitter:focus-visible:before{box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color) 14%,transparent),0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: TimelineGanttHeader, selector: "mt-timeline-gantt-header", inputs: ["timelineMode", "resolvedColumns", "orderedGanttSegments", "ganttCanvasWidth", "effectiveGanttSegmentWidthPx", "zoomToFit", "renderColumns", "renderTimeline"] }, { kind: "component", type: TimelineGanttRow, selector: "mt-timeline-gantt-row", inputs: ["item", "resolvedColumns", "ganttCanvasWidth", "laneInsetPx", "renderColumns", "renderTimeline", "columnTemplatesByKey", "progressTemplateDirective"], outputs: ["toggleCollapse", "progressClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
847
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGantt, deps: [], target: i0.ɵɵFactoryTarget.Component });
848
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TimelineGantt, isStandalone: true, selector: "mt-timeline-gantt", inputs: { timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ganttTitleColumnLabel: { classPropertyName: "ganttTitleColumnLabel", publicName: "ganttTitleColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnLabel: { classPropertyName: "ganttStatusColumnLabel", publicName: "ganttStatusColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttInitiativeColumnWidthPx: { classPropertyName: "ganttInitiativeColumnWidthPx", publicName: "ganttInitiativeColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnWidthPx: { classPropertyName: "ganttStatusColumnWidthPx", publicName: "ganttStatusColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, showGanttStatusColumn: { classPropertyName: "showGanttStatusColumn", publicName: "showGanttStatusColumn", isSignal: true, isRequired: false, transformFunction: null }, ganttSegmentWidthPx: { classPropertyName: "ganttSegmentWidthPx", publicName: "ganttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, defaultVisibleColumns: { classPropertyName: "defaultVisibleColumns", publicName: "defaultVisibleColumns", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMinWidthPx: { classPropertyName: "columnsPaneMinWidthPx", publicName: "columnsPaneMinWidthPx", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMaxWidthPx: { classPropertyName: "columnsPaneMaxWidthPx", publicName: "columnsPaneMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, enableVirtualScroll: { classPropertyName: "enableVirtualScroll", publicName: "enableVirtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollThreshold: { classPropertyName: "virtualScrollThreshold", publicName: "virtualScrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollBodyHeightPx: { classPropertyName: "virtualScrollBodyHeightPx", publicName: "virtualScrollBodyHeightPx", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, mappedGanttNodes: { classPropertyName: "mappedGanttNodes", publicName: "mappedGanttNodes", isSignal: true, isRequired: false, transformFunction: null }, orderedGanttSegments: { classPropertyName: "orderedGanttSegments", publicName: "orderedGanttSegments", isSignal: true, isRequired: false, transformFunction: null }, collapsedGanttIds: { classPropertyName: "collapsedGanttIds", publicName: "collapsedGanttIds", isSignal: true, isRequired: false, transformFunction: null }, columnTemplatesByKey: { classPropertyName: "columnTemplatesByKey", publicName: "columnTemplatesByKey", isSignal: true, isRequired: false, transformFunction: null }, progressTemplateDirective: { classPropertyName: "progressTemplateDirective", publicName: "progressTemplateDirective", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleCollapse: "toggleCollapse", progressClick: "progressClick", timelineViewportWidthChange: "timelineViewportWidthChange" }, viewQueries: [{ propertyName: "ganttSplitContainerRef", first: true, predicate: ["ganttSplitContainer"], descendants: true }, { propertyName: "ganttScrollViewportRef", first: true, predicate: ["ganttScrollViewport"], descendants: true }, { propertyName: "columnsHeaderScrollViewport", first: true, predicate: ["columnsHeaderScrollViewport"], descendants: true }, { propertyName: "columnsBodyScrollViewportRef", first: true, predicate: ["columnsBodyScrollViewport"], descendants: true }, { propertyName: "timelineHeaderScrollViewport", first: true, predicate: ["timelineHeaderScrollViewport"], descendants: true }, { propertyName: "timelineBodyScrollViewport", first: true, predicate: ["timelineBodyScrollViewport"], descendants: true }], ngImport: i0, template: "<!-- Gantt view shell: scroll viewport + sized timeline table. -->\n<div\n class=\"min-h-56 min-w-0 overflow-hidden py-2\"\n *transloco=\"let t; prefix: 'timeline'\"\n>\n @if (isVirtualScrollActive()) {\n <div\n class=\"flex min-w-0 border border-surface bg-content\"\n #ganttSplitContainer\n >\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n #columnsHeaderScrollViewport\n class=\"mt-timeline-scroll mt-timeline-scrollbar-hidden overflow-x-auto overflow-y-hidden\"\n (scroll)=\"onColumnsHeaderScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"0\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderTimeline]=\"false\"\n />\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <button\n type=\"button\"\n class=\"mt-timeline-splitter shrink-0\"\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\n (pointerdown)=\"onSplitterPointerDown($event)\"\n (dblclick)=\"onSplitterDoubleClick()\"\n (keydown)=\"onSplitterKeyDown($event)\"\n [attr.aria-label]=\"t('resize-columns')\"\n [title]=\"t('resize-columns-hint')\"\n ></button>\n }\n\n <div class=\"min-w-0 flex-1 overflow-hidden\">\n <div\n #timelineHeaderScrollViewport\n class=\"mt-timeline-scroll mt-timeline-scrollbar-hidden overflow-x-auto overflow-y-hidden\"\n (scroll)=\"onTimelineHeaderScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderColumns]=\"false\"\n />\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex min-w-0 border border-t-0 border-surface bg-content\">\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n #columnsBodyScrollViewport\n class=\"mt-timeline-scroll overflow-auto\"\n [style.height.px]=\"resolvedVirtualScrollBodyHeightPx()\"\n (scroll)=\"onColumnsBodyScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n @if (virtualScrollTopSpacerHeightPx() > 0) {\n <div [style.height.px]=\"virtualScrollTopSpacerHeightPx()\"></div>\n }\n\n @for (item of visibleResolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"resolvedColumns()\"\n [ganttCanvasWidth]=\"0\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderTimeline]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n\n @if (virtualScrollBottomSpacerHeightPx() > 0) {\n <div\n [style.height.px]=\"virtualScrollBottomSpacerHeightPx()\"\n ></div>\n }\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <div\n class=\"w-[10px] min-w-[10px] shrink-0 border-e border-surface bg-surface-50\"\n aria-hidden=\"true\"\n ></div>\n }\n\n <div class=\"min-w-0 flex-1 overflow-hidden\">\n <div\n #timelineBodyScrollViewport\n #ganttScrollViewport\n class=\"mt-timeline-scroll overflow-auto\"\n [style.height.px]=\"resolvedVirtualScrollBodyHeightPx()\"\n (scroll)=\"onTimelineBodyScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n @if (virtualScrollTopSpacerHeightPx() > 0) {\n <div [style.height.px]=\"virtualScrollTopSpacerHeightPx()\"></div>\n }\n\n @for (item of visibleResolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"[]\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderColumns]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n\n @if (virtualScrollBottomSpacerHeightPx() > 0) {\n <div\n [style.height.px]=\"virtualScrollBottomSpacerHeightPx()\"\n ></div>\n }\n </div>\n </div>\n </div>\n </div>\n } @else {\n <div\n class=\"flex min-w-0 border border-surface bg-content\"\n #ganttSplitContainer\n >\n <!-- Fixed metadata columns pane. -->\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n class=\"mt-timeline-scroll h-full overflow-x-auto overflow-y-hidden\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"0\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderTimeline]=\"false\"\n />\n\n <div>\n @for (item of resolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"resolvedColumns()\"\n [ganttCanvasWidth]=\"0\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderTimeline]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n </div>\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <button\n type=\"button\"\n class=\"mt-timeline-splitter shrink-0\"\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\n (pointerdown)=\"onSplitterPointerDown($event)\"\n (dblclick)=\"onSplitterDoubleClick()\"\n (keydown)=\"onSplitterKeyDown($event)\"\n [attr.aria-label]=\"t('resize-columns')\"\n [title]=\"t('resize-columns-hint')\"\n ></button>\n }\n\n <!-- Scrollable timeline pane (horizontal scroll is limited to this area). -->\n <div\n class=\"mt-timeline-scroll min-w-0 flex-1 overflow-x-auto overflow-y-hidden\"\n #ganttScrollViewport\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderColumns]=\"false\"\n />\n\n <div>\n @for (item of resolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"[]\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderColumns]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;min-width:0;max-width:100%}.mt-timeline-scroll{min-width:0;scrollbar-width:thin;scrollbar-color:var(--p-surface-400) transparent}.mt-timeline-scroll::-webkit-scrollbar{height:10px}.mt-timeline-scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-200) 30%,transparent);border-radius:9999px}.mt-timeline-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-surface-500) 60%,transparent);border-radius:9999px;border:2px solid transparent;background-clip:content-box}.mt-timeline-scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-surface-600) 65%,transparent);background-clip:content-box}.mt-timeline-scrollbar-hidden{scrollbar-width:none}.mt-timeline-scrollbar-hidden::-webkit-scrollbar{width:0;height:0}.mt-timeline-splitter{position:relative;width:10px;min-width:10px;border:0;overflow:visible;background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%);cursor:col-resize;touch-action:none;transition:background .14s ease,opacity .14s ease,filter .14s ease}.mt-timeline-splitter:hover,.mt-timeline-splitter-active,.mt-timeline-splitter:focus-visible{background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%)}.mt-timeline-splitter:before{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:16px;height:42px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;border:1px solid color-mix(in srgb,var(--p-surface-300) 72%,transparent);background:var(--p-surface-0);box-shadow:0 6px 16px -14px color-mix(in srgb,var(--p-surface-400) 18%,transparent),0 2px 6px -4px color-mix(in srgb,black 16%,transparent);pointer-events:none;transition:opacity .14s ease,transform .14s ease,border-color .14s ease,box-shadow .14s ease}.mt-timeline-splitter:after{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:6px;height:16px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;background:linear-gradient(90deg,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 0,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 6px);pointer-events:none;transition:opacity .14s ease,transform .14s ease,background .14s ease}.mt-timeline-splitter:hover:before,.mt-timeline-splitter-active:before,.mt-timeline-splitter:focus-visible:before{border-color:color-mix(in srgb,var(--p-primary-color) 18%,var(--p-surface-200));box-shadow:0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}.mt-timeline-splitter:hover:after,.mt-timeline-splitter-active:after,.mt-timeline-splitter:focus-visible:after{background:linear-gradient(90deg,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 0,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 6px)}.mt-timeline-splitter:hover{filter:saturate(1.03)}.mt-timeline-splitter:focus-visible{outline:none}.mt-timeline-splitter:focus-visible:before{box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color) 14%,transparent),0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: TimelineGanttHeader, selector: "mt-timeline-gantt-header", inputs: ["timelineMode", "resolvedColumns", "orderedGanttSegments", "ganttCanvasWidth", "effectiveGanttSegmentWidthPx", "zoomToFit", "renderColumns", "renderTimeline"] }, { kind: "component", type: TimelineGanttRow, selector: "mt-timeline-gantt-row", inputs: ["item", "resolvedColumns", "ganttCanvasWidth", "laneInsetPx", "renderColumns", "renderTimeline", "columnTemplatesByKey", "progressTemplateDirective"], outputs: ["toggleCollapse", "progressClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
743
849
  }
744
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineGantt, decorators: [{
850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineGantt, decorators: [{
745
851
  type: Component,
746
852
  args: [{ selector: 'mt-timeline-gantt', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
747
853
  CommonModule,
748
854
  TranslocoDirective,
749
855
  TimelineGanttHeader,
750
856
  TimelineGanttRow,
751
- ], template: "<!-- Gantt view shell: scroll viewport + sized timeline table. -->\r\n<div\r\n class=\"min-h-56 min-w-0 overflow-hidden py-2\"\r\n *transloco=\"let t; prefix: 'timeline'\"\r\n>\r\n <div\r\n class=\"flex min-w-0 border border-surface bg-content\"\r\n #ganttSplitContainer\r\n >\r\n <!-- Fixed metadata columns pane. -->\r\n <div\r\n class=\"shrink-0 overflow-hidden\"\r\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\r\n >\r\n <div class=\"mt-timeline-scroll h-full overflow-x-auto overflow-y-hidden\">\r\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\r\n <mt-timeline-gantt-header\r\n [timelineMode]=\"timelineMode()\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [ganttCanvasWidth]=\"0\"\r\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [renderTimeline]=\"false\"\r\n />\r\n\r\n <div>\r\n @for (item of resolvedGanttItems(); track $index) {\r\n <mt-timeline-gantt-row\r\n [item]=\"item\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [ganttCanvasWidth]=\"0\"\r\n [laneInsetPx]=\"laneInsetPx()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplateDirective()\"\r\n [renderTimeline]=\"false\"\r\n (toggleCollapse)=\"onToggleCollapse($event)\"\r\n (progressClick)=\"onRowProgressClick($event)\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (canResizeColumnsPane()) {\r\n <button\r\n type=\"button\"\r\n class=\"mt-timeline-splitter shrink-0\"\r\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\r\n (pointerdown)=\"onSplitterPointerDown($event)\"\r\n (dblclick)=\"onSplitterDoubleClick()\"\r\n (keydown)=\"onSplitterKeyDown($event)\"\r\n [attr.aria-label]=\"t('resize-columns')\"\r\n [title]=\"t('resize-columns-hint')\"\r\n ></button>\r\n }\r\n\r\n <!-- Scrollable timeline pane (horizontal scroll is limited to this area). -->\r\n <div\r\n class=\"mt-timeline-scroll min-w-0 flex-1 overflow-x-auto overflow-y-hidden\"\r\n #ganttScrollViewport\r\n >\r\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\r\n <mt-timeline-gantt-header\r\n [timelineMode]=\"timelineMode()\"\r\n [resolvedColumns]=\"resolvedColumns()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\r\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [renderColumns]=\"false\"\r\n />\r\n\r\n <div>\r\n @for (item of resolvedGanttItems(); track $index) {\r\n <mt-timeline-gantt-row\r\n [item]=\"item\"\r\n [resolvedColumns]=\"[]\"\r\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\r\n [laneInsetPx]=\"laneInsetPx()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplateDirective()\"\r\n [renderColumns]=\"false\"\r\n (toggleCollapse)=\"onToggleCollapse($event)\"\r\n (progressClick)=\"onRowProgressClick($event)\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;min-width:0;max-width:100%}.mt-timeline-scroll{min-width:0;scrollbar-width:thin;scrollbar-color:var(--p-surface-400) transparent}.mt-timeline-scroll::-webkit-scrollbar{height:10px}.mt-timeline-scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-200) 30%,transparent);border-radius:9999px}.mt-timeline-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-surface-500) 60%,transparent);border-radius:9999px;border:2px solid transparent;background-clip:content-box}.mt-timeline-scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-surface-600) 65%,transparent);background-clip:content-box}.mt-timeline-splitter{position:relative;width:10px;min-width:10px;border:0;overflow:visible;background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%);cursor:col-resize;touch-action:none;transition:background .14s ease,opacity .14s ease,filter .14s ease}.mt-timeline-splitter:hover,.mt-timeline-splitter-active,.mt-timeline-splitter:focus-visible{background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%)}.mt-timeline-splitter:before{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:16px;height:42px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;border:1px solid color-mix(in srgb,var(--p-surface-300) 72%,transparent);background:var(--p-surface-0);box-shadow:0 6px 16px -14px color-mix(in srgb,var(--p-surface-400) 18%,transparent),0 2px 6px -4px color-mix(in srgb,black 16%,transparent);pointer-events:none;transition:opacity .14s ease,transform .14s ease,border-color .14s ease,box-shadow .14s ease}.mt-timeline-splitter:after{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:6px;height:16px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;background:linear-gradient(90deg,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 0,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 6px);pointer-events:none;transition:opacity .14s ease,transform .14s ease,background .14s ease}.mt-timeline-splitter:hover:before,.mt-timeline-splitter-active:before,.mt-timeline-splitter:focus-visible:before{border-color:color-mix(in srgb,var(--p-primary-color) 18%,var(--p-surface-200));box-shadow:0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}.mt-timeline-splitter:hover:after,.mt-timeline-splitter-active:after,.mt-timeline-splitter:focus-visible:after{background:linear-gradient(90deg,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 0,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 6px)}.mt-timeline-splitter:hover{filter:saturate(1.03)}.mt-timeline-splitter:focus-visible{outline:none}.mt-timeline-splitter:focus-visible:before{box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color) 14%,transparent),0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}\n"] }]
857
+ ], template: "<!-- Gantt view shell: scroll viewport + sized timeline table. -->\n<div\n class=\"min-h-56 min-w-0 overflow-hidden py-2\"\n *transloco=\"let t; prefix: 'timeline'\"\n>\n @if (isVirtualScrollActive()) {\n <div\n class=\"flex min-w-0 border border-surface bg-content\"\n #ganttSplitContainer\n >\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n #columnsHeaderScrollViewport\n class=\"mt-timeline-scroll mt-timeline-scrollbar-hidden overflow-x-auto overflow-y-hidden\"\n (scroll)=\"onColumnsHeaderScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"0\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderTimeline]=\"false\"\n />\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <button\n type=\"button\"\n class=\"mt-timeline-splitter shrink-0\"\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\n (pointerdown)=\"onSplitterPointerDown($event)\"\n (dblclick)=\"onSplitterDoubleClick()\"\n (keydown)=\"onSplitterKeyDown($event)\"\n [attr.aria-label]=\"t('resize-columns')\"\n [title]=\"t('resize-columns-hint')\"\n ></button>\n }\n\n <div class=\"min-w-0 flex-1 overflow-hidden\">\n <div\n #timelineHeaderScrollViewport\n class=\"mt-timeline-scroll mt-timeline-scrollbar-hidden overflow-x-auto overflow-y-hidden\"\n (scroll)=\"onTimelineHeaderScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderColumns]=\"false\"\n />\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"flex min-w-0 border border-t-0 border-surface bg-content\">\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n #columnsBodyScrollViewport\n class=\"mt-timeline-scroll overflow-auto\"\n [style.height.px]=\"resolvedVirtualScrollBodyHeightPx()\"\n (scroll)=\"onColumnsBodyScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n @if (virtualScrollTopSpacerHeightPx() > 0) {\n <div [style.height.px]=\"virtualScrollTopSpacerHeightPx()\"></div>\n }\n\n @for (item of visibleResolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"resolvedColumns()\"\n [ganttCanvasWidth]=\"0\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderTimeline]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n\n @if (virtualScrollBottomSpacerHeightPx() > 0) {\n <div\n [style.height.px]=\"virtualScrollBottomSpacerHeightPx()\"\n ></div>\n }\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <div\n class=\"w-[10px] min-w-[10px] shrink-0 border-e border-surface bg-surface-50\"\n aria-hidden=\"true\"\n ></div>\n }\n\n <div class=\"min-w-0 flex-1 overflow-hidden\">\n <div\n #timelineBodyScrollViewport\n #ganttScrollViewport\n class=\"mt-timeline-scroll overflow-auto\"\n [style.height.px]=\"resolvedVirtualScrollBodyHeightPx()\"\n (scroll)=\"onTimelineBodyScroll($event)\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n @if (virtualScrollTopSpacerHeightPx() > 0) {\n <div [style.height.px]=\"virtualScrollTopSpacerHeightPx()\"></div>\n }\n\n @for (item of visibleResolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"[]\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderColumns]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n\n @if (virtualScrollBottomSpacerHeightPx() > 0) {\n <div\n [style.height.px]=\"virtualScrollBottomSpacerHeightPx()\"\n ></div>\n }\n </div>\n </div>\n </div>\n </div>\n } @else {\n <div\n class=\"flex min-w-0 border border-surface bg-content\"\n #ganttSplitContainer\n >\n <!-- Fixed metadata columns pane. -->\n <div\n class=\"shrink-0 overflow-hidden\"\n [style.width.px]=\"resolvedColumnsPaneWidthPx()\"\n >\n <div\n class=\"mt-timeline-scroll h-full overflow-x-auto overflow-y-hidden\"\n >\n <div class=\"min-w-full\" [style.width.px]=\"columnsContentWidthPx()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"0\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderTimeline]=\"false\"\n />\n\n <div>\n @for (item of resolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"resolvedColumns()\"\n [ganttCanvasWidth]=\"0\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderTimeline]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n </div>\n </div>\n </div>\n </div>\n\n @if (canResizeColumnsPane()) {\n <button\n type=\"button\"\n class=\"mt-timeline-splitter shrink-0\"\n [class.mt-timeline-splitter-active]=\"isColumnsResizing()\"\n (pointerdown)=\"onSplitterPointerDown($event)\"\n (dblclick)=\"onSplitterDoubleClick()\"\n (keydown)=\"onSplitterKeyDown($event)\"\n [attr.aria-label]=\"t('resize-columns')\"\n [title]=\"t('resize-columns-hint')\"\n ></button>\n }\n\n <!-- Scrollable timeline pane (horizontal scroll is limited to this area). -->\n <div\n class=\"mt-timeline-scroll min-w-0 flex-1 overflow-x-auto overflow-y-hidden\"\n #ganttScrollViewport\n >\n <div class=\"min-w-full\" [style.width.px]=\"ganttCanvasWidth()\">\n <mt-timeline-gantt-header\n [timelineMode]=\"timelineMode()\"\n [resolvedColumns]=\"resolvedColumns()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [effectiveGanttSegmentWidthPx]=\"effectiveGanttSegmentWidthPx()\"\n [zoomToFit]=\"zoomToFit()\"\n [renderColumns]=\"false\"\n />\n\n <div>\n @for (item of resolvedGanttItems(); track item.id) {\n <mt-timeline-gantt-row\n [item]=\"item\"\n [resolvedColumns]=\"[]\"\n [ganttCanvasWidth]=\"ganttCanvasWidth()\"\n [laneInsetPx]=\"laneInsetPx()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplateDirective()\"\n [renderColumns]=\"false\"\n (toggleCollapse)=\"onToggleCollapse($event)\"\n (progressClick)=\"onRowProgressClick($event)\"\n />\n }\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;min-width:0;max-width:100%}.mt-timeline-scroll{min-width:0;scrollbar-width:thin;scrollbar-color:var(--p-surface-400) transparent}.mt-timeline-scroll::-webkit-scrollbar{height:10px}.mt-timeline-scroll::-webkit-scrollbar-track{background:color-mix(in srgb,var(--p-surface-200) 30%,transparent);border-radius:9999px}.mt-timeline-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--p-surface-500) 60%,transparent);border-radius:9999px;border:2px solid transparent;background-clip:content-box}.mt-timeline-scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--p-surface-600) 65%,transparent);background-clip:content-box}.mt-timeline-scrollbar-hidden{scrollbar-width:none}.mt-timeline-scrollbar-hidden::-webkit-scrollbar{width:0;height:0}.mt-timeline-splitter{position:relative;width:10px;min-width:10px;border:0;overflow:visible;background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-surface-300) 45%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% - 1px),color-mix(in srgb,var(--p-surface-500) 72%,white 28%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%);cursor:col-resize;touch-action:none;transition:background .14s ease,opacity .14s ease,filter .14s ease}.mt-timeline-splitter:hover,.mt-timeline-splitter-active,.mt-timeline-splitter:focus-visible{background:linear-gradient(90deg,transparent 0,transparent calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% - 4px),color-mix(in srgb,var(--p-primary-color) 22%,transparent) calc(50% + 4px),transparent calc(50% + 4px),transparent 100%),linear-gradient(90deg,transparent 0,transparent calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% - 1px),color-mix(in srgb,var(--p-primary-color) 88%,white 12%) calc(50% + 1px),transparent calc(50% + 1px),transparent 100%)}.mt-timeline-splitter:before{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:16px;height:42px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;border:1px solid color-mix(in srgb,var(--p-surface-300) 72%,transparent);background:var(--p-surface-0);box-shadow:0 6px 16px -14px color-mix(in srgb,var(--p-surface-400) 18%,transparent),0 2px 6px -4px color-mix(in srgb,black 16%,transparent);pointer-events:none;transition:opacity .14s ease,transform .14s ease,border-color .14s ease,box-shadow .14s ease}.mt-timeline-splitter:after{content:\"\";position:absolute;top:50%;inset-inline-start:50%;width:6px;height:16px;transform:translate(-50%,-50%) scale(1);opacity:1;border-radius:9999px;background:linear-gradient(90deg,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 0,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 4px,color-mix(in srgb,var(--p-surface-500) 78%,white 22%) 6px);pointer-events:none;transition:opacity .14s ease,transform .14s ease,background .14s ease}.mt-timeline-splitter:hover:before,.mt-timeline-splitter-active:before,.mt-timeline-splitter:focus-visible:before{border-color:color-mix(in srgb,var(--p-primary-color) 18%,var(--p-surface-200));box-shadow:0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}.mt-timeline-splitter:hover:after,.mt-timeline-splitter-active:after,.mt-timeline-splitter:focus-visible:after{background:linear-gradient(90deg,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 0,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 2px,transparent 2px,transparent 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 4px,color-mix(in srgb,var(--p-primary-color) 88%,white 12%) 6px)}.mt-timeline-splitter:hover{filter:saturate(1.03)}.mt-timeline-splitter:focus-visible{outline:none}.mt-timeline-splitter:focus-visible:before{box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color) 14%,transparent),0 8px 18px -16px color-mix(in srgb,var(--p-primary-color) 28%,transparent),0 4px 8px -6px color-mix(in srgb,black 18%,transparent)}\n"] }]
752
858
  }], propDecorators: { ganttSplitContainerRef: [{
753
859
  type: ViewChild,
754
860
  args: ['ganttSplitContainer']
755
861
  }], ganttScrollViewportRef: [{
756
862
  type: ViewChild,
757
863
  args: ['ganttScrollViewport']
758
- }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], ganttTitleColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttTitleColumnLabel", required: false }] }], ganttStatusColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnLabel", required: false }] }], ganttInitiativeColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttInitiativeColumnWidthPx", required: false }] }], ganttStatusColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnWidthPx", required: false }] }], showGanttStatusColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttStatusColumn", required: false }] }], ganttSegmentWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttSegmentWidthPx", required: false }] }], defaultVisibleColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultVisibleColumns", required: false }] }], columnsPaneMinWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMinWidthPx", required: false }] }], columnsPaneMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMaxWidthPx", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }], mappedGanttNodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "mappedGanttNodes", required: false }] }], orderedGanttSegments: [{ type: i0.Input, args: [{ isSignal: true, alias: "orderedGanttSegments", required: false }] }], collapsedGanttIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedGanttIds", required: false }] }], columnTemplatesByKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnTemplatesByKey", required: false }] }], progressTemplateDirective: [{ type: i0.Input, args: [{ isSignal: true, alias: "progressTemplateDirective", required: false }] }], toggleCollapse: [{ type: i0.Output, args: ["toggleCollapse"] }], progressClick: [{ type: i0.Output, args: ["progressClick"] }] } });
864
+ }], columnsHeaderScrollViewport: [{
865
+ type: ViewChild,
866
+ args: ['columnsHeaderScrollViewport']
867
+ }], columnsBodyScrollViewportRef: [{
868
+ type: ViewChild,
869
+ args: ['columnsBodyScrollViewport']
870
+ }], timelineHeaderScrollViewport: [{
871
+ type: ViewChild,
872
+ args: ['timelineHeaderScrollViewport']
873
+ }], timelineBodyScrollViewport: [{
874
+ type: ViewChild,
875
+ args: ['timelineBodyScrollViewport']
876
+ }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], ganttTitleColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttTitleColumnLabel", required: false }] }], ganttStatusColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnLabel", required: false }] }], ganttInitiativeColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttInitiativeColumnWidthPx", required: false }] }], ganttStatusColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnWidthPx", required: false }] }], showGanttStatusColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttStatusColumn", required: false }] }], ganttSegmentWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttSegmentWidthPx", required: false }] }], defaultVisibleColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultVisibleColumns", required: false }] }], columnsPaneMinWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMinWidthPx", required: false }] }], columnsPaneMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMaxWidthPx", required: false }] }], enableVirtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableVirtualScroll", required: false }] }], virtualScrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScrollThreshold", required: false }] }], virtualScrollBodyHeightPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScrollBodyHeightPx", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }], mappedGanttNodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "mappedGanttNodes", required: false }] }], orderedGanttSegments: [{ type: i0.Input, args: [{ isSignal: true, alias: "orderedGanttSegments", required: false }] }], collapsedGanttIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedGanttIds", required: false }] }], columnTemplatesByKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnTemplatesByKey", required: false }] }], progressTemplateDirective: [{ type: i0.Input, args: [{ isSignal: true, alias: "progressTemplateDirective", required: false }] }], toggleCollapse: [{ type: i0.Output, args: ["toggleCollapse"] }], progressClick: [{ type: i0.Output, args: ["progressClick"] }], timelineViewportWidthChange: [{ type: i0.Output, args: ["timelineViewportWidthChange"] }] } });
759
877
 
760
878
  /**
761
879
  * Shared timeline header.
@@ -769,34 +887,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
769
887
  * the parent timeline container.
770
888
  */
771
889
  class TimelineHeader {
772
- title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
773
- timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : []));
774
- timelineModeOptions = input([], ...(ngDevMode ? [{ debugName: "timelineModeOptions" }] : []));
775
- showZoomToFitControl = input(false, ...(ngDevMode ? [{ debugName: "showZoomToFitControl" }] : []));
776
- zoomToFit = input(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : []));
777
- zoomToFitDisabled = input(false, ...(ngDevMode ? [{ debugName: "zoomToFitDisabled" }] : []));
890
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
891
+ timelineMode = input('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : /* istanbul ignore next */ []));
892
+ timelineModeOptions = input([], ...(ngDevMode ? [{ debugName: "timelineModeOptions" }] : /* istanbul ignore next */ []));
778
893
  timelineModeChange = output();
779
- zoomToFitToggle = output();
780
894
  // Re-emits selector changes so parent owns state updates.
781
895
  onTimelineModeChange(mode) {
782
896
  this.timelineModeChange.emit(mode);
783
897
  }
784
- onZoomToFitToggle() {
785
- if (this.zoomToFitDisabled()) {
786
- return;
787
- }
788
- this.zoomToFitToggle.emit();
789
- }
790
- getZoomToFitTooltip() {
791
- return this.zoomToFit() ? 'Disable zoom to fit' : 'Zoom to fit';
792
- }
793
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
794
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: TimelineHeader, isStandalone: true, selector: "mt-timeline-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, timelineModeOptions: { classPropertyName: "timelineModeOptions", publicName: "timelineModeOptions", isSignal: true, isRequired: false, transformFunction: null }, showZoomToFitControl: { classPropertyName: "showZoomToFitControl", publicName: "showZoomToFitControl", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, zoomToFitDisabled: { classPropertyName: "zoomToFitDisabled", publicName: "zoomToFitDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timelineModeChange: "timelineModeChange", zoomToFitToggle: "zoomToFitToggle" }, ngImport: i0, template: "<!-- Timeline title + scale mode selector. -->\r\n<div\r\n class=\"flex flex-wrap items-center justify-between gap-3\"\r\n *transloco=\"let t; prefix: 'timeline'\"\r\n>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-icon icon=\"custom.timeline-point\" class=\"text-base\"></mt-icon>\r\n <h3 class=\"text-base font-semibold\">{{ title() || t(\"timeline\") }}</h3>\r\n </div>\r\n\r\n <!-- Scale mode switcher (monthly/quarterly/etc.). -->\r\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\r\n @if (showZoomToFitControl()) {\r\n <mt-button\r\n class=\"shrink-0\"\r\n type=\"button\"\r\n icon=\"layout.maximize-01\"\r\n size=\"large\"\r\n [tooltip]=\"getZoomToFitTooltip()\"\r\n [severity]=\"zoomToFit() ? 'primary' : 'secondary'\"\r\n [outlined]=\"!zoomToFit()\"\r\n [disabled]=\"zoomToFitDisabled()\"\r\n (onClick)=\"onZoomToFitToggle()\"\r\n />\r\n }\r\n\r\n <div class=\"w-44\">\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"timelineModeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [showClear]=\"false\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('timeline-mode')\"\r\n [ngModel]=\"timelineMode()\"\r\n (onChange)=\"onTimelineModeChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
898
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
899
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: TimelineHeader, isStandalone: true, selector: "mt-timeline-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, timelineModeOptions: { classPropertyName: "timelineModeOptions", publicName: "timelineModeOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timelineModeChange: "timelineModeChange" }, ngImport: i0, template: "<!-- Timeline title + scale mode selector. -->\n<div\n class=\"flex flex-wrap items-center justify-between gap-3\"\n *transloco=\"let t; prefix: 'timeline'\"\n>\n <div class=\"flex items-center gap-2\">\n <mt-icon icon=\"custom.timeline-point\" class=\"text-base\"></mt-icon>\n <h3 class=\"text-base font-semibold\">{{ title() || t(\"timeline\") }}</h3>\n </div>\n\n <!-- Scale mode switcher (monthly/quarterly/etc.). -->\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\n <div class=\"w-44\">\n <mt-select-field\n [field]=\"false\"\n [options]=\"timelineModeOptions()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionIcon=\"icon\"\n optionIconColor=\"color\"\n optionAvatarShape=\"circle\"\n [showClear]=\"false\"\n [hasPlaceholderPrefix]=\"false\"\n [placeholder]=\"t('view')\"\n [ngModel]=\"timelineMode()\"\n (onChange)=\"onTimelineModeChange($event)\"\n />\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
795
900
  }
796
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TimelineHeader, decorators: [{
901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TimelineHeader, decorators: [{
797
902
  type: Component,
798
- args: [{ selector: 'mt-timeline-header', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, Button, TranslocoDirective, SelectField, Icon], template: "<!-- Timeline title + scale mode selector. -->\r\n<div\r\n class=\"flex flex-wrap items-center justify-between gap-3\"\r\n *transloco=\"let t; prefix: 'timeline'\"\r\n>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-icon icon=\"custom.timeline-point\" class=\"text-base\"></mt-icon>\r\n <h3 class=\"text-base font-semibold\">{{ title() || t(\"timeline\") }}</h3>\r\n </div>\r\n\r\n <!-- Scale mode switcher (monthly/quarterly/etc.). -->\r\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\r\n @if (showZoomToFitControl()) {\r\n <mt-button\r\n class=\"shrink-0\"\r\n type=\"button\"\r\n icon=\"layout.maximize-01\"\r\n size=\"large\"\r\n [tooltip]=\"getZoomToFitTooltip()\"\r\n [severity]=\"zoomToFit() ? 'primary' : 'secondary'\"\r\n [outlined]=\"!zoomToFit()\"\r\n [disabled]=\"zoomToFitDisabled()\"\r\n (onClick)=\"onZoomToFitToggle()\"\r\n />\r\n }\r\n\r\n <div class=\"w-44\">\r\n <mt-select-field\r\n [field]=\"false\"\r\n [options]=\"timelineModeOptions()\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [showClear]=\"false\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('timeline-mode')\"\r\n [ngModel]=\"timelineMode()\"\r\n (onChange)=\"onTimelineModeChange($event)\"\r\n />\r\n </div>\r\n </div>\r\n</div>\r\n" }]
799
- }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }], timelineModeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineModeOptions", required: false }] }], showZoomToFitControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoomToFitControl", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }], zoomToFitDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFitDisabled", required: false }] }], timelineModeChange: [{ type: i0.Output, args: ["timelineModeChange"] }], zoomToFitToggle: [{ type: i0.Output, args: ["zoomToFitToggle"] }] } });
903
+ args: [{ selector: 'mt-timeline-header', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, TranslocoDirective, SelectField, Icon], template: "<!-- Timeline title + scale mode selector. -->\n<div\n class=\"flex flex-wrap items-center justify-between gap-3\"\n *transloco=\"let t; prefix: 'timeline'\"\n>\n <div class=\"flex items-center gap-2\">\n <mt-icon icon=\"custom.timeline-point\" class=\"text-base\"></mt-icon>\n <h3 class=\"text-base font-semibold\">{{ title() || t(\"timeline\") }}</h3>\n </div>\n\n <!-- Scale mode switcher (monthly/quarterly/etc.). -->\n <div class=\"flex flex-wrap items-center justify-end gap-2\">\n <div class=\"w-44\">\n <mt-select-field\n [field]=\"false\"\n [options]=\"timelineModeOptions()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionIcon=\"icon\"\n optionIconColor=\"color\"\n optionAvatarShape=\"circle\"\n [showClear]=\"false\"\n [hasPlaceholderPrefix]=\"false\"\n [placeholder]=\"t('view')\"\n [ngModel]=\"timelineMode()\"\n (onChange)=\"onTimelineModeChange($event)\"\n />\n </div>\n </div>\n</div>\n" }]
904
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }], timelineModeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineModeOptions", required: false }] }], timelineModeChange: [{ type: i0.Output, args: ["timelineModeChange"] }] } });
800
905
 
801
906
  // Default scale mode values (labels are resolved at runtime via i18n).
802
907
  const DEFAULT_TIMELINE_MODE_VALUES = [
@@ -805,6 +910,13 @@ const DEFAULT_TIMELINE_MODE_VALUES = [
805
910
  'biannually',
806
911
  'annually',
807
912
  ];
913
+ const ZOOM_TO_FIT_VIEW = 'zoom-to-fit';
914
+ const ZOOM_TO_FIT_MIN_CELL_WIDTH_PX = {
915
+ monthly: 56,
916
+ quarterly: 72,
917
+ biannually: 84,
918
+ annually: 96,
919
+ };
808
920
  /**
809
921
  * Dynamic Gantt timeline component.
810
922
  *
@@ -826,53 +938,73 @@ class Timeline {
826
938
  detailsPopoverClickAnchor;
827
939
  transloco = inject(TranslocoService);
828
940
  destroyRef = inject(DestroyRef);
829
- activeLang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "activeLang" }] : []));
830
- title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
831
- emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
832
- isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
833
- showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
834
- showZoomToFitControl = input(false, ...(ngDevMode ? [{ debugName: "showZoomToFitControl" }] : []));
835
- timelineMode = model('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : []));
836
- timelineModeOptions = input([], ...(ngDevMode ? [{ debugName: "timelineModeOptions" }] : []));
941
+ activeLang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "activeLang" }] : /* istanbul ignore next */ []));
942
+ timelineViewportWidthPx = signal(0, ...(ngDevMode ? [{ debugName: "timelineViewportWidthPx" }] : /* istanbul ignore next */ []));
943
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
944
+ emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
945
+ isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
946
+ showHeader = input(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : /* istanbul ignore next */ []));
947
+ showZoomToFitControl = input(false, ...(ngDevMode ? [{ debugName: "showZoomToFitControl" }] : /* istanbul ignore next */ []));
948
+ timelineMode = model('quarterly', ...(ngDevMode ? [{ debugName: "timelineMode" }] : /* istanbul ignore next */ []));
949
+ timelineModeOptions = input([], ...(ngDevMode ? [{ debugName: "timelineModeOptions" }] : /* istanbul ignore next */ []));
837
950
  resolvedTimelineModeOptions = computed(() => {
838
951
  const options = this.timelineModeOptions();
839
- if (options.length)
840
- return options;
841
952
  this.activeLang(); // reactive dependency for language changes
842
- return DEFAULT_TIMELINE_MODE_VALUES.map((value) => ({
843
- label: this.transloco.translate(`timeline.mode-${value}`),
844
- value,
845
- }));
846
- }, ...(ngDevMode ? [{ debugName: "resolvedTimelineModeOptions" }] : []));
847
- zoomToFit = model(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : []));
848
- ganttData = input([], ...(ngDevMode ? [{ debugName: "ganttData" }] : []));
849
- ganttMapping = input(null, ...(ngDevMode ? [{ debugName: "ganttMapping" }] : []));
953
+ const baseOptions = options.length
954
+ ? options
955
+ : DEFAULT_TIMELINE_MODE_VALUES.map((value) => ({
956
+ label: this.transloco.translate(`timeline.mode-${value}`),
957
+ value,
958
+ }));
959
+ if (!this.showZoomToFitControl()) {
960
+ return baseOptions;
961
+ }
962
+ const hasZoomToFitOption = baseOptions.some((option) => option.value === ZOOM_TO_FIT_VIEW);
963
+ if (hasZoomToFitOption) {
964
+ return baseOptions;
965
+ }
966
+ return [
967
+ ...baseOptions,
968
+ {
969
+ label: this.transloco.translate('timeline.mode-zoom-to-fit'),
970
+ value: ZOOM_TO_FIT_VIEW,
971
+ icon: 'layout.maximize-01',
972
+ color: 'primary',
973
+ },
974
+ ];
975
+ }, ...(ngDevMode ? [{ debugName: "resolvedTimelineModeOptions" }] : /* istanbul ignore next */ []));
976
+ zoomToFit = model(false, ...(ngDevMode ? [{ debugName: "zoomToFit" }] : /* istanbul ignore next */ []));
977
+ ganttData = input([], ...(ngDevMode ? [{ debugName: "ganttData" }] : /* istanbul ignore next */ []));
978
+ ganttMapping = input(null, ...(ngDevMode ? [{ debugName: "ganttMapping" }] : /* istanbul ignore next */ []));
850
979
  // Null means "legacy defaults". Empty array means "progress-only" mode.
851
- columns = input(null, ...(ngDevMode ? [{ debugName: "columns" }] : []));
852
- ganttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "ganttSegmentWidthPx" }] : []));
853
- defaultVisibleColumns = input(4, ...(ngDevMode ? [{ debugName: "defaultVisibleColumns" }] : []));
854
- columnsPaneMinWidthPx = input(0, ...(ngDevMode ? [{ debugName: "columnsPaneMinWidthPx" }] : []));
855
- columnsPaneMaxWidthPx = input(null, ...(ngDevMode ? [{ debugName: "columnsPaneMaxWidthPx" }] : []));
980
+ columns = input(null, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
981
+ ganttSegmentWidthPx = input(96, ...(ngDevMode ? [{ debugName: "ganttSegmentWidthPx" }] : /* istanbul ignore next */ []));
982
+ defaultVisibleColumns = input(4, ...(ngDevMode ? [{ debugName: "defaultVisibleColumns" }] : /* istanbul ignore next */ []));
983
+ columnsPaneMinWidthPx = input(0, ...(ngDevMode ? [{ debugName: "columnsPaneMinWidthPx" }] : /* istanbul ignore next */ []));
984
+ columnsPaneMaxWidthPx = input(null, ...(ngDevMode ? [{ debugName: "columnsPaneMaxWidthPx" }] : /* istanbul ignore next */ []));
985
+ enableVirtualScroll = input(true, ...(ngDevMode ? [{ debugName: "enableVirtualScroll" }] : /* istanbul ignore next */ []));
986
+ virtualScrollThreshold = input(120, ...(ngDevMode ? [{ debugName: "virtualScrollThreshold" }] : /* istanbul ignore next */ []));
987
+ virtualScrollBodyHeightPx = input(640, ...(ngDevMode ? [{ debugName: "virtualScrollBodyHeightPx" }] : /* istanbul ignore next */ []));
856
988
  // Backward-compatible defaults when `columns` is null.
857
- ganttTitleColumnLabel = input('', ...(ngDevMode ? [{ debugName: "ganttTitleColumnLabel" }] : []));
858
- ganttStatusColumnLabel = input('', ...(ngDevMode ? [{ debugName: "ganttStatusColumnLabel" }] : []));
859
- ganttInitiativeColumnWidthPx = input(288, ...(ngDevMode ? [{ debugName: "ganttInitiativeColumnWidthPx" }] : []));
860
- ganttStatusColumnWidthPx = input(160, ...(ngDevMode ? [{ debugName: "ganttStatusColumnWidthPx" }] : []));
861
- showGanttStatusColumn = input(false, ...(ngDevMode ? [{ debugName: "showGanttStatusColumn" }] : []));
862
- showGanttDetailsPopup = input(true, ...(ngDevMode ? [{ debugName: "showGanttDetailsPopup" }] : []));
989
+ ganttTitleColumnLabel = input('', ...(ngDevMode ? [{ debugName: "ganttTitleColumnLabel" }] : /* istanbul ignore next */ []));
990
+ ganttStatusColumnLabel = input('', ...(ngDevMode ? [{ debugName: "ganttStatusColumnLabel" }] : /* istanbul ignore next */ []));
991
+ ganttInitiativeColumnWidthPx = input(288, ...(ngDevMode ? [{ debugName: "ganttInitiativeColumnWidthPx" }] : /* istanbul ignore next */ []));
992
+ ganttStatusColumnWidthPx = input(160, ...(ngDevMode ? [{ debugName: "ganttStatusColumnWidthPx" }] : /* istanbul ignore next */ []));
993
+ showGanttStatusColumn = input(false, ...(ngDevMode ? [{ debugName: "showGanttStatusColumn" }] : /* istanbul ignore next */ []));
994
+ showGanttDetailsPopup = input(true, ...(ngDevMode ? [{ debugName: "showGanttDetailsPopup" }] : /* istanbul ignore next */ []));
863
995
  // Public events exposed to consumers.
864
996
  timelineModeChangeEvent = output();
865
997
  ganttItemClick = output();
866
998
  // Optional full-template override for the Gantt body.
867
- ganttTemplate = contentChild(TimelineGanttTemplateDirective, ...(ngDevMode ? [{ debugName: "ganttTemplate" }] : []));
999
+ ganttTemplate = contentChild(TimelineGanttTemplateDirective, ...(ngDevMode ? [{ debugName: "ganttTemplate" }] : /* istanbul ignore next */ []));
868
1000
  // Optional cell template override for a specific column key.
869
- columnTemplates = contentChildren((TimelineColumnTemplateDirective), ...(ngDevMode ? [{ debugName: "columnTemplates" }] : []));
1001
+ columnTemplates = contentChildren((TimelineColumnTemplateDirective), ...(ngDevMode ? [{ debugName: "columnTemplates" }] : /* istanbul ignore next */ []));
870
1002
  // Optional popup content override (clicked progress item details).
871
- popoverTemplate = contentChild((TimelinePopoverTemplateDirective), ...(ngDevMode ? [{ debugName: "popoverTemplate" }] : []));
1003
+ popoverTemplate = contentChild((TimelinePopoverTemplateDirective), ...(ngDevMode ? [{ debugName: "popoverTemplate" }] : /* istanbul ignore next */ []));
872
1004
  // Optional progress bar renderer override.
873
- progressTemplate = contentChild((TimelineProgressTemplateDirective), ...(ngDevMode ? [{ debugName: "progressTemplate" }] : []));
874
- collapsedGanttIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "collapsedGanttIds" }] : []));
875
- selectedGanttItem = signal(null, ...(ngDevMode ? [{ debugName: "selectedGanttItem" }] : []));
1005
+ progressTemplate = contentChild((TimelineProgressTemplateDirective), ...(ngDevMode ? [{ debugName: "progressTemplate" }] : /* istanbul ignore next */ []));
1006
+ collapsedGanttIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "collapsedGanttIds" }] : /* istanbul ignore next */ []));
1007
+ selectedGanttItem = signal(null, ...(ngDevMode ? [{ debugName: "selectedGanttItem" }] : /* istanbul ignore next */ []));
876
1008
  // Maps `mtTimelineColumn` templates by key for fast lookup in row rendering.
877
1009
  columnTemplatesByKey = computed(() => {
878
1010
  const map = new Map();
@@ -882,7 +1014,7 @@ class Timeline {
882
1014
  }
883
1015
  }
884
1016
  return map;
885
- }, ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : []));
1017
+ }, ...(ngDevMode ? [{ debugName: "columnTemplatesByKey" }] : /* istanbul ignore next */ []));
886
1018
  mappedGanttNodes = computed(() => {
887
1019
  const mapping = this.ganttMapping();
888
1020
  const data = this.ganttData();
@@ -893,20 +1025,34 @@ class Timeline {
893
1025
  return data
894
1026
  .map((item) => this.mapNode(item, mapping, state))
895
1027
  .filter((item) => item !== null);
896
- }, ...(ngDevMode ? [{ debugName: "mappedGanttNodes" }] : []));
1028
+ }, ...(ngDevMode ? [{ debugName: "mappedGanttNodes" }] : /* istanbul ignore next */ []));
1029
+ selectedTimelineView = computed(() => {
1030
+ if (this.timelineMode() === ZOOM_TO_FIT_VIEW || this.zoomToFit()) {
1031
+ return ZOOM_TO_FIT_VIEW;
1032
+ }
1033
+ return this.timelineMode();
1034
+ }, ...(ngDevMode ? [{ debugName: "selectedTimelineView" }] : /* istanbul ignore next */ []));
1035
+ resolvedTimelineRange = computed(() => this.resolveDateRange(this.mappedGanttNodes()), ...(ngDevMode ? [{ debugName: "resolvedTimelineRange" }] : /* istanbul ignore next */ []));
1036
+ resolvedRenderTimelineMode = computed(() => {
1037
+ const selectedView = this.selectedTimelineView();
1038
+ if (selectedView !== ZOOM_TO_FIT_VIEW) {
1039
+ return selectedView;
1040
+ }
1041
+ const range = this.resolvedTimelineRange();
1042
+ if (!range) {
1043
+ return 'quarterly';
1044
+ }
1045
+ return this.resolveZoomToFitMode(range.startAt, range.endAt, this.timelineViewportWidthPx());
1046
+ }, ...(ngDevMode ? [{ debugName: "resolvedRenderTimelineMode" }] : /* istanbul ignore next */ []));
897
1047
  // Builds time columns from the mapped data date range and selected mode.
898
1048
  orderedGanttSegments = computed(() => {
899
- const nodes = this.mappedGanttNodes();
900
- if (!nodes.length) {
901
- return [];
902
- }
903
- const range = this.resolveDateRange(nodes);
1049
+ const range = this.resolvedTimelineRange();
904
1050
  if (!range) {
905
1051
  return [];
906
1052
  }
907
- return this.buildSegments(range.startAt, range.endAt, this.timelineMode());
908
- }, ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : []));
909
- canZoomToFit = computed(() => this.orderedGanttSegments().length > 0, ...(ngDevMode ? [{ debugName: "canZoomToFit" }] : []));
1053
+ return this.buildSegments(range.startAt, range.endAt, this.resolvedRenderTimelineMode());
1054
+ }, ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : /* istanbul ignore next */ []));
1055
+ isZoomToFitActive = computed(() => this.selectedTimelineView() === ZOOM_TO_FIT_VIEW, ...(ngDevMode ? [{ debugName: "isZoomToFitActive" }] : /* istanbul ignore next */ []));
910
1056
  constructor() {
911
1057
  this.transloco.langChanges$
912
1058
  .pipe(takeUntilDestroyed(this.destroyRef))
@@ -914,17 +1060,19 @@ class Timeline {
914
1060
  }
915
1061
  // Timeline mode is controlled by parent model signal to keep it externally bindable.
916
1062
  onTimelineModeChange(mode) {
917
- if (!mode || this.timelineMode() === mode) {
1063
+ if (!mode || this.selectedTimelineView() === mode) {
918
1064
  return;
919
1065
  }
1066
+ const enableZoomToFit = mode === ZOOM_TO_FIT_VIEW;
1067
+ this.zoomToFit.set(enableZoomToFit);
920
1068
  this.timelineMode.set(mode);
921
1069
  this.timelineModeChangeEvent.emit(mode);
922
1070
  }
923
- onZoomToFitToggle() {
924
- if (!this.canZoomToFit()) {
1071
+ onTimelineViewportWidthChange(widthPx) {
1072
+ if (!Number.isFinite(widthPx) || widthPx <= 0) {
925
1073
  return;
926
1074
  }
927
- this.zoomToFit.update((current) => !current);
1075
+ this.timelineViewportWidthPx.set(widthPx);
928
1076
  }
929
1077
  // Handles row progress clicks: emits public event and opens details popover.
930
1078
  onGanttProgressClick(item, event) {
@@ -1047,10 +1195,24 @@ class Timeline {
1047
1195
  return this.genSegments(startAt, endAt, 6, (month) => `H ${month < 6 ? 1 : 2}`, 'H');
1048
1196
  case 'annually':
1049
1197
  return this.genSegments(startAt, endAt, 12, () => 'Y', 'Y');
1050
- default:
1051
- return this.genSegments(startAt, endAt, 3, (month) => `Q ${Math.floor(month / 3) + 1}`, 'Q');
1052
1198
  }
1053
1199
  }
1200
+ resolveZoomToFitMode(startAt, endAt, viewportWidthPx) {
1201
+ const availableWidthPx = viewportWidthPx > 0
1202
+ ? viewportWidthPx
1203
+ : Math.max(this.ganttSegmentWidthPx() * 4, 320);
1204
+ for (const mode of DEFAULT_TIMELINE_MODE_VALUES) {
1205
+ const segments = this.buildSegments(startAt, endAt, mode);
1206
+ if (!segments.length) {
1207
+ continue;
1208
+ }
1209
+ const fittedCellWidthPx = availableWidthPx / segments.length;
1210
+ if (fittedCellWidthPx >= ZOOM_TO_FIT_MIN_CELL_WIDTH_PX[mode]) {
1211
+ return mode;
1212
+ }
1213
+ }
1214
+ return 'annually';
1215
+ }
1054
1216
  // Generates contiguous segments between range boundaries.
1055
1217
  genSegments(startAt, endAt, stepMonths, title, prefix) {
1056
1218
  const segments = [];
@@ -1198,10 +1360,10 @@ class Timeline {
1198
1360
  anchor.style.top = `${event.clientY}px`;
1199
1361
  return anchor;
1200
1362
  }
1201
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Timeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
1202
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: Timeline, isStandalone: true, selector: "mt-timeline", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showZoomToFitControl: { classPropertyName: "showZoomToFitControl", publicName: "showZoomToFitControl", isSignal: true, isRequired: false, transformFunction: null }, timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, timelineModeOptions: { classPropertyName: "timelineModeOptions", publicName: "timelineModeOptions", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, ganttData: { classPropertyName: "ganttData", publicName: "ganttData", isSignal: true, isRequired: false, transformFunction: null }, ganttMapping: { classPropertyName: "ganttMapping", publicName: "ganttMapping", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ganttSegmentWidthPx: { classPropertyName: "ganttSegmentWidthPx", publicName: "ganttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, defaultVisibleColumns: { classPropertyName: "defaultVisibleColumns", publicName: "defaultVisibleColumns", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMinWidthPx: { classPropertyName: "columnsPaneMinWidthPx", publicName: "columnsPaneMinWidthPx", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMaxWidthPx: { classPropertyName: "columnsPaneMaxWidthPx", publicName: "columnsPaneMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, ganttTitleColumnLabel: { classPropertyName: "ganttTitleColumnLabel", publicName: "ganttTitleColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnLabel: { classPropertyName: "ganttStatusColumnLabel", publicName: "ganttStatusColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttInitiativeColumnWidthPx: { classPropertyName: "ganttInitiativeColumnWidthPx", publicName: "ganttInitiativeColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnWidthPx: { classPropertyName: "ganttStatusColumnWidthPx", publicName: "ganttStatusColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, showGanttStatusColumn: { classPropertyName: "showGanttStatusColumn", publicName: "showGanttStatusColumn", isSignal: true, isRequired: false, transformFunction: null }, showGanttDetailsPopup: { classPropertyName: "showGanttDetailsPopup", publicName: "showGanttDetailsPopup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timelineMode: "timelineModeChange", zoomToFit: "zoomToFitChange", timelineModeChangeEvent: "timelineModeChangeEvent", ganttItemClick: "ganttItemClick" }, host: { classAttribute: "block" }, queries: [{ propertyName: "ganttTemplate", first: true, predicate: TimelineGanttTemplateDirective, descendants: true, isSignal: true }, { propertyName: "columnTemplates", predicate: (TimelineColumnTemplateDirective), isSignal: true }, { propertyName: "popoverTemplate", first: true, predicate: (TimelinePopoverTemplateDirective), descendants: true, isSignal: true }, { propertyName: "progressTemplate", first: true, predicate: (TimelineProgressTemplateDirective), descendants: true, isSignal: true }], viewQueries: [{ propertyName: "detailsPopover", first: true, predicate: ["detailsPopover"], descendants: true }, { propertyName: "detailsPopoverClickAnchor", first: true, predicate: ["detailsPopoverClickAnchor"], descendants: true }], ngImport: i0, template: "<div class=\"mt-3 block overflow-hidden\" *transloco=\"let t; prefix: 'timeline'\">\r\n <!-- Optional top header (title + timeline mode selector). -->\r\n @if (showHeader()) {\r\n <mt-timeline-header\r\n [title]=\"title() || t('timeline')\"\r\n [timelineMode]=\"timelineMode()\"\r\n [timelineModeOptions]=\"resolvedTimelineModeOptions()\"\r\n [showZoomToFitControl]=\"showZoomToFitControl()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [zoomToFitDisabled]=\"!canZoomToFit()\"\r\n (timelineModeChange)=\"onTimelineModeChange($event)\"\r\n (zoomToFitToggle)=\"onZoomToFitToggle()\"\r\n />\r\n }\r\n\r\n <!-- Loading state. -->\r\n @if (isLoading()) {\r\n <div class=\"flex min-h-56 items-center justify-center p-8\">\r\n <div\r\n class=\"h-8 w-8 animate-spin rounded-full border-2 border-surface-200\"\r\n style=\"border-top-color: var(--p-primary-color)\"\r\n ></div>\r\n </div>\r\n } @else if (ganttTemplate(); as template) {\r\n <!-- Full custom gantt-body override. -->\r\n <div class=\"min-h-56 py-4\">\r\n <ng-container [ngTemplateOutlet]=\"template.templateRef\"></ng-container>\r\n </div>\r\n } @else if (\r\n mappedGanttNodes().length > 0 && orderedGanttSegments().length > 0\r\n ) {\r\n <!-- Built-in gantt renderer. -->\r\n <mt-timeline-gantt\r\n [timelineMode]=\"timelineMode()\"\r\n [columns]=\"columns()\"\r\n [ganttTitleColumnLabel]=\"ganttTitleColumnLabel() || t('portfolio-name')\"\r\n [ganttStatusColumnLabel]=\"ganttStatusColumnLabel() || t('status')\"\r\n [ganttInitiativeColumnWidthPx]=\"ganttInitiativeColumnWidthPx()\"\r\n [ganttStatusColumnWidthPx]=\"ganttStatusColumnWidthPx()\"\r\n [showGanttStatusColumn]=\"showGanttStatusColumn()\"\r\n [ganttSegmentWidthPx]=\"ganttSegmentWidthPx()\"\r\n [defaultVisibleColumns]=\"defaultVisibleColumns()\"\r\n [columnsPaneMinWidthPx]=\"columnsPaneMinWidthPx()\"\r\n [columnsPaneMaxWidthPx]=\"columnsPaneMaxWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [mappedGanttNodes]=\"mappedGanttNodes()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [collapsedGanttIds]=\"collapsedGanttIds()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplate()\"\r\n (toggleCollapse)=\"toggleGanttCollapse($event)\"\r\n (progressClick)=\"onGanttProgressClick($event.item, $event.event)\"\r\n />\r\n } @else {\r\n <!-- Empty state. -->\r\n <div\r\n class=\"flex min-h-56 items-center justify-center p-8 text-sm text-surface-500\"\r\n >\r\n {{ emptyMessage() || t(\"empty-message\") }}\r\n </div>\r\n }\r\n\r\n <!-- Details popover host (custom template or built-in fallback). -->\r\n <p-popover #detailsPopover appendTo=\"body\" (onHide)=\"onDetailsPopoverHide()\">\r\n @if (showGanttDetailsPopup() && selectedGanttItem(); as item) {\r\n @if (popoverTemplate(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template.templateRef\"\r\n [ngTemplateOutletContext]=\"getPopoverTemplateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <mt-timeline-default-popover\r\n [item]=\"item\"\r\n (requestClose)=\"hideDetailsPopover()\"\r\n />\r\n }\r\n }\r\n </p-popover>\r\n\r\n <!-- Point anchor used to place the popover exactly where user clicked. -->\r\n <span\r\n #detailsPopoverClickAnchor\r\n class=\"pointer-events-none fixed h-0 w-0\"\r\n [style.left.px]=\"-9999\"\r\n [style.top.px]=\"-9999\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n</div>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: TimelineHeader, selector: "mt-timeline-header", inputs: ["title", "timelineMode", "timelineModeOptions", "showZoomToFitControl", "zoomToFit", "zoomToFitDisabled"], outputs: ["timelineModeChange", "zoomToFitToggle"] }, { kind: "component", type: TimelineGantt, selector: "mt-timeline-gantt", inputs: ["timelineMode", "columns", "ganttTitleColumnLabel", "ganttStatusColumnLabel", "ganttInitiativeColumnWidthPx", "ganttStatusColumnWidthPx", "showGanttStatusColumn", "ganttSegmentWidthPx", "defaultVisibleColumns", "columnsPaneMinWidthPx", "columnsPaneMaxWidthPx", "zoomToFit", "mappedGanttNodes", "orderedGanttSegments", "collapsedGanttIds", "columnTemplatesByKey", "progressTemplateDirective"], outputs: ["toggleCollapse", "progressClick"] }, { kind: "component", type: TimelineDefaultPopover, selector: "mt-timeline-default-popover", inputs: ["item"], outputs: ["requestClose"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1363
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Timeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
1364
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: Timeline, isStandalone: true, selector: "mt-timeline", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showZoomToFitControl: { classPropertyName: "showZoomToFitControl", publicName: "showZoomToFitControl", isSignal: true, isRequired: false, transformFunction: null }, timelineMode: { classPropertyName: "timelineMode", publicName: "timelineMode", isSignal: true, isRequired: false, transformFunction: null }, timelineModeOptions: { classPropertyName: "timelineModeOptions", publicName: "timelineModeOptions", isSignal: true, isRequired: false, transformFunction: null }, zoomToFit: { classPropertyName: "zoomToFit", publicName: "zoomToFit", isSignal: true, isRequired: false, transformFunction: null }, ganttData: { classPropertyName: "ganttData", publicName: "ganttData", isSignal: true, isRequired: false, transformFunction: null }, ganttMapping: { classPropertyName: "ganttMapping", publicName: "ganttMapping", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, ganttSegmentWidthPx: { classPropertyName: "ganttSegmentWidthPx", publicName: "ganttSegmentWidthPx", isSignal: true, isRequired: false, transformFunction: null }, defaultVisibleColumns: { classPropertyName: "defaultVisibleColumns", publicName: "defaultVisibleColumns", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMinWidthPx: { classPropertyName: "columnsPaneMinWidthPx", publicName: "columnsPaneMinWidthPx", isSignal: true, isRequired: false, transformFunction: null }, columnsPaneMaxWidthPx: { classPropertyName: "columnsPaneMaxWidthPx", publicName: "columnsPaneMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, enableVirtualScroll: { classPropertyName: "enableVirtualScroll", publicName: "enableVirtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollThreshold: { classPropertyName: "virtualScrollThreshold", publicName: "virtualScrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollBodyHeightPx: { classPropertyName: "virtualScrollBodyHeightPx", publicName: "virtualScrollBodyHeightPx", isSignal: true, isRequired: false, transformFunction: null }, ganttTitleColumnLabel: { classPropertyName: "ganttTitleColumnLabel", publicName: "ganttTitleColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnLabel: { classPropertyName: "ganttStatusColumnLabel", publicName: "ganttStatusColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, ganttInitiativeColumnWidthPx: { classPropertyName: "ganttInitiativeColumnWidthPx", publicName: "ganttInitiativeColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, ganttStatusColumnWidthPx: { classPropertyName: "ganttStatusColumnWidthPx", publicName: "ganttStatusColumnWidthPx", isSignal: true, isRequired: false, transformFunction: null }, showGanttStatusColumn: { classPropertyName: "showGanttStatusColumn", publicName: "showGanttStatusColumn", isSignal: true, isRequired: false, transformFunction: null }, showGanttDetailsPopup: { classPropertyName: "showGanttDetailsPopup", publicName: "showGanttDetailsPopup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { timelineMode: "timelineModeChange", zoomToFit: "zoomToFitChange", timelineModeChangeEvent: "timelineModeChangeEvent", ganttItemClick: "ganttItemClick" }, host: { classAttribute: "block" }, queries: [{ propertyName: "ganttTemplate", first: true, predicate: TimelineGanttTemplateDirective, descendants: true, isSignal: true }, { propertyName: "columnTemplates", predicate: (TimelineColumnTemplateDirective), isSignal: true }, { propertyName: "popoverTemplate", first: true, predicate: (TimelinePopoverTemplateDirective), descendants: true, isSignal: true }, { propertyName: "progressTemplate", first: true, predicate: (TimelineProgressTemplateDirective), descendants: true, isSignal: true }], viewQueries: [{ propertyName: "detailsPopover", first: true, predicate: ["detailsPopover"], descendants: true }, { propertyName: "detailsPopoverClickAnchor", first: true, predicate: ["detailsPopoverClickAnchor"], descendants: true }], ngImport: i0, template: "<div class=\"mt-3 block overflow-hidden\" *transloco=\"let t; prefix: 'timeline'\">\n <!-- Optional top header (title + timeline mode selector). -->\n @if (showHeader()) {\n <mt-timeline-header\n [title]=\"title() || t('timeline')\"\n [timelineMode]=\"selectedTimelineView()\"\n [timelineModeOptions]=\"resolvedTimelineModeOptions()\"\n (timelineModeChange)=\"onTimelineModeChange($event)\"\n />\n }\n\n <!-- Loading state. -->\n @if (isLoading()) {\n <div class=\"flex min-h-56 items-center justify-center p-8\">\n <div\n class=\"h-8 w-8 animate-spin rounded-full border-2 border-surface-200\"\n style=\"border-top-color: var(--p-primary-color)\"\n ></div>\n </div>\n } @else if (ganttTemplate(); as template) {\n <!-- Full custom gantt-body override. -->\n <div class=\"min-h-56 py-4\">\n <ng-container [ngTemplateOutlet]=\"template.templateRef\"></ng-container>\n </div>\n } @else if (\n mappedGanttNodes().length > 0 && orderedGanttSegments().length > 0\n ) {\n <!-- Built-in gantt renderer. -->\n <mt-timeline-gantt\n [timelineMode]=\"resolvedRenderTimelineMode()\"\n [columns]=\"columns()\"\n [ganttTitleColumnLabel]=\"ganttTitleColumnLabel() || t('portfolio-name')\"\n [ganttStatusColumnLabel]=\"ganttStatusColumnLabel() || t('status')\"\n [ganttInitiativeColumnWidthPx]=\"ganttInitiativeColumnWidthPx()\"\n [ganttStatusColumnWidthPx]=\"ganttStatusColumnWidthPx()\"\n [showGanttStatusColumn]=\"showGanttStatusColumn()\"\n [ganttSegmentWidthPx]=\"ganttSegmentWidthPx()\"\n [defaultVisibleColumns]=\"defaultVisibleColumns()\"\n [columnsPaneMinWidthPx]=\"columnsPaneMinWidthPx()\"\n [columnsPaneMaxWidthPx]=\"columnsPaneMaxWidthPx()\"\n [enableVirtualScroll]=\"enableVirtualScroll()\"\n [virtualScrollThreshold]=\"virtualScrollThreshold()\"\n [virtualScrollBodyHeightPx]=\"virtualScrollBodyHeightPx()\"\n [zoomToFit]=\"isZoomToFitActive()\"\n [mappedGanttNodes]=\"mappedGanttNodes()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [collapsedGanttIds]=\"collapsedGanttIds()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplate()\"\n (timelineViewportWidthChange)=\"onTimelineViewportWidthChange($event)\"\n (toggleCollapse)=\"toggleGanttCollapse($event)\"\n (progressClick)=\"onGanttProgressClick($event.item, $event.event)\"\n />\n } @else {\n <!-- Empty state. -->\n <div\n class=\"flex min-h-56 items-center justify-center p-8 text-sm text-surface-500\"\n >\n {{ emptyMessage() || t(\"empty-message\") }}\n </div>\n }\n\n <!-- Details popover host (custom template or built-in fallback). -->\n <p-popover #detailsPopover appendTo=\"body\" (onHide)=\"onDetailsPopoverHide()\">\n @if (showGanttDetailsPopup() && selectedGanttItem(); as item) {\n @if (popoverTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template.templateRef\"\n [ngTemplateOutletContext]=\"getPopoverTemplateContext(item)\"\n ></ng-container>\n } @else {\n <mt-timeline-default-popover\n [item]=\"item\"\n (requestClose)=\"hideDetailsPopover()\"\n />\n }\n }\n </p-popover>\n\n <!-- Point anchor used to place the popover exactly where user clicked. -->\n <span\n #detailsPopoverClickAnchor\n class=\"pointer-events-none fixed h-0 w-0\"\n [style.left.px]=\"-9999\"\n [style.top.px]=\"-9999\"\n aria-hidden=\"true\"\n ></span>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: TimelineHeader, selector: "mt-timeline-header", inputs: ["title", "timelineMode", "timelineModeOptions"], outputs: ["timelineModeChange"] }, { kind: "component", type: TimelineGantt, selector: "mt-timeline-gantt", inputs: ["timelineMode", "columns", "ganttTitleColumnLabel", "ganttStatusColumnLabel", "ganttInitiativeColumnWidthPx", "ganttStatusColumnWidthPx", "showGanttStatusColumn", "ganttSegmentWidthPx", "defaultVisibleColumns", "columnsPaneMinWidthPx", "columnsPaneMaxWidthPx", "enableVirtualScroll", "virtualScrollThreshold", "virtualScrollBodyHeightPx", "zoomToFit", "mappedGanttNodes", "orderedGanttSegments", "collapsedGanttIds", "columnTemplatesByKey", "progressTemplateDirective"], outputs: ["toggleCollapse", "progressClick", "timelineViewportWidthChange"] }, { kind: "component", type: TimelineDefaultPopover, selector: "mt-timeline-default-popover", inputs: ["item"], outputs: ["requestClose"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1203
1365
  }
1204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Timeline, decorators: [{
1366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: Timeline, decorators: [{
1205
1367
  type: Component,
1206
1368
  args: [{ selector: 'mt-timeline', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1207
1369
  CommonModule,
@@ -1211,14 +1373,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1211
1373
  TimelineDefaultPopover,
1212
1374
  Popover,
1213
1375
  NgTemplateOutlet,
1214
- ], host: { class: 'block' }, template: "<div class=\"mt-3 block overflow-hidden\" *transloco=\"let t; prefix: 'timeline'\">\r\n <!-- Optional top header (title + timeline mode selector). -->\r\n @if (showHeader()) {\r\n <mt-timeline-header\r\n [title]=\"title() || t('timeline')\"\r\n [timelineMode]=\"timelineMode()\"\r\n [timelineModeOptions]=\"resolvedTimelineModeOptions()\"\r\n [showZoomToFitControl]=\"showZoomToFitControl()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [zoomToFitDisabled]=\"!canZoomToFit()\"\r\n (timelineModeChange)=\"onTimelineModeChange($event)\"\r\n (zoomToFitToggle)=\"onZoomToFitToggle()\"\r\n />\r\n }\r\n\r\n <!-- Loading state. -->\r\n @if (isLoading()) {\r\n <div class=\"flex min-h-56 items-center justify-center p-8\">\r\n <div\r\n class=\"h-8 w-8 animate-spin rounded-full border-2 border-surface-200\"\r\n style=\"border-top-color: var(--p-primary-color)\"\r\n ></div>\r\n </div>\r\n } @else if (ganttTemplate(); as template) {\r\n <!-- Full custom gantt-body override. -->\r\n <div class=\"min-h-56 py-4\">\r\n <ng-container [ngTemplateOutlet]=\"template.templateRef\"></ng-container>\r\n </div>\r\n } @else if (\r\n mappedGanttNodes().length > 0 && orderedGanttSegments().length > 0\r\n ) {\r\n <!-- Built-in gantt renderer. -->\r\n <mt-timeline-gantt\r\n [timelineMode]=\"timelineMode()\"\r\n [columns]=\"columns()\"\r\n [ganttTitleColumnLabel]=\"ganttTitleColumnLabel() || t('portfolio-name')\"\r\n [ganttStatusColumnLabel]=\"ganttStatusColumnLabel() || t('status')\"\r\n [ganttInitiativeColumnWidthPx]=\"ganttInitiativeColumnWidthPx()\"\r\n [ganttStatusColumnWidthPx]=\"ganttStatusColumnWidthPx()\"\r\n [showGanttStatusColumn]=\"showGanttStatusColumn()\"\r\n [ganttSegmentWidthPx]=\"ganttSegmentWidthPx()\"\r\n [defaultVisibleColumns]=\"defaultVisibleColumns()\"\r\n [columnsPaneMinWidthPx]=\"columnsPaneMinWidthPx()\"\r\n [columnsPaneMaxWidthPx]=\"columnsPaneMaxWidthPx()\"\r\n [zoomToFit]=\"zoomToFit()\"\r\n [mappedGanttNodes]=\"mappedGanttNodes()\"\r\n [orderedGanttSegments]=\"orderedGanttSegments()\"\r\n [collapsedGanttIds]=\"collapsedGanttIds()\"\r\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\r\n [progressTemplateDirective]=\"progressTemplate()\"\r\n (toggleCollapse)=\"toggleGanttCollapse($event)\"\r\n (progressClick)=\"onGanttProgressClick($event.item, $event.event)\"\r\n />\r\n } @else {\r\n <!-- Empty state. -->\r\n <div\r\n class=\"flex min-h-56 items-center justify-center p-8 text-sm text-surface-500\"\r\n >\r\n {{ emptyMessage() || t(\"empty-message\") }}\r\n </div>\r\n }\r\n\r\n <!-- Details popover host (custom template or built-in fallback). -->\r\n <p-popover #detailsPopover appendTo=\"body\" (onHide)=\"onDetailsPopoverHide()\">\r\n @if (showGanttDetailsPopup() && selectedGanttItem(); as item) {\r\n @if (popoverTemplate(); as template) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"template.templateRef\"\r\n [ngTemplateOutletContext]=\"getPopoverTemplateContext(item)\"\r\n ></ng-container>\r\n } @else {\r\n <mt-timeline-default-popover\r\n [item]=\"item\"\r\n (requestClose)=\"hideDetailsPopover()\"\r\n />\r\n }\r\n }\r\n </p-popover>\r\n\r\n <!-- Point anchor used to place the popover exactly where user clicked. -->\r\n <span\r\n #detailsPopoverClickAnchor\r\n class=\"pointer-events-none fixed h-0 w-0\"\r\n [style.left.px]=\"-9999\"\r\n [style.top.px]=\"-9999\"\r\n aria-hidden=\"true\"\r\n ></span>\r\n</div>\r\n", styles: [":host{display:block}\n"] }]
1376
+ ], host: { class: 'block' }, template: "<div class=\"mt-3 block overflow-hidden\" *transloco=\"let t; prefix: 'timeline'\">\n <!-- Optional top header (title + timeline mode selector). -->\n @if (showHeader()) {\n <mt-timeline-header\n [title]=\"title() || t('timeline')\"\n [timelineMode]=\"selectedTimelineView()\"\n [timelineModeOptions]=\"resolvedTimelineModeOptions()\"\n (timelineModeChange)=\"onTimelineModeChange($event)\"\n />\n }\n\n <!-- Loading state. -->\n @if (isLoading()) {\n <div class=\"flex min-h-56 items-center justify-center p-8\">\n <div\n class=\"h-8 w-8 animate-spin rounded-full border-2 border-surface-200\"\n style=\"border-top-color: var(--p-primary-color)\"\n ></div>\n </div>\n } @else if (ganttTemplate(); as template) {\n <!-- Full custom gantt-body override. -->\n <div class=\"min-h-56 py-4\">\n <ng-container [ngTemplateOutlet]=\"template.templateRef\"></ng-container>\n </div>\n } @else if (\n mappedGanttNodes().length > 0 && orderedGanttSegments().length > 0\n ) {\n <!-- Built-in gantt renderer. -->\n <mt-timeline-gantt\n [timelineMode]=\"resolvedRenderTimelineMode()\"\n [columns]=\"columns()\"\n [ganttTitleColumnLabel]=\"ganttTitleColumnLabel() || t('portfolio-name')\"\n [ganttStatusColumnLabel]=\"ganttStatusColumnLabel() || t('status')\"\n [ganttInitiativeColumnWidthPx]=\"ganttInitiativeColumnWidthPx()\"\n [ganttStatusColumnWidthPx]=\"ganttStatusColumnWidthPx()\"\n [showGanttStatusColumn]=\"showGanttStatusColumn()\"\n [ganttSegmentWidthPx]=\"ganttSegmentWidthPx()\"\n [defaultVisibleColumns]=\"defaultVisibleColumns()\"\n [columnsPaneMinWidthPx]=\"columnsPaneMinWidthPx()\"\n [columnsPaneMaxWidthPx]=\"columnsPaneMaxWidthPx()\"\n [enableVirtualScroll]=\"enableVirtualScroll()\"\n [virtualScrollThreshold]=\"virtualScrollThreshold()\"\n [virtualScrollBodyHeightPx]=\"virtualScrollBodyHeightPx()\"\n [zoomToFit]=\"isZoomToFitActive()\"\n [mappedGanttNodes]=\"mappedGanttNodes()\"\n [orderedGanttSegments]=\"orderedGanttSegments()\"\n [collapsedGanttIds]=\"collapsedGanttIds()\"\n [columnTemplatesByKey]=\"columnTemplatesByKey()\"\n [progressTemplateDirective]=\"progressTemplate()\"\n (timelineViewportWidthChange)=\"onTimelineViewportWidthChange($event)\"\n (toggleCollapse)=\"toggleGanttCollapse($event)\"\n (progressClick)=\"onGanttProgressClick($event.item, $event.event)\"\n />\n } @else {\n <!-- Empty state. -->\n <div\n class=\"flex min-h-56 items-center justify-center p-8 text-sm text-surface-500\"\n >\n {{ emptyMessage() || t(\"empty-message\") }}\n </div>\n }\n\n <!-- Details popover host (custom template or built-in fallback). -->\n <p-popover #detailsPopover appendTo=\"body\" (onHide)=\"onDetailsPopoverHide()\">\n @if (showGanttDetailsPopup() && selectedGanttItem(); as item) {\n @if (popoverTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template.templateRef\"\n [ngTemplateOutletContext]=\"getPopoverTemplateContext(item)\"\n ></ng-container>\n } @else {\n <mt-timeline-default-popover\n [item]=\"item\"\n (requestClose)=\"hideDetailsPopover()\"\n />\n }\n }\n </p-popover>\n\n <!-- Point anchor used to place the popover exactly where user clicked. -->\n <span\n #detailsPopoverClickAnchor\n class=\"pointer-events-none fixed h-0 w-0\"\n [style.left.px]=\"-9999\"\n [style.top.px]=\"-9999\"\n aria-hidden=\"true\"\n ></span>\n</div>\n", styles: [":host{display:block}\n"] }]
1215
1377
  }], ctorParameters: () => [], propDecorators: { detailsPopover: [{
1216
1378
  type: ViewChild,
1217
1379
  args: ['detailsPopover']
1218
1380
  }], detailsPopoverClickAnchor: [{
1219
1381
  type: ViewChild,
1220
1382
  args: ['detailsPopoverClickAnchor']
1221
- }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showZoomToFitControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoomToFitControl", required: false }] }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }, { type: i0.Output, args: ["timelineModeChange"] }], timelineModeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineModeOptions", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }, { type: i0.Output, args: ["zoomToFitChange"] }], ganttData: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttData", required: false }] }], ganttMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttMapping", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], ganttSegmentWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttSegmentWidthPx", required: false }] }], defaultVisibleColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultVisibleColumns", required: false }] }], columnsPaneMinWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMinWidthPx", required: false }] }], columnsPaneMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMaxWidthPx", required: false }] }], ganttTitleColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttTitleColumnLabel", required: false }] }], ganttStatusColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnLabel", required: false }] }], ganttInitiativeColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttInitiativeColumnWidthPx", required: false }] }], ganttStatusColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnWidthPx", required: false }] }], showGanttStatusColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttStatusColumn", required: false }] }], showGanttDetailsPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttDetailsPopup", required: false }] }], timelineModeChangeEvent: [{ type: i0.Output, args: ["timelineModeChangeEvent"] }], ganttItemClick: [{ type: i0.Output, args: ["ganttItemClick"] }], ganttTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelineGanttTemplateDirective), { isSignal: true }] }], columnTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TimelineColumnTemplateDirective), { isSignal: true }] }], popoverTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelinePopoverTemplateDirective), { isSignal: true }] }], progressTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelineProgressTemplateDirective), { isSignal: true }] }] } });
1383
+ }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], showZoomToFitControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoomToFitControl", required: false }] }], timelineMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineMode", required: false }] }, { type: i0.Output, args: ["timelineModeChange"] }], timelineModeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "timelineModeOptions", required: false }] }], zoomToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomToFit", required: false }] }, { type: i0.Output, args: ["zoomToFitChange"] }], ganttData: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttData", required: false }] }], ganttMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttMapping", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], ganttSegmentWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttSegmentWidthPx", required: false }] }], defaultVisibleColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultVisibleColumns", required: false }] }], columnsPaneMinWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMinWidthPx", required: false }] }], columnsPaneMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsPaneMaxWidthPx", required: false }] }], enableVirtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableVirtualScroll", required: false }] }], virtualScrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScrollThreshold", required: false }] }], virtualScrollBodyHeightPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScrollBodyHeightPx", required: false }] }], ganttTitleColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttTitleColumnLabel", required: false }] }], ganttStatusColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnLabel", required: false }] }], ganttInitiativeColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttInitiativeColumnWidthPx", required: false }] }], ganttStatusColumnWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "ganttStatusColumnWidthPx", required: false }] }], showGanttStatusColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttStatusColumn", required: false }] }], showGanttDetailsPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGanttDetailsPopup", required: false }] }], timelineModeChangeEvent: [{ type: i0.Output, args: ["timelineModeChangeEvent"] }], ganttItemClick: [{ type: i0.Output, args: ["ganttItemClick"] }], ganttTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelineGanttTemplateDirective), { isSignal: true }] }], columnTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TimelineColumnTemplateDirective), { isSignal: true }] }], popoverTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelinePopoverTemplateDirective), { isSignal: true }] }], progressTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TimelineProgressTemplateDirective), { isSignal: true }] }] } });
1222
1384
 
1223
1385
  /**
1224
1386
  * Generated bundle index. Do not edit.