@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.
- package/assets/i18n/ar.json +24 -22
- package/assets/i18n/en.json +24 -22
- package/assets/timeline.css +1 -1
- package/fesm2022/masterteam-timeline.mjs +316 -154
- package/fesm2022/masterteam-timeline.mjs.map +1 -1
- package/package.json +12 -11
- package/types/masterteam-timeline.d.ts +19 -5
|
@@ -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.
|
|
18
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.
|
|
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.
|
|
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.
|
|
32
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.
|
|
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.
|
|
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.
|
|
48
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.
|
|
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.
|
|
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.
|
|
61
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.
|
|
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.
|
|
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.
|
|
84
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.
|
|
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.
|
|
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.
|
|
144
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
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.
|
|
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.
|
|
282
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
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.
|
|
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
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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.
|
|
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.
|
|
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
|
-
}],
|
|
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
|
-
|
|
785
|
-
|
|
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.
|
|
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,
|
|
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 }] }],
|
|
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
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
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
|
-
|
|
843
|
-
|
|
844
|
-
value
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
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
|
|
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.
|
|
908
|
-
}, ...(ngDevMode ? [{ debugName: "orderedGanttSegments" }] : []));
|
|
909
|
-
|
|
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.
|
|
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
|
-
|
|
924
|
-
if (!
|
|
1071
|
+
onTimelineViewportWidthChange(widthPx) {
|
|
1072
|
+
if (!Number.isFinite(widthPx) || widthPx <= 0) {
|
|
925
1073
|
return;
|
|
926
1074
|
}
|
|
927
|
-
this.
|
|
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.
|
|
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.
|
|
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'\">\
|
|
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.
|