@scion/workbench 21.0.0-beta.4 → 21.0.0-beta.5
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.
|
@@ -6395,7 +6395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
6395
6395
|
*/
|
|
6396
6396
|
function trackFocus(target, workbenchElement) {
|
|
6397
6397
|
const focusMonitor = inject(ɵWorkbenchFocusMonitor);
|
|
6398
|
-
|
|
6398
|
+
toObservable(focusMonitor.activeElement)
|
|
6399
6399
|
.pipe(startWith(focusMonitor.activeElement()), // Immediately subscribe to `focusin` events, required when the DOM element is focused right after invocation.
|
|
6400
6400
|
switchMap(activeWorkbenchElement => activeWorkbenchElement === workbenchElement ? EMPTY : merge(fromEvent(target, 'focusin', { once: true }), fromEvent(target, 'sci-microfrontend-focusin', { once: true }))), finalize(() => requestAnimationFrame(() => focusMonitor.unsetActiveElement(workbenchElement))), // Asynchronously unset the active workbench element to prevent a `null` focus during destruction until the next element gains focus.
|
|
6401
6401
|
takeUntilDestroyed())
|
|
@@ -6404,7 +6404,6 @@ function trackFocus(target, workbenchElement) {
|
|
|
6404
6404
|
});
|
|
6405
6405
|
return {
|
|
6406
6406
|
unsetActiveElement: () => focusMonitor.unsetActiveElement(workbenchElement),
|
|
6407
|
-
destroy: () => subscription.unsubscribe(),
|
|
6408
6407
|
};
|
|
6409
6408
|
}
|
|
6410
6409
|
class ɵWorkbenchFocusMonitor {
|
|
@@ -6426,7 +6425,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
6426
6425
|
}] });
|
|
6427
6426
|
|
|
6428
6427
|
/*
|
|
6429
|
-
* Copyright (c) 2018-
|
|
6428
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
6430
6429
|
*
|
|
6431
6430
|
* This program and the accompanying materials are made
|
|
6432
6431
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -6854,7 +6853,7 @@ class WbComponentPortal {
|
|
|
6854
6853
|
this.detach();
|
|
6855
6854
|
}
|
|
6856
6855
|
this._viewContainerRef.set(viewContainerRef);
|
|
6857
|
-
this._componentRef.update(componentRef => componentRef ?? createPortalComponent(this._componentType, { providers: this._options?.providers, injector: viewContainerRef.injector }));
|
|
6856
|
+
this._componentRef.update(componentRef => componentRef ?? createPortalComponent(this._componentType, { providers: this._options?.providers, injector: this._options?.injector ?? viewContainerRef.injector }));
|
|
6858
6857
|
this._logger.debug(() => 'Attaching portal', LoggerNames.LIFECYCLE, this._options?.debugName ?? this._componentType.name);
|
|
6859
6858
|
this._componentRef().changeDetectorRef.reattach();
|
|
6860
6859
|
this._viewContainerRef().insert(this._componentRef().hostView);
|
|
@@ -8330,7 +8329,7 @@ class MainAreaPartComponent {
|
|
|
8330
8329
|
});
|
|
8331
8330
|
}
|
|
8332
8331
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MainAreaPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8333
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: MainAreaPartComponent, isStandalone: true, selector: "wb-part[data-partid=\"part.main-area\"]", host: { properties: { "attr.data-grid": "dasherize(part.gridName())", "attr.data-active": "part.active() ? '' : null" } }, ngImport: i0, template: "@if (mainAreaGrid().root.visible) {\n <wb-grid [grid]=\"mainAreaGrid()\"\n [gridDropZone]=\"{\n dropRegionSize: 100,\n dropPlaceholderSize: 100,\n dropZoneAttributes: {\n 'data-grid': 'main-area',\n 'data-partid': part.id,\n }\n }\"\n [attr.data-grid]=\"'main-area'\"\n class=\"e2e-
|
|
8332
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: MainAreaPartComponent, isStandalone: true, selector: "wb-part[data-partid=\"part.main-area\"]", host: { properties: { "attr.data-grid": "dasherize(part.gridName())", "attr.data-active": "part.active() ? '' : null" } }, ngImport: i0, template: "@if (mainAreaGrid().root.visible) {\n <wb-grid [grid]=\"mainAreaGrid()\"\n [gridDropZone]=\"{\n dropRegionSize: 100,\n dropPlaceholderSize: 100,\n dropZoneAttributes: {\n 'data-grid': 'main-area',\n 'data-partid': part.id,\n }\n }\"\n [attr.data-grid]=\"'main-area'\"\n class=\"e2e-slot\"/>\n} @else {\n <div wbViewDropZone\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: false, south: false, west: false, east: false}\"\n [wbViewDropZoneAttributes]=\"{\n 'data-desktop': '',\n 'data-partid': part.id,\n }\"\n (wbViewDropZoneDrop)=\"onDesktopViewDrop($event)\"\n class=\"desktop e2e-part-slot e2e-slot\">\n @if (part.navigation()) {\n <ng-container *wbPortalOutlet=\"part.slot.portal; destroyOnDetach: false\"/>\n } @else {\n <ng-container *wbPortalOutlet=\"desktop.slot.portal; destroyOnDetach: false\"/>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>wb-grid{flex:auto}:host>div.desktop{flex:auto;display:grid;position:relative}\n"], dependencies: [{ kind: "component", type: GridComponent, selector: "wb-grid", inputs: ["grid", "gridDropZone"] }, { kind: "directive", type: ViewDropZoneDirective, selector: "[wbViewDropZone]", inputs: ["wbViewDropZoneRegions", "wbViewDropZoneAttributes", "wbViewDropZoneRegionSize", "wbViewDropZonePlaceholderSize"], outputs: ["wbViewDropZoneDrop"] }, { kind: "directive", type: WorkbenchPortalOutletDirective, selector: "ng-template[wbPortalOutlet]", inputs: ["wbPortalOutlet", "wbPortalOutletDestroyOnDetach"] }] });
|
|
8334
8333
|
}
|
|
8335
8334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MainAreaPartComponent, decorators: [{
|
|
8336
8335
|
type: Component,
|
|
@@ -8341,7 +8340,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
8341
8340
|
], host: {
|
|
8342
8341
|
'[attr.data-grid]': 'dasherize(part.gridName())',
|
|
8343
8342
|
'[attr.data-active]': `part.active() ? '' : null`,
|
|
8344
|
-
}, template: "@if (mainAreaGrid().root.visible) {\n <wb-grid [grid]=\"mainAreaGrid()\"\n [gridDropZone]=\"{\n dropRegionSize: 100,\n dropPlaceholderSize: 100,\n dropZoneAttributes: {\n 'data-grid': 'main-area',\n 'data-partid': part.id,\n }\n }\"\n [attr.data-grid]=\"'main-area'\"\n class=\"e2e-
|
|
8343
|
+
}, template: "@if (mainAreaGrid().root.visible) {\n <wb-grid [grid]=\"mainAreaGrid()\"\n [gridDropZone]=\"{\n dropRegionSize: 100,\n dropPlaceholderSize: 100,\n dropZoneAttributes: {\n 'data-grid': 'main-area',\n 'data-partid': part.id,\n }\n }\"\n [attr.data-grid]=\"'main-area'\"\n class=\"e2e-slot\"/>\n} @else {\n <div wbViewDropZone\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: false, south: false, west: false, east: false}\"\n [wbViewDropZoneAttributes]=\"{\n 'data-desktop': '',\n 'data-partid': part.id,\n }\"\n (wbViewDropZoneDrop)=\"onDesktopViewDrop($event)\"\n class=\"desktop e2e-part-slot e2e-slot\">\n @if (part.navigation()) {\n <ng-container *wbPortalOutlet=\"part.slot.portal; destroyOnDetach: false\"/>\n } @else {\n <ng-container *wbPortalOutlet=\"desktop.slot.portal; destroyOnDetach: false\"/>\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host>wb-grid{flex:auto}:host>div.desktop{flex:auto;display:grid;position:relative}\n"] }]
|
|
8345
8344
|
}] });
|
|
8346
8345
|
|
|
8347
8346
|
/*
|
|
@@ -9723,7 +9722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
9723
9722
|
}] });
|
|
9724
9723
|
|
|
9725
9724
|
/*
|
|
9726
|
-
* Copyright (c) 2018-
|
|
9725
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
9727
9726
|
*
|
|
9728
9727
|
* This program and the accompanying materials are made
|
|
9729
9728
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -9745,7 +9744,8 @@ class WorkbenchDialogComponent {
|
|
|
9745
9744
|
headerHeight = signal(undefined, { ...(ngDevMode ? { debugName: "headerHeight" } : {}) });
|
|
9746
9745
|
transformTranslateX = signal(0, { ...(ngDevMode ? { debugName: "transformTranslateX" } : {}) });
|
|
9747
9746
|
transformTranslateY = signal(0, { ...(ngDevMode ? { debugName: "transformTranslateY" } : {}) });
|
|
9748
|
-
|
|
9747
|
+
slotAnchorName = this.dialog.id.replace('.', '_'); // Anchor must not contain a dot.
|
|
9748
|
+
dialogSlotBounds = viewChild.required('slot_bounds', { read: (ElementRef) });
|
|
9749
9749
|
constructor() {
|
|
9750
9750
|
this.setDialogOffset();
|
|
9751
9751
|
this.trackFocus();
|
|
@@ -9847,7 +9847,7 @@ class WorkbenchDialogComponent {
|
|
|
9847
9847
|
this.focus();
|
|
9848
9848
|
}
|
|
9849
9849
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9850
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchDialogComponent, isStandalone: true, selector: "wb-dialog", host: { listeners: { "keydown.escape": "onEscape($event)" }, properties: { "attr.data-dialogid": "dialog.id", "class.justified": "!dialog.padding()", "style.--\u0275dialog-transform-translate-x": "transformTranslateX()", "style.--\u0275dialog-transform-translate-y": "transformTranslateY()", "style.--\u0275dialog-min-height": "dialog.size.minHeight() ?? headerHeight()", "style.--\u0275dialog-height": "dialog.size.height()", "style.--\u0275dialog-max-height": "dialog.size.maxHeight()", "style.--\u0275dialog-min-width": "dialog.size.minWidth() ?? '100px'", "style.--\u0275dialog-width": "dialog.size.width()", "style.--\u0275dialog-max-width": "dialog.size.maxWidth()", "class": "dialog.cssClass()" } }, viewQueries: [{ propertyName: "_cdkTrapFocus", first: true, predicate: CdkTrapFocus, descendants: true, isSignal: true }, { propertyName: "_dialogElement", first: true, predicate: ["dialog_element"], descendants: true, isSignal: true }, { propertyName: "
|
|
9850
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchDialogComponent, isStandalone: true, selector: "wb-dialog", host: { listeners: { "keydown.escape": "onEscape($event)" }, properties: { "attr.data-dialogid": "dialog.id", "class.justified": "!dialog.padding()", "style.--\u0275dialog-transform-translate-x": "transformTranslateX()", "style.--\u0275dialog-transform-translate-y": "transformTranslateY()", "style.--\u0275dialog-min-height": "dialog.size.minHeight() ?? headerHeight()", "style.--\u0275dialog-height": "dialog.size.height()", "style.--\u0275dialog-max-height": "dialog.size.maxHeight()", "style.--\u0275dialog-min-width": "dialog.size.minWidth() ?? '100px'", "style.--\u0275dialog-width": "dialog.size.width()", "style.--\u0275dialog-max-width": "dialog.size.maxWidth()", "style.--\u0275slot-anchor": "`--${slotAnchorName}`", "class": "dialog.cssClass()" } }, viewQueries: [{ propertyName: "_cdkTrapFocus", first: true, predicate: CdkTrapFocus, descendants: true, isSignal: true }, { propertyName: "_dialogElement", first: true, predicate: ["dialog_element"], descendants: true, isSignal: true }, { propertyName: "dialogSlotBounds", first: true, predicate: ["slot_bounds"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div class=\"dialog e2e-dialog\"\n [class.blinking]=\"dialog.blinking$ | async\"\n [tabindex]=\"-1\"\n wbMovable [wbHandle]=\"header\" (wbMovableMove)=\"onMove($event)\"\n (mousedown)=\"onDialogMouseDown()\"\n wbResizable [wbResizableEnabled]=\"dialog.resizable()\" (wbResizableResize)=\"onResize($event)\"\n @enter\n [@.disabled]=\"!dialog.animate\"\n wbGlassPane\n #dialog_element>\n <div class=\"dialog-box e2e-dialog-box\" cdkTrapFocus>\n <header #header\n class=\"e2e-dialog-header\"\n [class.divider]=\"dialog.header?.divider() ?? true\"\n sciDimension (sciDimensionChange)=\"onHeaderDimensionChange($event)\">\n <ng-container *ngTemplateOutlet=\"dialog.header?.template ?? default_dialog_header\"/>\n </header>\n\n <sci-viewport class=\"e2e-dialog-slot\">\n <ng-container *ngComponentOutlet=\"dialog.component; inputs: dialog.inputs\"/>\n </sci-viewport>\n\n <!-- Extra DIV to capture bounds available to slotted content, excluding viewport content padding. May differ from the actual content size if content overflows or does not fill the slot. -->\n <div class=\"slot-bounds e2e-dialog-slot-bounds\" #slot_bounds></div>\n\n @if (dialog.footer || dialog.actions.length) {\n <footer class=\"e2e-dialog-footer\" [class.divider]=\"dialog.footer?.divider() ?? true\">\n <ng-container *ngTemplateOutlet=\"dialog.footer?.template ?? default_dialog_footer\"/>\n </footer>\n }\n </div>\n</div>\n\n<ng-template #default_dialog_header>\n <wb-dialog-header/>\n</ng-template>\n\n<ng-template #default_dialog_footer>\n <wb-dialog-footer/>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{--\\275 dialog-transform-translate-x: 0;--\\275 dialog-transform-translate-y: 0;--\\275 dialog-min-height: initial;--\\275 dialog-height: initial;--\\275 dialog-max-height: initial;--\\275 dialog-min-width: initial;--\\275 dialog-width: initial;--\\275 dialog-max-width: initial;--\\275 dialog-padding: var(--sci-workbench-dialog-padding)}:host.justified{--\\275 dialog-padding: 0}:host{display:flex;flex-direction:column;align-items:center;position:relative}:host>div.dialog{display:flex;flex-direction:column;position:absolute;top:3%;color:var(--sci-color-text);transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x))) translateY(calc(1px * var(--\\275 dialog-transform-translate-y)));min-height:var(--\\275 dialog-min-height);height:var(--\\275 dialog-height);max-height:var(--\\275 dialog-max-height);min-width:var(--\\275 dialog-min-width);width:var(--\\275 dialog-width);max-width:var(--\\275 dialog-max-width);outline:none;pointer-events:auto}:host>div.dialog>div.dialog-box{flex:auto;display:flex;flex-direction:column;gap:calc(1.25 * var(--\\275 dialog-padding));border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);background-color:var(--sci-color-background-elevation);box-shadow:var(--sci-elevation) var(--sci-static-color-black);overflow:hidden}:host>div.dialog>div.dialog-box>header{flex:none}:host>div.dialog>div.dialog-box>header.divider{border-bottom:1px solid var(--sci-color-border)}:host>div.dialog>div.dialog-box>sci-viewport{flex:auto;anchor-name:var(--\\275slot-anchor)}:host>div.dialog>div.dialog-box>sci-viewport::part(content){padding-inline:var(--\\275 dialog-padding)}:host>div.dialog>div.dialog-box>div.slot-bounds{position:absolute;position-anchor:var(--\\275slot-anchor);inset:anchor(top) anchor(right) anchor(bottom) anchor(left);margin-inline:var(--\\275 dialog-padding);visibility:hidden}:host>div.dialog>div.dialog-box>footer{flex:none}:host>div.dialog>div.dialog-box>footer.divider{border-top:1px solid var(--sci-color-border)}:host>div.dialog.blinking{animation-duration:50ms;animation-iteration-count:infinite;animation-name:blink-animation}@keyframes blink-animation{0%{transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x) - 2px)) translateY(calc(1px * var(--\\275 dialog-transform-translate-y) - 1px))}to{transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x) + 2px)) translateY(calc(1px * var(--\\275 dialog-transform-translate-y) + 1px))}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: MovableDirective, selector: "[wbMovable]", inputs: ["wbHandle"], outputs: ["wbMovableMove"] }, { kind: "directive", type: ResizableDirective, selector: "[wbResizable]", inputs: ["wbResizableEnabled"], outputs: ["wbResizableResize"] }, { kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "directive", type: SciDimensionDirective, selector: "[sciDimension]", inputs: ["emitOutsideAngular"], outputs: ["sciDimensionChange"] }, { kind: "component", type: DialogHeaderComponent, selector: "wb-dialog-header" }, { kind: "component", type: DialogFooterComponent, selector: "wb-dialog-footer" }, { kind: "directive", type: GlassPaneDirective, selector: "[wbGlassPane]" }, { kind: "pipe", type: AsyncPipe, name: "async" }], viewProviders: [
|
|
9851
9851
|
configureDialogGlassPane(),
|
|
9852
9852
|
], animations: [
|
|
9853
9853
|
trigger('enter', provideEnterAnimation()),
|
|
@@ -9882,9 +9882,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
9882
9882
|
'[style.--ɵdialog-min-width]': 'dialog.size.minWidth() ?? \'100px\'',
|
|
9883
9883
|
'[style.--ɵdialog-width]': 'dialog.size.width()',
|
|
9884
9884
|
'[style.--ɵdialog-max-width]': 'dialog.size.maxWidth()',
|
|
9885
|
+
'[style.--ɵslot-anchor]': '`--${slotAnchorName}`',
|
|
9885
9886
|
'[class]': 'dialog.cssClass()',
|
|
9886
|
-
}, template: "<div class=\"dialog e2e-dialog\"\n [class.blinking]=\"dialog.blinking$ | async\"\n [tabindex]=\"-1\"\n wbMovable [wbHandle]=\"header\" (wbMovableMove)=\"onMove($event)\"\n (mousedown)=\"onDialogMouseDown()\"\n wbResizable [wbResizableEnabled]=\"dialog.resizable()\" (wbResizableResize)=\"onResize($event)\"\n @enter\n [@.disabled]=\"!dialog.animate\"\n wbGlassPane\n #dialog_element>\n <div class=\"dialog-box e2e-dialog-box\" cdkTrapFocus>\n <header #header\n class=\"e2e-dialog-header\"\n [class.divider]=\"dialog.header?.divider() ?? true\"\n sciDimension (sciDimensionChange)=\"onHeaderDimensionChange($event)\">\n <ng-container *ngTemplateOutlet=\"dialog.header?.template ?? default_dialog_header\"/>\n </header>\n\n <sci-viewport class=\"
|
|
9887
|
-
}], ctorParameters: () => [], propDecorators: { _cdkTrapFocus: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkTrapFocus), { isSignal: true }] }], _dialogElement: [{ type: i0.ViewChild, args: ['dialog_element', { isSignal: true }] }],
|
|
9887
|
+
}, template: "<div class=\"dialog e2e-dialog\"\n [class.blinking]=\"dialog.blinking$ | async\"\n [tabindex]=\"-1\"\n wbMovable [wbHandle]=\"header\" (wbMovableMove)=\"onMove($event)\"\n (mousedown)=\"onDialogMouseDown()\"\n wbResizable [wbResizableEnabled]=\"dialog.resizable()\" (wbResizableResize)=\"onResize($event)\"\n @enter\n [@.disabled]=\"!dialog.animate\"\n wbGlassPane\n #dialog_element>\n <div class=\"dialog-box e2e-dialog-box\" cdkTrapFocus>\n <header #header\n class=\"e2e-dialog-header\"\n [class.divider]=\"dialog.header?.divider() ?? true\"\n sciDimension (sciDimensionChange)=\"onHeaderDimensionChange($event)\">\n <ng-container *ngTemplateOutlet=\"dialog.header?.template ?? default_dialog_header\"/>\n </header>\n\n <sci-viewport class=\"e2e-dialog-slot\">\n <ng-container *ngComponentOutlet=\"dialog.component; inputs: dialog.inputs\"/>\n </sci-viewport>\n\n <!-- Extra DIV to capture bounds available to slotted content, excluding viewport content padding. May differ from the actual content size if content overflows or does not fill the slot. -->\n <div class=\"slot-bounds e2e-dialog-slot-bounds\" #slot_bounds></div>\n\n @if (dialog.footer || dialog.actions.length) {\n <footer class=\"e2e-dialog-footer\" [class.divider]=\"dialog.footer?.divider() ?? true\">\n <ng-container *ngTemplateOutlet=\"dialog.footer?.template ?? default_dialog_footer\"/>\n </footer>\n }\n </div>\n</div>\n\n<ng-template #default_dialog_header>\n <wb-dialog-header/>\n</ng-template>\n\n<ng-template #default_dialog_footer>\n <wb-dialog-footer/>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{--\\275 dialog-transform-translate-x: 0;--\\275 dialog-transform-translate-y: 0;--\\275 dialog-min-height: initial;--\\275 dialog-height: initial;--\\275 dialog-max-height: initial;--\\275 dialog-min-width: initial;--\\275 dialog-width: initial;--\\275 dialog-max-width: initial;--\\275 dialog-padding: var(--sci-workbench-dialog-padding)}:host.justified{--\\275 dialog-padding: 0}:host{display:flex;flex-direction:column;align-items:center;position:relative}:host>div.dialog{display:flex;flex-direction:column;position:absolute;top:3%;color:var(--sci-color-text);transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x))) translateY(calc(1px * var(--\\275 dialog-transform-translate-y)));min-height:var(--\\275 dialog-min-height);height:var(--\\275 dialog-height);max-height:var(--\\275 dialog-max-height);min-width:var(--\\275 dialog-min-width);width:var(--\\275 dialog-width);max-width:var(--\\275 dialog-max-width);outline:none;pointer-events:auto}:host>div.dialog>div.dialog-box{flex:auto;display:flex;flex-direction:column;gap:calc(1.25 * var(--\\275 dialog-padding));border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);background-color:var(--sci-color-background-elevation);box-shadow:var(--sci-elevation) var(--sci-static-color-black);overflow:hidden}:host>div.dialog>div.dialog-box>header{flex:none}:host>div.dialog>div.dialog-box>header.divider{border-bottom:1px solid var(--sci-color-border)}:host>div.dialog>div.dialog-box>sci-viewport{flex:auto;anchor-name:var(--\\275slot-anchor)}:host>div.dialog>div.dialog-box>sci-viewport::part(content){padding-inline:var(--\\275 dialog-padding)}:host>div.dialog>div.dialog-box>div.slot-bounds{position:absolute;position-anchor:var(--\\275slot-anchor);inset:anchor(top) anchor(right) anchor(bottom) anchor(left);margin-inline:var(--\\275 dialog-padding);visibility:hidden}:host>div.dialog>div.dialog-box>footer{flex:none}:host>div.dialog>div.dialog-box>footer.divider{border-top:1px solid var(--sci-color-border)}:host>div.dialog.blinking{animation-duration:50ms;animation-iteration-count:infinite;animation-name:blink-animation}@keyframes blink-animation{0%{transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x) - 2px)) translateY(calc(1px * var(--\\275 dialog-transform-translate-y) - 1px))}to{transform:translate(calc(1px * var(--\\275 dialog-transform-translate-x) + 2px)) translateY(calc(1px * var(--\\275 dialog-transform-translate-y) + 1px))}}\n"] }]
|
|
9888
|
+
}], ctorParameters: () => [], propDecorators: { _cdkTrapFocus: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkTrapFocus), { isSignal: true }] }], _dialogElement: [{ type: i0.ViewChild, args: ['dialog_element', { isSignal: true }] }], dialogSlotBounds: [{ type: i0.ViewChild, args: ['slot_bounds', { ...{ read: (ElementRef) }, isSignal: true }] }], onEscape: [{
|
|
9888
9889
|
type: HostListener,
|
|
9889
9890
|
args: ['keydown.escape', ['$event']]
|
|
9890
9891
|
}] } });
|
|
@@ -10246,7 +10247,7 @@ class WorkbenchMessageBoxComponent {
|
|
|
10246
10247
|
this.empty.set(!dimension.offsetHeight);
|
|
10247
10248
|
}
|
|
10248
10249
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchMessageBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10249
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchMessageBoxComponent, isStandalone: true, selector: "wb-message-box", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown.escape": "onEscape()" }, properties: { "attr.tabindex": "-1", "class.empty": "empty()", "class.content-selectable": "options()?.contentSelectable", "class.has-title": "!!this.options()?.title" } }, ngImport: i0, template: "@let options = this.options() ?? {};\n<ng-template wbDialogHeader [divider]=\"false\">\n <wb-message-box-header [title]=\"options.title\" [severity]=\"options.severity ?? 'info'\"/>\n</ng-template>\n\n@let message = this.message();\n<div class=\"
|
|
10250
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchMessageBoxComponent, isStandalone: true, selector: "wb-message-box", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown.escape": "onEscape()" }, properties: { "attr.tabindex": "-1", "class.empty": "empty()", "class.content-selectable": "options()?.contentSelectable", "class.has-title": "!!this.options()?.title" } }, ngImport: i0, template: "@let options = this.options() ?? {};\n<ng-template wbDialogHeader [divider]=\"false\">\n <wb-message-box-header [title]=\"options.title\" [severity]=\"options.severity ?? 'info'\"/>\n</ng-template>\n\n@let message = this.message();\n<div class=\"slot e2e-slot\" [class.text]=\"message | wbTypeof:'string'\" sciDimension (sciDimensionChange)=\"onContentDimensionChange($event)\">\n @if (message | wbTypeof:'string') {\n {{($any(message) | wbText)()}}\n } @else {\n <ng-container *ngComponentOutlet=\"message; inputs: options.inputs\"/>\n }\n</div>\n\n<ng-template wbDialogFooter>\n <wb-message-box-footer [actions]=\"options.actions ?? {ok: '%workbench.ok.action'}\"\n [severity]=\"options.severity ?? 'info'\"\n (action)=\"onAction($event)\"\n (keydown.escape)=\"onEscape()\"\n (preferredSizeChange)=\"onFooterPreferredSizeChange($event)\"/>\n</ng-template>\n", styles: [":host{display:grid;outline:none;padding-inline:var(--sci-workbench-messagebox-padding);padding-bottom:var(--sci-workbench-messagebox-padding)}:host.has-title:not(.empty){padding-top:var(--sci-workbench-messagebox-padding)}:host:not(.content-selectable){-webkit-user-select:none;user-select:none}:host>div.slot.text{word-break:break-word;white-space:pre-line;text-align:var(--sci-workbench-messagebox-text-align)}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: SciDimensionDirective, selector: "[sciDimension]", inputs: ["emitOutsideAngular"], outputs: ["sciDimensionChange"] }, { kind: "directive", type: WorkbenchDialogHeaderDirective, selector: "ng-template[wbDialogHeader]", inputs: ["divider"] }, { kind: "directive", type: WorkbenchDialogFooterDirective, selector: "ng-template[wbDialogFooter]", inputs: ["divider"] }, { kind: "component", type: MessageBoxHeaderComponent, selector: "wb-message-box-header", inputs: ["title", "severity"] }, { kind: "component", type: MessageBoxFooterComponent, selector: "wb-message-box-footer", inputs: ["actions", "severity"], outputs: ["action", "preferredSizeChange"] }, { kind: "pipe", type: TypeofPipe, name: "wbTypeof" }, { kind: "pipe", type: TextPipe, name: "wbText" }] });
|
|
10250
10251
|
}
|
|
10251
10252
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchMessageBoxComponent, decorators: [{
|
|
10252
10253
|
type: Component,
|
|
@@ -10266,7 +10267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
10266
10267
|
'[class.content-selectable]': 'options()?.contentSelectable',
|
|
10267
10268
|
'[class.has-title]': '!!this.options()?.title',
|
|
10268
10269
|
'(keydown.escape)': 'onEscape()',
|
|
10269
|
-
}, template: "@let options = this.options() ?? {};\n<ng-template wbDialogHeader [divider]=\"false\">\n <wb-message-box-header [title]=\"options.title\" [severity]=\"options.severity ?? 'info'\"/>\n</ng-template>\n\n@let message = this.message();\n<div class=\"
|
|
10270
|
+
}, template: "@let options = this.options() ?? {};\n<ng-template wbDialogHeader [divider]=\"false\">\n <wb-message-box-header [title]=\"options.title\" [severity]=\"options.severity ?? 'info'\"/>\n</ng-template>\n\n@let message = this.message();\n<div class=\"slot e2e-slot\" [class.text]=\"message | wbTypeof:'string'\" sciDimension (sciDimensionChange)=\"onContentDimensionChange($event)\">\n @if (message | wbTypeof:'string') {\n {{($any(message) | wbText)()}}\n } @else {\n <ng-container *ngComponentOutlet=\"message; inputs: options.inputs\"/>\n }\n</div>\n\n<ng-template wbDialogFooter>\n <wb-message-box-footer [actions]=\"options.actions ?? {ok: '%workbench.ok.action'}\"\n [severity]=\"options.severity ?? 'info'\"\n (action)=\"onAction($event)\"\n (keydown.escape)=\"onEscape()\"\n (preferredSizeChange)=\"onFooterPreferredSizeChange($event)\"/>\n</ng-template>\n", styles: [":host{display:grid;outline:none;padding-inline:var(--sci-workbench-messagebox-padding);padding-bottom:var(--sci-workbench-messagebox-padding)}:host.has-title:not(.empty){padding-top:var(--sci-workbench-messagebox-padding)}:host:not(.content-selectable){-webkit-user-select:none;user-select:none}:host>div.slot.text{word-break:break-word;white-space:pre-line;text-align:var(--sci-workbench-messagebox-text-align)}\n"] }]
|
|
10270
10271
|
}], ctorParameters: () => [], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
|
|
10271
10272
|
function nullIfEmptyMessage(message) {
|
|
10272
10273
|
return message !== '' ? message : null;
|
|
@@ -10923,6 +10924,38 @@ const LEGACY_POPUP_INPUT = new InjectionToken('LEGACY_POPUP_INPUT');
|
|
|
10923
10924
|
*
|
|
10924
10925
|
* SPDX-License-Identifier: EPL-2.0
|
|
10925
10926
|
*/
|
|
10927
|
+
/**
|
|
10928
|
+
* Registry for {@link WorkbenchNotification} elements.
|
|
10929
|
+
*/
|
|
10930
|
+
class WorkbenchNotificationRegistry extends WorkbenchElementRegistry {
|
|
10931
|
+
/**
|
|
10932
|
+
* Gets the most recently opened notification.
|
|
10933
|
+
*/
|
|
10934
|
+
top;
|
|
10935
|
+
constructor() {
|
|
10936
|
+
super({
|
|
10937
|
+
nullElementErrorFn: notificationId => Error(`[NullNotificationError] Notification '${notificationId}' not found.`),
|
|
10938
|
+
onUnregister: notification => notification.destroy(),
|
|
10939
|
+
});
|
|
10940
|
+
this.top = computed(() => this.elements().at(-1), { ...(ngDevMode ? { debugName: "top" } : {}) });
|
|
10941
|
+
}
|
|
10942
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
10943
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationRegistry, providedIn: 'root' });
|
|
10944
|
+
}
|
|
10945
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationRegistry, decorators: [{
|
|
10946
|
+
type: Injectable,
|
|
10947
|
+
args: [{ providedIn: 'root' }]
|
|
10948
|
+
}], ctorParameters: () => [] });
|
|
10949
|
+
|
|
10950
|
+
/*
|
|
10951
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
10952
|
+
*
|
|
10953
|
+
* This program and the accompanying materials are made
|
|
10954
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
10955
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
10956
|
+
*
|
|
10957
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
10958
|
+
*/
|
|
10926
10959
|
/**
|
|
10927
10960
|
* Creates the invocation context for given element.
|
|
10928
10961
|
*
|
|
@@ -10978,6 +11011,16 @@ function createInvocationContext(elementId, options) {
|
|
|
10978
11011
|
peripheral: signal(false),
|
|
10979
11012
|
};
|
|
10980
11013
|
}
|
|
11014
|
+
else if (isNotificationId(contextualElementId)) {
|
|
11015
|
+
const notification = injector.get(WorkbenchNotificationRegistry).get(contextualElementId);
|
|
11016
|
+
return {
|
|
11017
|
+
elementId: notification.id,
|
|
11018
|
+
attached: computed(() => !notification.destroyed()),
|
|
11019
|
+
bounds: notification.bounds,
|
|
11020
|
+
destroyed: notification.destroyed,
|
|
11021
|
+
peripheral: signal(true),
|
|
11022
|
+
};
|
|
11023
|
+
}
|
|
10981
11024
|
return null;
|
|
10982
11025
|
}
|
|
10983
11026
|
|
|
@@ -11175,7 +11218,7 @@ function provideWorkbenchDialogContext() {
|
|
|
11175
11218
|
}
|
|
11176
11219
|
|
|
11177
11220
|
/*
|
|
11178
|
-
* Copyright (c) 2018-
|
|
11221
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
11179
11222
|
*
|
|
11180
11223
|
* This program and the accompanying materials are made
|
|
11181
11224
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -11210,7 +11253,7 @@ class ɵWorkbenchDialog {
|
|
|
11210
11253
|
focused = computed(() => this._focusMonitor.activeElement()?.id === this.id, { ...(ngDevMode ? { debugName: "focused" } : {}) });
|
|
11211
11254
|
attached;
|
|
11212
11255
|
destroyed = signal(false, { ...(ngDevMode ? { debugName: "destroyed" } : {}) });
|
|
11213
|
-
bounds = boundingClientRect(computed(() => this._componentRef()?.instance.
|
|
11256
|
+
bounds = boundingClientRect(computed(() => this._componentRef()?.instance.dialogSlotBounds()));
|
|
11214
11257
|
modal;
|
|
11215
11258
|
blinking$ = new BehaviorSubject(false);
|
|
11216
11259
|
header;
|
|
@@ -13680,7 +13723,7 @@ class PartComponent {
|
|
|
13680
13723
|
inject(DestroyRef).onDestroy(() => logger.debug(() => `Destroying PartComponent [partId=${this.part.id}]'`, LoggerNames.LIFECYCLE));
|
|
13681
13724
|
}
|
|
13682
13725
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13683
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: PartComponent, isStandalone: true, selector: "wb-part", host: { properties: { "attr.data-partid": "part.id", "attr.data-peripheral": "part.peripheral() ? '' : null", "attr.data-grid": "dasherize(part.gridName())", "attr.data-active": "part.active() ? '' : null", "attr.data-referencepart": "part.referencePart() ? '' : null", "attr.tabindex": "-1", "class": "part.classList.asList()" } }, ngImport: i0, template: "@if (part.title() || part.views().length || part.actions().length || part.canMinimize()) {\n <wb-part-bar/>\n}\n\n@if (part.views().length) {\n <!-- Prevent splitting if there is no active view, i.e, when dragging the last view out of the tabbar. -->\n @let canSplit = !!part.activeView();\n <div wbViewDropZone\n [wbViewDropZoneRegionSize]=\".25\"\n [wbViewDropZonePlaceholderSize]=\".5\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: canSplit, south: canSplit, west: canSplit, east: canSplit}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"
|
|
13726
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: PartComponent, isStandalone: true, selector: "wb-part", host: { properties: { "attr.data-partid": "part.id", "attr.data-peripheral": "part.peripheral() ? '' : null", "attr.data-grid": "dasherize(part.gridName())", "attr.data-active": "part.active() ? '' : null", "attr.data-referencepart": "part.referencePart() ? '' : null", "attr.tabindex": "-1", "class": "part.classList.asList()" } }, ngImport: i0, template: "@if (part.title() || part.views().length || part.actions().length || part.canMinimize()) {\n <wb-part-bar/>\n}\n\n@if (part.views().length) {\n <!-- Prevent splitting if there is no active view, i.e, when dragging the last view out of the tabbar. -->\n @let canSplit = !!part.activeView();\n <div wbViewDropZone\n [wbViewDropZoneRegionSize]=\".25\"\n [wbViewDropZonePlaceholderSize]=\".5\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: canSplit, south: canSplit, west: canSplit, east: canSplit}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"slot e2e-slot e2e-view-slot\">\n <ng-container *wbPortalOutlet=\"part.activeView()?.slot!.portal; destroyOnDetach: false\"/>\n </div>\n} @else {\n <div wbViewDropZone\n [wbViewDropZoneRegions]=\"canDrop() && {center: false, north: true, south: true, west: true, east: true}\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"slot e2e-slot e2e-part-slot\">\n <ng-container *wbPortalOutlet=\"part.slot.portal; destroyOnDetach: false\"/>\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;outline:none;background-color:var(--sci-workbench-part-background-color);overflow:hidden}:host[data-peripheral]{background-color:var(--sci-workbench-part-peripheral-background-color)}:host>wb-part-bar{flex:none}:host>div.slot{flex:auto;display:grid;position:relative}\n"], dependencies: [{ kind: "component", type: PartBarComponent, selector: "wb-part-bar" }, { kind: "directive", type: ViewDropZoneDirective, selector: "[wbViewDropZone]", inputs: ["wbViewDropZoneRegions", "wbViewDropZoneAttributes", "wbViewDropZoneRegionSize", "wbViewDropZonePlaceholderSize"], outputs: ["wbViewDropZoneDrop"] }, { kind: "directive", type: WorkbenchPortalOutletDirective, selector: "ng-template[wbPortalOutlet]", inputs: ["wbPortalOutlet", "wbPortalOutletDestroyOnDetach"] }] });
|
|
13684
13727
|
}
|
|
13685
13728
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PartComponent, decorators: [{
|
|
13686
13729
|
type: Component,
|
|
@@ -13696,7 +13739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
13696
13739
|
'[attr.data-referencepart]': `part.referencePart() ? '' : null`,
|
|
13697
13740
|
'[attr.tabindex]': '-1',
|
|
13698
13741
|
'[class]': 'part.classList.asList()',
|
|
13699
|
-
}, template: "@if (part.title() || part.views().length || part.actions().length || part.canMinimize()) {\n <wb-part-bar/>\n}\n\n@if (part.views().length) {\n <!-- Prevent splitting if there is no active view, i.e, when dragging the last view out of the tabbar. -->\n @let canSplit = !!part.activeView();\n <div wbViewDropZone\n [wbViewDropZoneRegionSize]=\".25\"\n [wbViewDropZonePlaceholderSize]=\".5\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: canSplit, south: canSplit, west: canSplit, east: canSplit}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"
|
|
13742
|
+
}, template: "@if (part.title() || part.views().length || part.actions().length || part.canMinimize()) {\n <wb-part-bar/>\n}\n\n@if (part.views().length) {\n <!-- Prevent splitting if there is no active view, i.e, when dragging the last view out of the tabbar. -->\n @let canSplit = !!part.activeView();\n <div wbViewDropZone\n [wbViewDropZoneRegionSize]=\".25\"\n [wbViewDropZonePlaceholderSize]=\".5\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n [wbViewDropZoneRegions]=\"canDrop() && {center: true, north: canSplit, south: canSplit, west: canSplit, east: canSplit}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"slot e2e-slot e2e-view-slot\">\n <ng-container *wbPortalOutlet=\"part.activeView()?.slot!.portal; destroyOnDetach: false\"/>\n </div>\n} @else {\n <div wbViewDropZone\n [wbViewDropZoneRegions]=\"canDrop() && {center: false, north: true, south: true, west: true, east: true}\"\n [wbViewDropZoneAttributes]=\"{'data-partid': part.id}\"\n (wbViewDropZoneDrop)=\"onViewDrop($event)\"\n class=\"slot e2e-slot e2e-part-slot\">\n <ng-container *wbPortalOutlet=\"part.slot.portal; destroyOnDetach: false\"/>\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;outline:none;background-color:var(--sci-workbench-part-background-color);overflow:hidden}:host[data-peripheral]{background-color:var(--sci-workbench-part-peripheral-background-color)}:host>wb-part-bar{flex:none}:host>div.slot{flex:auto;display:grid;position:relative}\n"] }]
|
|
13700
13743
|
}], ctorParameters: () => [] });
|
|
13701
13744
|
|
|
13702
13745
|
/*
|
|
@@ -17815,27 +17858,183 @@ class Notification {
|
|
|
17815
17858
|
* SPDX-License-Identifier: EPL-2.0
|
|
17816
17859
|
*/
|
|
17817
17860
|
/**
|
|
17818
|
-
*
|
|
17861
|
+
* TODO [Angular 22] Remove with Angular 22. Used for backward compatiblity.
|
|
17819
17862
|
*/
|
|
17820
|
-
class
|
|
17863
|
+
class RemoveLegacyInputPipe {
|
|
17864
|
+
transform(inputs) {
|
|
17865
|
+
const inputsCopy = { ...inputs ?? {} };
|
|
17866
|
+
delete inputsCopy[LEGACY_NOTIFICATION_INPUT]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
|
|
17867
|
+
return inputsCopy;
|
|
17868
|
+
}
|
|
17869
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
17870
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, isStandalone: true, name: "wbRemoveLegacyInput" });
|
|
17871
|
+
}
|
|
17872
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, decorators: [{
|
|
17873
|
+
type: Pipe,
|
|
17874
|
+
args: [{ name: 'wbRemoveLegacyInput' }]
|
|
17875
|
+
}] });
|
|
17876
|
+
|
|
17877
|
+
/*
|
|
17878
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
17879
|
+
*
|
|
17880
|
+
* This program and the accompanying materials are made
|
|
17881
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
17882
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
17883
|
+
*
|
|
17884
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
17885
|
+
*/
|
|
17886
|
+
/**
|
|
17887
|
+
* Renders the content of a workbench notification.
|
|
17888
|
+
*/
|
|
17889
|
+
class WorkbenchNotificationComponent {
|
|
17890
|
+
notification = inject(ɵWorkbenchNotification);
|
|
17891
|
+
hover = signal(false, { ...(ngDevMode ? { debugName: "hover" } : {}) });
|
|
17892
|
+
slotAnchorName = this.notification.id.replace('.', '_'); // Anchor must not contain a dot.
|
|
17893
|
+
notificationSlotBounds = viewChild('slot_bounds', { ...(ngDevMode ? { debugName: "notificationSlotBounds" } : {}), read: (ElementRef) });
|
|
17894
|
+
constructor() {
|
|
17895
|
+
this.installAutoCloseTimer();
|
|
17896
|
+
this.closeOnEscapeIfOnTop();
|
|
17897
|
+
trackFocus(inject(ElementRef).nativeElement, this.notification);
|
|
17898
|
+
}
|
|
17899
|
+
onClose() {
|
|
17900
|
+
this.notification.close();
|
|
17901
|
+
}
|
|
17902
|
+
onEscape(event) {
|
|
17903
|
+
if (this.notification.focused()) {
|
|
17904
|
+
event.stopPropagation(); // stop propagation to prevent closing the most recently displayed notification
|
|
17905
|
+
this.notification.close();
|
|
17906
|
+
}
|
|
17907
|
+
}
|
|
17908
|
+
onAuxClick(event) {
|
|
17909
|
+
if (event.button === 1) { // primary aux button
|
|
17910
|
+
event.preventDefault(); // prevent user-agent default action
|
|
17911
|
+
this.notification.close();
|
|
17912
|
+
}
|
|
17913
|
+
}
|
|
17821
17914
|
/**
|
|
17822
|
-
*
|
|
17915
|
+
* Closes this notification when pressing escape if it is the most recently displayed notification.
|
|
17823
17916
|
*/
|
|
17824
|
-
|
|
17825
|
-
|
|
17826
|
-
|
|
17827
|
-
|
|
17828
|
-
|
|
17917
|
+
closeOnEscapeIfOnTop() {
|
|
17918
|
+
const zone = inject(NgZone);
|
|
17919
|
+
const document = inject(DOCUMENT);
|
|
17920
|
+
effect(onCleanup => {
|
|
17921
|
+
if (!this.notification.top()) {
|
|
17922
|
+
return;
|
|
17923
|
+
}
|
|
17924
|
+
const subscription = fromEvent(document, 'keydown')
|
|
17925
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), filter((event) => event.key === 'Escape'), observeIn(fn => zone.run(fn)))
|
|
17926
|
+
.subscribe(() => this.notification.close());
|
|
17927
|
+
onCleanup(() => subscription.unsubscribe());
|
|
17829
17928
|
});
|
|
17830
|
-
this.top = computed(() => this.elements().at(-1), { ...(ngDevMode ? { debugName: "top" } : {}) });
|
|
17831
17929
|
}
|
|
17832
|
-
|
|
17833
|
-
|
|
17930
|
+
/**
|
|
17931
|
+
* Installs a timer to close the notification.
|
|
17932
|
+
*/
|
|
17933
|
+
installAutoCloseTimer() {
|
|
17934
|
+
effect(onCleanup => {
|
|
17935
|
+
const duration = this.notification.duration();
|
|
17936
|
+
const focus = this.notification.focused();
|
|
17937
|
+
const blockedBy = this.notification.blockedBy();
|
|
17938
|
+
const hover = this.hover();
|
|
17939
|
+
if (hover || focus || blockedBy) {
|
|
17940
|
+
return;
|
|
17941
|
+
}
|
|
17942
|
+
untracked(() => {
|
|
17943
|
+
const subscription = fromDuration$(duration).subscribe(() => this.notification.close());
|
|
17944
|
+
onCleanup(() => subscription.unsubscribe());
|
|
17945
|
+
});
|
|
17946
|
+
});
|
|
17947
|
+
function fromDuration$(duration) {
|
|
17948
|
+
switch (duration) {
|
|
17949
|
+
case 'short':
|
|
17950
|
+
return timer(7000);
|
|
17951
|
+
case 'medium':
|
|
17952
|
+
return timer(15000);
|
|
17953
|
+
case 'long':
|
|
17954
|
+
return timer(30000);
|
|
17955
|
+
default:
|
|
17956
|
+
if (typeof duration === 'number') {
|
|
17957
|
+
return timer(duration);
|
|
17958
|
+
}
|
|
17959
|
+
return NEVER;
|
|
17960
|
+
}
|
|
17961
|
+
}
|
|
17962
|
+
}
|
|
17963
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17964
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchNotificationComponent, isStandalone: true, selector: "wb-notification", host: { listeners: { "mouseenter": "hover.set(true)", "mouseleave": "hover.set(false)", "auxclick": "onAuxClick($event)", "keydown.escape": "onEscape($event)" }, properties: { "attr.data-notificationid": "notification.id", "attr.data-severity": "notification.severity()", "style.min-height": "notification.size.minHeight()", "style.height": "notification.size.height()", "style.max-height": "notification.size.maxHeight()", "style.--\u0275slot-anchor": "`--${slotAnchorName}`", "attr.tabindex": "-1", "class": "notification.cssClass()" } }, providers: [
|
|
17965
|
+
configureNotificationGlassPane(),
|
|
17966
|
+
], viewQueries: [{ propertyName: "notificationSlotBounds", first: true, predicate: ["slot_bounds"], descendants: true, read: ElementRef, isSignal: true }], hostDirectives: [{ directive: GlassPaneDirective }], ngImport: i0, template: "<!-- Title -->\n@if (notification.title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n}\n\n<!-- Message -->\n<div class=\"slot e2e-slot\" [class.text]=\"!!notification.slot.text?.length\">\n @if (notification.slot.text?.length) {\n {{(notification.slot.text | wbText)()}}\n } @else if (notification.slot.component) {\n <sci-viewport class=\"e2e-notification-slot\">\n <ng-container *ngComponentOutlet=\"notification.slot.component; inputs: notification.inputs | wbRemoveLegacyInput;\"/>\n </sci-viewport>\n\n <!-- Extra DIV to capture bounds available to slotted content, excluding viewport content padding. May differ from the actual content size if content overflows or does not fill the slot. -->\n <div class=\"slot-bounds e2e-notification-slot-bounds\" #slot_bounds></div>\n }\n</div>\n\n<button (click)=\"onClose()\"\n [title]=\"('%workbench.close.tooltip' | wbText)()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:.75em;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:.9em;border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);padding:1em 0;overflow:hidden;outline:none;position:relative}:host:before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:var(--sci-workbench-notification-severity-indicator-size)}:host[data-severity=info]:before{background-color:var(--sci-color-accent)}:host[data-severity=warn]:before{background-color:var(--sci-color-notice)}:host[data-severity=error]:before{background-color:var(--sci-color-negative)}:host>header{flex:none;font-weight:700;padding:0 var(--sci-workbench-notification-padding);word-break:break-word;white-space:pre-line}:host>div.slot{flex:auto;overflow:hidden;display:grid}:host>div.slot.text{word-break:break-word;white-space:pre-line;padding:0 var(--sci-workbench-notification-padding)}:host>div.slot>sci-viewport{anchor-name:var(--\\275slot-anchor)}:host>div.slot>sci-viewport::part(content){padding-inline:var(--sci-workbench-notification-padding)}:host>div.slot>div.slot-bounds{position:absolute;position-anchor:var(--\\275slot-anchor);inset:anchor(top) anchor(right) anchor(bottom) anchor(left);margin-inline:var(--sci-workbench-notification-padding);visibility:hidden}:host>button.close:is(button,#sci-reset){all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-corner);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-workbench-button-cursor)}:host>button.close:is(button,#sci-reset):hover:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-hover)}:host>button.close:is(button,#sci-reset):active:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-active)}:host>button.close:is(button,#sci-reset):focus:not(:focus-visible){outline:none}:host>button.close:is(button,#sci-reset):focus-visible{outline:var(--sci-workbench-button-outline-width-focus) solid var(--sci-color-accent)}:host>button.close:is(button,#sci-reset):disabled{color:var(--sci-color-gray-500)}:host>button.close:is(button,#sci-reset){position:absolute;top:.275em;right:.275em;padding:.125em;border-radius:var(--sci-corner-small);font-size:1rem}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "wb-icon", inputs: ["icon"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "pipe", type: TextPipe, name: "wbText" }, { kind: "pipe", type: RemoveLegacyInputPipe, name: "wbRemoveLegacyInput" }] });
|
|
17967
|
+
}
|
|
17968
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, decorators: [{
|
|
17969
|
+
type: Component,
|
|
17970
|
+
args: [{ selector: 'wb-notification', imports: [
|
|
17971
|
+
TextPipe,
|
|
17972
|
+
IconComponent,
|
|
17973
|
+
NgComponentOutlet,
|
|
17974
|
+
RemoveLegacyInputPipe,
|
|
17975
|
+
SciViewportComponent,
|
|
17976
|
+
], hostDirectives: [
|
|
17977
|
+
GlassPaneDirective,
|
|
17978
|
+
], providers: [
|
|
17979
|
+
configureNotificationGlassPane(),
|
|
17980
|
+
], host: {
|
|
17981
|
+
'[attr.data-notificationid]': 'notification.id',
|
|
17982
|
+
'[attr.data-severity]': 'notification.severity()',
|
|
17983
|
+
'[style.min-height]': 'notification.size.minHeight()',
|
|
17984
|
+
'[style.height]': 'notification.size.height()',
|
|
17985
|
+
'[style.max-height]': 'notification.size.maxHeight()',
|
|
17986
|
+
'[style.--ɵslot-anchor]': '`--${slotAnchorName}`',
|
|
17987
|
+
'[attr.tabindex]': '-1',
|
|
17988
|
+
'[class]': 'notification.cssClass()',
|
|
17989
|
+
'(mouseenter)': 'hover.set(true)',
|
|
17990
|
+
'(mouseleave)': 'hover.set(false)',
|
|
17991
|
+
'(auxclick)': 'onAuxClick($event)',
|
|
17992
|
+
'(keydown.escape)': 'onEscape($event)',
|
|
17993
|
+
}, template: "<!-- Title -->\n@if (notification.title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n}\n\n<!-- Message -->\n<div class=\"slot e2e-slot\" [class.text]=\"!!notification.slot.text?.length\">\n @if (notification.slot.text?.length) {\n {{(notification.slot.text | wbText)()}}\n } @else if (notification.slot.component) {\n <sci-viewport class=\"e2e-notification-slot\">\n <ng-container *ngComponentOutlet=\"notification.slot.component; inputs: notification.inputs | wbRemoveLegacyInput;\"/>\n </sci-viewport>\n\n <!-- Extra DIV to capture bounds available to slotted content, excluding viewport content padding. May differ from the actual content size if content overflows or does not fill the slot. -->\n <div class=\"slot-bounds e2e-notification-slot-bounds\" #slot_bounds></div>\n }\n</div>\n\n<button (click)=\"onClose()\"\n [title]=\"('%workbench.close.tooltip' | wbText)()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:.75em;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:.9em;border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);padding:1em 0;overflow:hidden;outline:none;position:relative}:host:before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:var(--sci-workbench-notification-severity-indicator-size)}:host[data-severity=info]:before{background-color:var(--sci-color-accent)}:host[data-severity=warn]:before{background-color:var(--sci-color-notice)}:host[data-severity=error]:before{background-color:var(--sci-color-negative)}:host>header{flex:none;font-weight:700;padding:0 var(--sci-workbench-notification-padding);word-break:break-word;white-space:pre-line}:host>div.slot{flex:auto;overflow:hidden;display:grid}:host>div.slot.text{word-break:break-word;white-space:pre-line;padding:0 var(--sci-workbench-notification-padding)}:host>div.slot>sci-viewport{anchor-name:var(--\\275slot-anchor)}:host>div.slot>sci-viewport::part(content){padding-inline:var(--sci-workbench-notification-padding)}:host>div.slot>div.slot-bounds{position:absolute;position-anchor:var(--\\275slot-anchor);inset:anchor(top) anchor(right) anchor(bottom) anchor(left);margin-inline:var(--sci-workbench-notification-padding);visibility:hidden}:host>button.close:is(button,#sci-reset){all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-corner);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-workbench-button-cursor)}:host>button.close:is(button,#sci-reset):hover:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-hover)}:host>button.close:is(button,#sci-reset):active:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-active)}:host>button.close:is(button,#sci-reset):focus:not(:focus-visible){outline:none}:host>button.close:is(button,#sci-reset):focus-visible{outline:var(--sci-workbench-button-outline-width-focus) solid var(--sci-color-accent)}:host>button.close:is(button,#sci-reset):disabled{color:var(--sci-color-gray-500)}:host>button.close:is(button,#sci-reset){position:absolute;top:.275em;right:.275em;padding:.125em;border-radius:var(--sci-corner-small);font-size:1rem}\n"] }]
|
|
17994
|
+
}], ctorParameters: () => [], propDecorators: { notificationSlotBounds: [{ type: i0.ViewChild, args: ['slot_bounds', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
|
|
17995
|
+
/**
|
|
17996
|
+
* Blocks this notification when dialog(s) overlay it.
|
|
17997
|
+
*/
|
|
17998
|
+
function configureNotificationGlassPane() {
|
|
17999
|
+
return [
|
|
18000
|
+
{
|
|
18001
|
+
provide: GLASS_PANE_BLOCKABLE,
|
|
18002
|
+
useFactory: () => inject(ɵWorkbenchNotification),
|
|
18003
|
+
},
|
|
18004
|
+
{
|
|
18005
|
+
provide: GLASS_PANE_OPTIONS,
|
|
18006
|
+
useFactory: () => ({ attributes: { 'data-notificationid': inject(ɵWorkbenchNotification).id } }),
|
|
18007
|
+
},
|
|
18008
|
+
];
|
|
18009
|
+
}
|
|
18010
|
+
|
|
18011
|
+
/*
|
|
18012
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
18013
|
+
*
|
|
18014
|
+
* This program and the accompanying materials are made
|
|
18015
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
18016
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
18017
|
+
*
|
|
18018
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
18019
|
+
*/
|
|
18020
|
+
/**
|
|
18021
|
+
* DI token to register providers available for DI if in the context of a workbench notification.
|
|
18022
|
+
*/
|
|
18023
|
+
const WORKBENCH_NOTIFICATION_CONTEXT = new InjectionToken('WORKBENCH_NOTIFICATION_CONTEXT');
|
|
18024
|
+
/**
|
|
18025
|
+
* Provides providers available for DI if in the context of a workbench notification.
|
|
18026
|
+
*/
|
|
18027
|
+
function provideWorkbenchNotificationContext() {
|
|
18028
|
+
return {
|
|
18029
|
+
provide: WORKBENCH_NOTIFICATION_CONTEXT,
|
|
18030
|
+
useFactory: () => [
|
|
18031
|
+
provideWorkbenchDialogService(),
|
|
18032
|
+
provideWorkbenchMessageBoxService(),
|
|
18033
|
+
provideWorkbenchPopupService(),
|
|
18034
|
+
],
|
|
18035
|
+
multi: true,
|
|
18036
|
+
};
|
|
17834
18037
|
}
|
|
17835
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationRegistry, decorators: [{
|
|
17836
|
-
type: Injectable,
|
|
17837
|
-
args: [{ providedIn: 'root' }]
|
|
17838
|
-
}], ctorParameters: () => [] });
|
|
17839
18038
|
|
|
17840
18039
|
/** @inheritDoc */
|
|
17841
18040
|
class ɵWorkbenchNotification {
|
|
@@ -17850,17 +18049,20 @@ class ɵWorkbenchNotification {
|
|
|
17850
18049
|
_severity;
|
|
17851
18050
|
_duration;
|
|
17852
18051
|
_cssClass;
|
|
18052
|
+
portal;
|
|
17853
18053
|
size = new ɵWorkbenchNotificationSize();
|
|
17854
18054
|
focused = computed(() => this._focusMonitor.activeElement()?.id === this.id, { ...(ngDevMode ? { debugName: "focused" } : {}) });
|
|
17855
18055
|
/** Checks if this notification is the most recently displayed notification. */
|
|
17856
18056
|
top = computed(() => this._notificationRegistry.top() === this, { ...(ngDevMode ? { debugName: "top" } : {}) });
|
|
17857
18057
|
destroyed = signal(false, { ...(ngDevMode ? { debugName: "destroyed" } : {}) });
|
|
18058
|
+
bounds;
|
|
18059
|
+
blockedBy;
|
|
17858
18060
|
group;
|
|
17859
18061
|
constructor(id, content, _options) {
|
|
17860
18062
|
this.id = id;
|
|
17861
18063
|
this._options = _options;
|
|
18064
|
+
this.portal = this.createPortal();
|
|
17862
18065
|
this.slot = {
|
|
17863
|
-
injector: this.createInjector(),
|
|
17864
18066
|
component: typeof content === 'function' ? content : undefined,
|
|
17865
18067
|
text: typeof content === 'string' ? content : undefined,
|
|
17866
18068
|
};
|
|
@@ -17869,24 +18071,25 @@ class ɵWorkbenchNotification {
|
|
|
17869
18071
|
this._duration = signal(this._options.duration ?? 'medium', { ...(ngDevMode ? { debugName: "_duration" } : {}) });
|
|
17870
18072
|
this._cssClass = signal(Arrays.coerce(this._options.cssClass), { ...(ngDevMode ? { debugName: "_cssClass" } : {}) });
|
|
17871
18073
|
this.group = this._options.group;
|
|
18074
|
+
this.blockedBy = inject(WorkbenchDialogRegistry).top(this.id);
|
|
18075
|
+
this.bounds = boundingClientRect(computed(() => this.portal.componentRef()?.instance.notificationSlotBounds()));
|
|
17872
18076
|
inject(DestroyRef).onDestroy(() => this.destroyed.set(true));
|
|
17873
18077
|
}
|
|
17874
18078
|
/**
|
|
17875
|
-
* Creates
|
|
18079
|
+
* Creates a portal to render {@link WorkbenchNotificationComponent} in the notification's injection context.
|
|
17876
18080
|
*/
|
|
17877
|
-
|
|
17878
|
-
|
|
17879
|
-
|
|
18081
|
+
createPortal() {
|
|
18082
|
+
return new WbComponentPortal(WorkbenchNotificationComponent, {
|
|
18083
|
+
injector: this._options.injector,
|
|
17880
18084
|
providers: [
|
|
17881
18085
|
{ provide: ɵWorkbenchNotification, useValue: this },
|
|
17882
18086
|
{ provide: WorkbenchNotification, useExisting: ɵWorkbenchNotification },
|
|
17883
18087
|
{ provide: Notification, useClass: ɵNotification },
|
|
17884
18088
|
{ provide: WORKBENCH_ELEMENT, useExisting: ɵWorkbenchNotification },
|
|
18089
|
+
inject(WORKBENCH_NOTIFICATION_CONTEXT, { optional: true }) ?? [],
|
|
17885
18090
|
...this._options.providers ?? [],
|
|
17886
18091
|
],
|
|
17887
18092
|
});
|
|
17888
|
-
inject(DestroyRef).onDestroy(() => injector.destroy());
|
|
17889
|
-
return injector;
|
|
17890
18093
|
}
|
|
17891
18094
|
/** @inheritDoc */
|
|
17892
18095
|
get title() {
|
|
@@ -17922,6 +18125,9 @@ class ɵWorkbenchNotification {
|
|
|
17922
18125
|
}
|
|
17923
18126
|
/** @inheritDoc */
|
|
17924
18127
|
close() {
|
|
18128
|
+
if (this.blockedBy()) {
|
|
18129
|
+
return;
|
|
18130
|
+
}
|
|
17925
18131
|
this.destroy();
|
|
17926
18132
|
}
|
|
17927
18133
|
/**
|
|
@@ -18434,6 +18640,7 @@ function provideMicrofrontendNotification() {
|
|
|
18434
18640
|
MicrofrontendNotificationCapabilityValidator,
|
|
18435
18641
|
MicrofrontendTextNotificationCapabilityProvider,
|
|
18436
18642
|
MicrofrontendNotificationIntentHandler,
|
|
18643
|
+
provideWorkbenchNotificationContext(),
|
|
18437
18644
|
provideMicrofrontendTextNotificationRoute(),
|
|
18438
18645
|
provideMicrofrontendPlatformInitializer(onPreStartup, { phase: MicrofrontendPlatformStartupPhase.PreStartup }),
|
|
18439
18646
|
]);
|
|
@@ -18445,6 +18652,20 @@ function provideMicrofrontendNotification() {
|
|
|
18445
18652
|
// Register notification intent handler.
|
|
18446
18653
|
Beans.register(IntentInterceptor, { useValue: inject(MicrofrontendNotificationIntentHandler), multi: true });
|
|
18447
18654
|
}
|
|
18655
|
+
/**
|
|
18656
|
+
* Provides beans of @scion/workbench-client available for DI if in the context of a workbench notification.
|
|
18657
|
+
*/
|
|
18658
|
+
function provideWorkbenchNotificationContext() {
|
|
18659
|
+
return {
|
|
18660
|
+
provide: WORKBENCH_NOTIFICATION_CONTEXT,
|
|
18661
|
+
useFactory: () => [
|
|
18662
|
+
{ provide: WorkbenchDialogService$1, useFactory: () => new _WorkbenchDialogService(inject(WorkbenchNotification).id) },
|
|
18663
|
+
{ provide: WorkbenchMessageBoxService$1, useFactory: () => new _WorkbenchMessageBoxService(inject(WorkbenchNotification).id) },
|
|
18664
|
+
{ provide: WorkbenchPopupService$1, useFactory: () => new _WorkbenchPopupService(inject(WorkbenchNotification).id) },
|
|
18665
|
+
],
|
|
18666
|
+
multi: true,
|
|
18667
|
+
};
|
|
18668
|
+
}
|
|
18448
18669
|
}
|
|
18449
18670
|
|
|
18450
18671
|
/*
|
|
@@ -20291,6 +20512,7 @@ function provideWorkbench(config) {
|
|
|
20291
20512
|
provideWorkbenchViewContext(),
|
|
20292
20513
|
provideWorkbenchDialogContext(),
|
|
20293
20514
|
provideWorkbenchPopupContext(),
|
|
20515
|
+
provideWorkbenchNotificationContext(),
|
|
20294
20516
|
provideWorkbenchMicrofrontendSupport(config),
|
|
20295
20517
|
]);
|
|
20296
20518
|
}
|
|
@@ -20384,32 +20606,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
20384
20606
|
args: [{ selector: 'wb-splash', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SciThrobberComponent], template: "<sci-throbber type=\"ellipsis\"/>\n", styles: [":host{display:grid;justify-content:center;margin-top:3em}:host>sci-throbber{--sci-throbber-size: 80px}\n"] }]
|
|
20385
20607
|
}] });
|
|
20386
20608
|
|
|
20387
|
-
/*
|
|
20388
|
-
* Copyright (c) 2018-2025 Swiss Federal Railways
|
|
20389
|
-
*
|
|
20390
|
-
* This program and the accompanying materials are made
|
|
20391
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
20392
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
20393
|
-
*
|
|
20394
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
20395
|
-
*/
|
|
20396
|
-
/**
|
|
20397
|
-
* TODO [Angular 22] Remove with Angular 22. Used for backward compatiblity.
|
|
20398
|
-
*/
|
|
20399
|
-
class RemoveLegacyInputPipe {
|
|
20400
|
-
transform(inputs) {
|
|
20401
|
-
const inputsCopy = { ...inputs ?? {} };
|
|
20402
|
-
delete inputsCopy[LEGACY_NOTIFICATION_INPUT]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
|
|
20403
|
-
return inputsCopy;
|
|
20404
|
-
}
|
|
20405
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
20406
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, isStandalone: true, name: "wbRemoveLegacyInput" });
|
|
20407
|
-
}
|
|
20408
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, decorators: [{
|
|
20409
|
-
type: Pipe,
|
|
20410
|
-
args: [{ name: 'wbRemoveLegacyInput' }]
|
|
20411
|
-
}] });
|
|
20412
|
-
|
|
20413
20609
|
/*
|
|
20414
20610
|
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
20415
20611
|
*
|
|
@@ -20419,140 +20615,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
20419
20615
|
*
|
|
20420
20616
|
* SPDX-License-Identifier: EPL-2.0
|
|
20421
20617
|
*/
|
|
20422
|
-
/**
|
|
20423
|
-
* Renders the content of a workbench notification.
|
|
20424
|
-
*/
|
|
20425
|
-
class WorkbenchNotificationComponent {
|
|
20426
|
-
notification = input.required({ ...(ngDevMode ? { debugName: "notification" } : {}) });
|
|
20427
|
-
hover = signal(false, { ...(ngDevMode ? { debugName: "hover" } : {}) });
|
|
20428
|
-
constructor() {
|
|
20429
|
-
this.installAutoCloseTimer();
|
|
20430
|
-
this.installFocusTracker();
|
|
20431
|
-
this.closeOnEscapeIfOnTop();
|
|
20432
|
-
}
|
|
20433
|
-
onClose() {
|
|
20434
|
-
this.notification().close();
|
|
20435
|
-
}
|
|
20436
|
-
onEscape(event) {
|
|
20437
|
-
if (this.notification().focused()) {
|
|
20438
|
-
event.stopPropagation(); // stop propagation to prevent closing the most recently displayed notification
|
|
20439
|
-
this.notification().close();
|
|
20440
|
-
}
|
|
20441
|
-
}
|
|
20442
|
-
onAuxClick(event) {
|
|
20443
|
-
if (event.button === 1) { // primary aux button
|
|
20444
|
-
event.preventDefault(); // prevent user-agent default action
|
|
20445
|
-
this.notification().close();
|
|
20446
|
-
}
|
|
20447
|
-
}
|
|
20448
|
-
/**
|
|
20449
|
-
* Closes this notification when pressing escape if it is the most recently displayed notification.
|
|
20450
|
-
*/
|
|
20451
|
-
closeOnEscapeIfOnTop() {
|
|
20452
|
-
const zone = inject(NgZone);
|
|
20453
|
-
const document = inject(DOCUMENT);
|
|
20454
|
-
effect(onCleanup => {
|
|
20455
|
-
if (!this.notification().top()) {
|
|
20456
|
-
return;
|
|
20457
|
-
}
|
|
20458
|
-
const subscription = fromEvent(document, 'keydown')
|
|
20459
|
-
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), filter((event) => event.key === 'Escape'), observeIn(fn => zone.run(fn)))
|
|
20460
|
-
.subscribe(() => this.notification().close());
|
|
20461
|
-
onCleanup(() => subscription.unsubscribe());
|
|
20462
|
-
});
|
|
20463
|
-
}
|
|
20464
|
-
/**
|
|
20465
|
-
* Installs a timer to close the notification.
|
|
20466
|
-
*/
|
|
20467
|
-
installAutoCloseTimer() {
|
|
20468
|
-
effect(onCleanup => {
|
|
20469
|
-
const notification = this.notification();
|
|
20470
|
-
const duration = notification.duration();
|
|
20471
|
-
const focus = notification.focused();
|
|
20472
|
-
const hover = this.hover();
|
|
20473
|
-
if (hover || focus) {
|
|
20474
|
-
return;
|
|
20475
|
-
}
|
|
20476
|
-
untracked(() => {
|
|
20477
|
-
const subscription = fromDuration$(duration).subscribe(() => this.notification().close());
|
|
20478
|
-
onCleanup(() => subscription.unsubscribe());
|
|
20479
|
-
});
|
|
20480
|
-
});
|
|
20481
|
-
function fromDuration$(duration) {
|
|
20482
|
-
switch (duration) {
|
|
20483
|
-
case 'short':
|
|
20484
|
-
return timer(7000);
|
|
20485
|
-
case 'medium':
|
|
20486
|
-
return timer(15000);
|
|
20487
|
-
case 'long':
|
|
20488
|
-
return timer(30000);
|
|
20489
|
-
default:
|
|
20490
|
-
if (typeof duration === 'number') {
|
|
20491
|
-
return timer(duration);
|
|
20492
|
-
}
|
|
20493
|
-
return NEVER;
|
|
20494
|
-
}
|
|
20495
|
-
}
|
|
20496
|
-
}
|
|
20497
|
-
installFocusTracker() {
|
|
20498
|
-
const host = inject(ElementRef).nativeElement;
|
|
20499
|
-
const injector = inject(Injector);
|
|
20500
|
-
effect(onCleanup => {
|
|
20501
|
-
const notification = this.notification();
|
|
20502
|
-
untracked(() => {
|
|
20503
|
-
const tracker = runInInjectionContext(injector, () => trackFocus(host, notification));
|
|
20504
|
-
onCleanup(() => tracker.destroy());
|
|
20505
|
-
});
|
|
20506
|
-
});
|
|
20507
|
-
}
|
|
20508
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20509
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: WorkbenchNotificationComponent, isStandalone: true, selector: "wb-notification", inputs: { notification: { classPropertyName: "notification", publicName: "notification", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "mouseenter": "hover.set(true)", "mouseleave": "hover.set(false)", "auxclick": "onAuxClick($event)", "keydown.escape": "onEscape($event)" }, properties: { "attr.data-notificationid": "notification().id", "attr.data-severity": "notification().severity()", "style.min-height": "notification().size.minHeight()", "style.height": "notification().size.height()", "style.max-height": "notification().size.maxHeight()", "attr.tabindex": "-1", "class": "notification().cssClass()" } }, ngImport: i0, template: "<!-- Title -->\n@if (notification().title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n}\n\n<!-- Message -->\n<div class=\"message e2e-message\" [class.text]=\"!!notification().slot.text?.length\">\n @if (notification().slot.text?.length) {\n {{(notification().slot.text | wbText)()}}\n } @else if (notification().slot.component) {\n <sci-viewport class=\"e2e-message-viewport\">\n <ng-container *ngComponentOutlet=\"notification().slot.component!; inputs: notification().inputs | wbRemoveLegacyInput; injector: notification().slot.injector\"/>\n </sci-viewport>\n }\n</div>\n\n<button (click)=\"onClose()\"\n [title]=\"('%workbench.close.tooltip' | wbText)()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n</button>\n", styles: [":host{display:flex;flex-direction:column;gap:.75em;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:.9em;border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);padding:1em 0;overflow:hidden;outline:none;position:relative}:host:before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:var(--sci-workbench-notification-severity-indicator-size)}:host[data-severity=info]:before{background-color:var(--sci-color-accent)}:host[data-severity=warn]:before{background-color:var(--sci-color-notice)}:host[data-severity=error]:before{background-color:var(--sci-color-negative)}:host>header{flex:none;font-weight:700;padding:0 1.5em;word-break:break-word;white-space:pre-line}:host>div.message{flex:auto;overflow:hidden}:host>div.message.text{word-break:break-word;white-space:pre-line;padding:0 1.5em}:host>div.message>sci-viewport{height:100%}:host>div.message>sci-viewport::part(content){padding:0 1.5em}:host>button.close:is(button,#sci-reset){all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-corner);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-workbench-button-cursor)}:host>button.close:is(button,#sci-reset):hover:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-hover)}:host>button.close:is(button,#sci-reset):active:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-active)}:host>button.close:is(button,#sci-reset):focus:not(:focus-visible){outline:none}:host>button.close:is(button,#sci-reset):focus-visible{outline:var(--sci-workbench-button-outline-width-focus) solid var(--sci-color-accent)}:host>button.close:is(button,#sci-reset):disabled{color:var(--sci-color-gray-500)}:host>button.close:is(button,#sci-reset){position:absolute;top:.275em;right:.275em;padding:.125em;border-radius:var(--sci-corner-small);font-size:1rem}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "wb-icon", inputs: ["icon"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "pipe", type: TextPipe, name: "wbText" }, { kind: "pipe", type: RemoveLegacyInputPipe, name: "wbRemoveLegacyInput" }] });
|
|
20510
|
-
}
|
|
20511
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, decorators: [{
|
|
20512
|
-
type: Component,
|
|
20513
|
-
args: [{ selector: 'wb-notification', imports: [
|
|
20514
|
-
TextPipe,
|
|
20515
|
-
IconComponent,
|
|
20516
|
-
NgComponentOutlet,
|
|
20517
|
-
RemoveLegacyInputPipe,
|
|
20518
|
-
SciViewportComponent,
|
|
20519
|
-
], host: {
|
|
20520
|
-
'[attr.data-notificationid]': 'notification().id',
|
|
20521
|
-
'[attr.data-severity]': 'notification().severity()',
|
|
20522
|
-
'[style.min-height]': 'notification().size.minHeight()',
|
|
20523
|
-
'[style.height]': 'notification().size.height()',
|
|
20524
|
-
'[style.max-height]': 'notification().size.maxHeight()',
|
|
20525
|
-
'[attr.tabindex]': '-1',
|
|
20526
|
-
'[class]': 'notification().cssClass()',
|
|
20527
|
-
'(mouseenter)': 'hover.set(true)',
|
|
20528
|
-
'(mouseleave)': 'hover.set(false)',
|
|
20529
|
-
'(auxclick)': 'onAuxClick($event)',
|
|
20530
|
-
'(keydown.escape)': 'onEscape($event)',
|
|
20531
|
-
}, template: "<!-- Title -->\n@if (notification().title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n}\n\n<!-- Message -->\n<div class=\"message e2e-message\" [class.text]=\"!!notification().slot.text?.length\">\n @if (notification().slot.text?.length) {\n {{(notification().slot.text | wbText)()}}\n } @else if (notification().slot.component) {\n <sci-viewport class=\"e2e-message-viewport\">\n <ng-container *ngComponentOutlet=\"notification().slot.component!; inputs: notification().inputs | wbRemoveLegacyInput; injector: notification().slot.injector\"/>\n </sci-viewport>\n }\n</div>\n\n<button (click)=\"onClose()\"\n [title]=\"('%workbench.close.tooltip' | wbText)()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n</button>\n", styles: [":host{display:flex;flex-direction:column;gap:.75em;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:.9em;border:1px solid var(--sci-color-border);border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);padding:1em 0;overflow:hidden;outline:none;position:relative}:host:before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:var(--sci-workbench-notification-severity-indicator-size)}:host[data-severity=info]:before{background-color:var(--sci-color-accent)}:host[data-severity=warn]:before{background-color:var(--sci-color-notice)}:host[data-severity=error]:before{background-color:var(--sci-color-negative)}:host>header{flex:none;font-weight:700;padding:0 1.5em;word-break:break-word;white-space:pre-line}:host>div.message{flex:auto;overflow:hidden}:host>div.message.text{word-break:break-word;white-space:pre-line;padding:0 1.5em}:host>div.message>sci-viewport{height:100%}:host>div.message>sci-viewport::part(content){padding:0 1.5em}:host>button.close:is(button,#sci-reset){all:unset;display:inline-grid;place-content:center;place-items:center;padding:.25em;border-radius:var(--sci-corner);-webkit-user-select:none;user-select:none;overflow:hidden;cursor:var(--sci-workbench-button-cursor)}:host>button.close:is(button,#sci-reset):hover:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-hover)}:host>button.close:is(button,#sci-reset):active:where(:not(:disabled)){background-color:var(--sci-workbench-button-background-color-active)}:host>button.close:is(button,#sci-reset):focus:not(:focus-visible){outline:none}:host>button.close:is(button,#sci-reset):focus-visible{outline:var(--sci-workbench-button-outline-width-focus) solid var(--sci-color-accent)}:host>button.close:is(button,#sci-reset):disabled{color:var(--sci-color-gray-500)}:host>button.close:is(button,#sci-reset){position:absolute;top:.275em;right:.275em;padding:.125em;border-radius:var(--sci-corner-small);font-size:1rem}\n"] }]
|
|
20532
|
-
}], ctorParameters: () => [], propDecorators: { notification: [{ type: i0.Input, args: [{ isSignal: true, alias: "notification", required: true }] }] } });
|
|
20533
|
-
|
|
20534
|
-
/*
|
|
20535
|
-
* Copyright (c) 2018-2022 Swiss Federal Railways
|
|
20536
|
-
*
|
|
20537
|
-
* This program and the accompanying materials are made
|
|
20538
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
20539
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
20540
|
-
*
|
|
20541
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
20542
|
-
*/
|
|
20543
20618
|
/**
|
|
20544
20619
|
* Displays notifications on the right side, stacked vertically.
|
|
20545
20620
|
*/
|
|
20546
20621
|
class NotificationListComponent {
|
|
20547
20622
|
notifications = inject(WorkbenchNotificationRegistry).elements;
|
|
20548
20623
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20549
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NotificationListComponent, isStandalone: true, selector: "wb-notification-list", ngImport: i0, template: "@for (notification of notifications(); track notification.group || notification.id) {\n <
|
|
20624
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NotificationListComponent, isStandalone: true, selector: "wb-notification-list", ngImport: i0, template: "@for (notification of notifications(); track notification.group || notification.id) {\n <div class=\"notification\">\n <ng-container *wbPortalOutlet=\"notification.portal; destroyOnDetach: true\"/>\n </div>\n}\n", styles: [":host{display:flex;flex-flow:column wrap-reverse;gap:.5em;max-height:100%;align-items:flex-start;align-content:flex-start;pointer-events:none;margin:.5em}:host>div.notification{pointer-events:auto;width:var(--sci-workbench-notification-width);max-width:100%;position:relative;animation:slide-in .3s ease-out}@keyframes slide-in{0%{opacity:0;left:100%}to{opacity:1;left:0}}\n"], dependencies: [{ kind: "directive", type: WorkbenchPortalOutletDirective, selector: "ng-template[wbPortalOutlet]", inputs: ["wbPortalOutlet", "wbPortalOutletDestroyOnDetach"] }] });
|
|
20550
20625
|
}
|
|
20551
20626
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
20552
20627
|
type: Component,
|
|
20553
20628
|
args: [{ selector: 'wb-notification-list', imports: [
|
|
20554
|
-
|
|
20555
|
-
], template: "@for (notification of notifications(); track notification.group || notification.id) {\n <
|
|
20629
|
+
WorkbenchPortalOutletDirective,
|
|
20630
|
+
], template: "@for (notification of notifications(); track notification.group || notification.id) {\n <div class=\"notification\">\n <ng-container *wbPortalOutlet=\"notification.portal; destroyOnDetach: true\"/>\n </div>\n}\n", styles: [":host{display:flex;flex-flow:column wrap-reverse;gap:.5em;max-height:100%;align-items:flex-start;align-content:flex-start;pointer-events:none;margin:.5em}:host>div.notification{pointer-events:auto;width:var(--sci-workbench-notification-width);max-width:100%;position:relative;animation:slide-in .3s ease-out}@keyframes slide-in{0%{opacity:0;left:100%}to{opacity:1;left:0}}\n"] }]
|
|
20556
20631
|
}] });
|
|
20557
20632
|
|
|
20558
20633
|
/*
|
|
@@ -20963,7 +21038,7 @@ function configureWorkbenchGlassPane() {
|
|
|
20963
21038
|
},
|
|
20964
21039
|
{
|
|
20965
21040
|
provide: GLASS_PANE_OPTIONS,
|
|
20966
|
-
|
|
21041
|
+
useFactory: () => ({ cssClass: 'e2e-workbench' }),
|
|
20967
21042
|
},
|
|
20968
21043
|
];
|
|
20969
21044
|
}
|
|
@@ -21572,7 +21647,7 @@ function migrateGroupInputReduceFn(config) {
|
|
|
21572
21647
|
*/
|
|
21573
21648
|
|
|
21574
21649
|
/*
|
|
21575
|
-
* Copyright (c) 2018-
|
|
21650
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
21576
21651
|
*
|
|
21577
21652
|
* This program and the accompanying materials are made
|
|
21578
21653
|
* available under the terms of the Eclipse Public License 2.0
|