@scion/workbench 21.0.0-beta.3 → 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.
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { effect, untracked, Injectable, inject, Injector, signal, booleanAttribute, numberAttribute, DestroyRef, DOCUMENT, computed, InjectionToken, assertNotInReactiveContext, isSignal, createEnvironmentInjector, EnvironmentInjector, runInInjectionContext, Pipe, isDevMode, ChangeDetectionStrategy, Component, makeEnvironmentProviders, NgZone, ɵZONELESS_ENABLED as _ZONELESS_ENABLED, ApplicationInitStatus, forwardRef, Directive, createComponent, ApplicationRef, ElementRef, viewChild, afterRenderEffect, input, output, ViewContainerRef, TemplateRef, Renderer2, ChangeDetectorRef, linkedSignal, HostListener, HostBinding, viewChildren, IterableDiffers, CUSTOM_ELEMENTS_SCHEMA, provideEnvironmentInitializer } from '@angular/core';
|
|
3
3
|
import { RouterOutlet, Router, PRIMARY_OUTLET, ChildrenOutletContexts, NavigationStart, ActivationStart, ActivationEnd, UrlSegment, RouterEvent, NavigationEnd, NavigationCancel, NavigationError, ActivatedRoute } from '@angular/router';
|
|
4
|
-
import { Arrays, Objects
|
|
4
|
+
import { Arrays, Objects, Defined, Observables, Maps, Dictionaries } from '@scion/toolkit/util';
|
|
5
5
|
import { toObservable, takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { skipUntil, mergeMap,
|
|
6
|
+
import { skipUntil, mergeMap, observeOn, catchError, map, startWith, take, filter, switchMap as switchMap$1, skip, subscribeOn, finalize, distinctUntilChanged, takeUntil, first, combineLatestWith } from 'rxjs/operators';
|
|
7
7
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
8
8
|
import { UUID } from '@scion/toolkit/uuid';
|
|
9
|
-
import { Observable, Subject, asapScheduler, AsyncSubject, lastValueFrom, iif, switchMap, race, pairwise, EMPTY, of, firstValueFrom, from, animationFrameScheduler, merge, fromEvent, noop, BehaviorSubject, mergeWith, mergeMap as mergeMap$1, delay, identity, concatWith, withLatestFrom, NEVER, map as map$1, share, timer, ReplaySubject, combineLatest, tap
|
|
9
|
+
import { Observable, Subject, asapScheduler, AsyncSubject, lastValueFrom, iif, switchMap, race, pairwise, EMPTY, of, firstValueFrom, from, animationFrameScheduler, merge, fromEvent, noop, BehaviorSubject, mergeWith, mergeMap as mergeMap$1, delay, identity, concatWith, withLatestFrom, NEVER, map as map$1, share, timer, ReplaySubject, combineLatest, tap } from 'rxjs';
|
|
10
10
|
import { ManifestService, MicrofrontendPlatform, PlatformState, QualifierMatcher, ObservableDecorator, MicrofrontendPlatformConfig, MicrofrontendPlatformHost, APP_IDENTITY, MessageClient, mapToBody, OutletRouter, MessageHeaders, ResponseStatusCodes, ParamMatcher, CapabilityInterceptor, HostManifestInterceptor, IntentInterceptor, IntentClient, PlatformPropertyService } from '@scion/microfrontend-platform';
|
|
11
11
|
import { tapFirst, subscribeIn, observeIn, filterArray } from '@scion/toolkit/operators';
|
|
12
|
-
import { WorkbenchCapabilities, WorkbenchRouter as WorkbenchRouter$1, ɵWorkbenchRouter as _WorkbenchRouter, WorkbenchDialogService as WorkbenchDialogService$1, ɵWorkbenchDialogService as _WorkbenchDialogService, WorkbenchMessageBoxService as WorkbenchMessageBoxService$1, ɵWorkbenchMessageBoxService as _WorkbenchMessageBoxService, WorkbenchPopupService as WorkbenchPopupService$1, ɵWorkbenchPopupService as _WorkbenchPopupService, WorkbenchNotificationService as WorkbenchNotificationService$1, ɵWorkbenchNotificationService as _WorkbenchNotificationService, WorkbenchTextService, ɵWorkbenchTextService as _WorkbenchTextService, ɵTHEME_CONTEXT_KEY as _THEME_CONTEXT_KEY, ɵVIEW_ID_CONTEXT_KEY as _VIEW_ID_CONTEXT_KEY, ɵWorkbenchCommands as _WorkbenchCommands, ɵVIEW_CAPABILITY_ID_PARAM_NAME as _VIEW_CAPABILITY_ID_PARAM_NAME, ɵWORKBENCH_PART_CONTEXT as _WORKBENCH_PART_CONTEXT, eNOTIFICATION_MESSAGE_PARAM, ɵDIALOG_CONTEXT as _DIALOG_CONTEXT, ɵWorkbenchDialogMessageHeaders as _WorkbenchDialogMessageHeaders, ɵMESSAGE_BOX_CONTEXT as _MESSAGE_BOX_CONTEXT, eMESSAGE_BOX_MESSAGE_PARAM, WorkbenchClient, ɵPOPUP_CONTEXT as _POPUP_CONTEXT, ɵWorkbenchPopupMessageHeaders as _WorkbenchPopupMessageHeaders } from '@scion/workbench-client';
|
|
12
|
+
import { WorkbenchCapabilities, WorkbenchRouter as WorkbenchRouter$1, ɵWorkbenchRouter as _WorkbenchRouter, WorkbenchDialogService as WorkbenchDialogService$1, ɵWorkbenchDialogService as _WorkbenchDialogService, WorkbenchMessageBoxService as WorkbenchMessageBoxService$1, ɵWorkbenchMessageBoxService as _WorkbenchMessageBoxService, WorkbenchPopupService as WorkbenchPopupService$1, ɵWorkbenchPopupService as _WorkbenchPopupService, WorkbenchNotificationService as WorkbenchNotificationService$1, ɵWorkbenchNotificationService as _WorkbenchNotificationService, WorkbenchTextService, ɵWorkbenchTextService as _WorkbenchTextService, ɵTHEME_CONTEXT_KEY as _THEME_CONTEXT_KEY, ɵVIEW_ID_CONTEXT_KEY as _VIEW_ID_CONTEXT_KEY, ɵWorkbenchCommands as _WorkbenchCommands, ɵVIEW_CAPABILITY_ID_PARAM_NAME as _VIEW_CAPABILITY_ID_PARAM_NAME, ɵWORKBENCH_PART_CONTEXT as _WORKBENCH_PART_CONTEXT, eNOTIFICATION_MESSAGE_PARAM, ɵNOTIFICATION_CONTEXT as _NOTIFICATION_CONTEXT, ɵDIALOG_CONTEXT as _DIALOG_CONTEXT, ɵWorkbenchDialogMessageHeaders as _WorkbenchDialogMessageHeaders, ɵMESSAGE_BOX_CONTEXT as _MESSAGE_BOX_CONTEXT, eMESSAGE_BOX_MESSAGE_PARAM, WorkbenchClient, ɵPOPUP_CONTEXT as _POPUP_CONTEXT, ɵWorkbenchPopupMessageHeaders as _WorkbenchPopupMessageHeaders } from '@scion/workbench-client';
|
|
13
13
|
import { fromMutation$, fromResize$ } from '@scion/toolkit/observable';
|
|
14
14
|
import { boundingClientRect, SciDimensionDirective, dimension } from '@scion/components/dimension';
|
|
15
15
|
import { SciViewportComponent } from '@scion/components/viewport';
|
|
@@ -511,12 +511,6 @@ const WORKBENCH_ROUTE = new InjectionToken('WORKBENCH_ROUTE');
|
|
|
511
511
|
function serializeExecution(fn) {
|
|
512
512
|
return mergeMap(element => fn(element), 1);
|
|
513
513
|
}
|
|
514
|
-
/**
|
|
515
|
-
* Mirrors the source except for `null` emissions.
|
|
516
|
-
*/
|
|
517
|
-
function filterNull() {
|
|
518
|
-
return filter((item) => item !== null);
|
|
519
|
-
}
|
|
520
514
|
|
|
521
515
|
/*
|
|
522
516
|
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
@@ -1376,7 +1370,7 @@ function provideManifestObjectCache() {
|
|
|
1376
1370
|
}
|
|
1377
1371
|
|
|
1378
1372
|
/*
|
|
1379
|
-
* Copyright (c) 2018-
|
|
1373
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
1380
1374
|
*
|
|
1381
1375
|
* This program and the accompanying materials are made
|
|
1382
1376
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -1559,6 +1553,41 @@ function canMatchWorkbenchMessageBoxCapability(qualifier) {
|
|
|
1559
1553
|
function canMatchWorkbenchPopupCapability(qualifier) {
|
|
1560
1554
|
return canMatchWorkbenchCapability('popup', WorkbenchCapabilities.Popup, qualifier);
|
|
1561
1555
|
}
|
|
1556
|
+
/**
|
|
1557
|
+
* Configures a route to only match workbench notifications navigated to the specified notification capability.
|
|
1558
|
+
*
|
|
1559
|
+
* Use this guard to differentiate microfrontend routes, which must all have an empty path.
|
|
1560
|
+
*
|
|
1561
|
+
* @example - Route matching a notification capability with qualifier {notification: 'info'}
|
|
1562
|
+
* ```ts
|
|
1563
|
+
* import {Routes} from '@angular/router';
|
|
1564
|
+
* import {canMatchWorkbenchNotificationCapability} from '@scion/workbench';
|
|
1565
|
+
*
|
|
1566
|
+
* const routes: Routes = [
|
|
1567
|
+
* {path: '', canMatch: [canMatchWorkbenchNotificationCapability({notification: 'info'})], component: InfoComponent},
|
|
1568
|
+
* ];
|
|
1569
|
+
* ```
|
|
1570
|
+
*
|
|
1571
|
+
* The above route matches the following notification capability:
|
|
1572
|
+
*
|
|
1573
|
+
* ```json
|
|
1574
|
+
* {
|
|
1575
|
+
* "type": "notification",
|
|
1576
|
+
* "qualifier": {
|
|
1577
|
+
* "notification": "info"
|
|
1578
|
+
* },
|
|
1579
|
+
* "properties": {
|
|
1580
|
+
* "path": ""
|
|
1581
|
+
* }
|
|
1582
|
+
* }
|
|
1583
|
+
* ```
|
|
1584
|
+
*
|
|
1585
|
+
* @param qualifier - Identifies the notification capability.
|
|
1586
|
+
* @return guard matching the specified notification capability.
|
|
1587
|
+
*/
|
|
1588
|
+
function canMatchWorkbenchNotificationCapability(qualifier) {
|
|
1589
|
+
return canMatchWorkbenchCapability('notification', WorkbenchCapabilities.Notification, qualifier);
|
|
1590
|
+
}
|
|
1562
1591
|
/**
|
|
1563
1592
|
* Matches a route if navigated to the specified capability displayed in the specified workbench element.
|
|
1564
1593
|
*/
|
|
@@ -1673,6 +1702,12 @@ function isDialogId(dialogId) {
|
|
|
1673
1702
|
function isPopupId(popupId) {
|
|
1674
1703
|
return popupId?.startsWith(POPUP_ID_PREFIX) ?? false;
|
|
1675
1704
|
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Tests if the given id matches the format of a notification identifier.
|
|
1707
|
+
*/
|
|
1708
|
+
function isNotificationId(notificationId) {
|
|
1709
|
+
return notificationId?.startsWith(NOTIFICATION_ID_PREFIX) ?? false;
|
|
1710
|
+
}
|
|
1676
1711
|
/**
|
|
1677
1712
|
* Tests if the given id matches the format of an activity identifier.
|
|
1678
1713
|
*/
|
|
@@ -1993,7 +2028,7 @@ class UrlSegmentMatcher {
|
|
|
1993
2028
|
if (checkPath && segment.path !== this._pattern[index].path) {
|
|
1994
2029
|
return false;
|
|
1995
2030
|
}
|
|
1996
|
-
if (checkMatrixParams && !Objects
|
|
2031
|
+
if (checkMatrixParams && !Objects.isEqual(segment.parameters, this._pattern[index].parameters)) {
|
|
1997
2032
|
return false;
|
|
1998
2033
|
}
|
|
1999
2034
|
return true;
|
|
@@ -2001,51 +2036,6 @@ class UrlSegmentMatcher {
|
|
|
2001
2036
|
}
|
|
2002
2037
|
}
|
|
2003
2038
|
|
|
2004
|
-
/*
|
|
2005
|
-
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
2006
|
-
*
|
|
2007
|
-
* This program and the accompanying materials are made
|
|
2008
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
2009
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
2010
|
-
*
|
|
2011
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
2012
|
-
*/
|
|
2013
|
-
/**
|
|
2014
|
-
* Provides helper functions for working with objects.
|
|
2015
|
-
*/
|
|
2016
|
-
const Objects = {
|
|
2017
|
-
/**
|
|
2018
|
-
* Like {@link Object.keys}, but preserving the data type of keys.
|
|
2019
|
-
*/
|
|
2020
|
-
keys: (object) => {
|
|
2021
|
-
return Object.keys(object);
|
|
2022
|
-
},
|
|
2023
|
-
/**
|
|
2024
|
-
* Like {@link Object.values}, but preserving the data type of values and supporting optional properties.
|
|
2025
|
-
*/
|
|
2026
|
-
values: (object) => {
|
|
2027
|
-
return Object.values(object);
|
|
2028
|
-
},
|
|
2029
|
-
/**
|
|
2030
|
-
* Like {@link Object.entries}, but preserving the data type of keys and supporting optional properties.
|
|
2031
|
-
*/
|
|
2032
|
-
entries: (object) => {
|
|
2033
|
-
return Object.entries(object);
|
|
2034
|
-
},
|
|
2035
|
-
/**
|
|
2036
|
-
* Stringifies given object to matrix notation: a=b;c=d;e=f
|
|
2037
|
-
*/
|
|
2038
|
-
toMatrixNotation: (object) => {
|
|
2039
|
-
return Object.entries(object ?? {}).map(([key, value]) => `${key}=${value}`).join(';');
|
|
2040
|
-
},
|
|
2041
|
-
/**
|
|
2042
|
-
* Compares the two objects for shallow equality, ignoring the propery order.
|
|
2043
|
-
*/
|
|
2044
|
-
isEqual: (a, b) => {
|
|
2045
|
-
return Objects$1.isEqual(a, b);
|
|
2046
|
-
},
|
|
2047
|
-
};
|
|
2048
|
-
|
|
2049
2039
|
/*
|
|
2050
2040
|
* Copyright (c) 2018-2023 Swiss Federal Railways
|
|
2051
2041
|
*
|
|
@@ -6376,7 +6366,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
6376
6366
|
}], ctorParameters: () => [] });
|
|
6377
6367
|
|
|
6378
6368
|
/*
|
|
6379
|
-
* Copyright (c) 2018-
|
|
6369
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
6380
6370
|
*
|
|
6381
6371
|
* This program and the accompanying materials are made
|
|
6382
6372
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -6435,7 +6425,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
6435
6425
|
}] });
|
|
6436
6426
|
|
|
6437
6427
|
/*
|
|
6438
|
-
* Copyright (c) 2018-
|
|
6428
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
6439
6429
|
*
|
|
6440
6430
|
* This program and the accompanying materials are made
|
|
6441
6431
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -6789,7 +6779,7 @@ function removeEmptyEntries(map) {
|
|
|
6789
6779
|
* Compares two arrays of strings for equality, ignoring element order.
|
|
6790
6780
|
*/
|
|
6791
6781
|
function isEqualArray(a, b) {
|
|
6792
|
-
return
|
|
6782
|
+
return Objects.isEqual(a, b, { ignoreArrayOrder: true });
|
|
6793
6783
|
}
|
|
6794
6784
|
|
|
6795
6785
|
/**
|
|
@@ -6863,7 +6853,7 @@ class WbComponentPortal {
|
|
|
6863
6853
|
this.detach();
|
|
6864
6854
|
}
|
|
6865
6855
|
this._viewContainerRef.set(viewContainerRef);
|
|
6866
|
-
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 }));
|
|
6867
6857
|
this._logger.debug(() => 'Attaching portal', LoggerNames.LIFECYCLE, this._options?.debugName ?? this._componentType.name);
|
|
6868
6858
|
this._componentRef().changeDetectorRef.reattach();
|
|
6869
6859
|
this._viewContainerRef().insert(this._componentRef().hostView);
|
|
@@ -8339,7 +8329,7 @@ class MainAreaPartComponent {
|
|
|
8339
8329
|
});
|
|
8340
8330
|
}
|
|
8341
8331
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MainAreaPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8342
|
-
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"] }] });
|
|
8343
8333
|
}
|
|
8344
8334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MainAreaPartComponent, decorators: [{
|
|
8345
8335
|
type: Component,
|
|
@@ -8350,7 +8340,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
8350
8340
|
], host: {
|
|
8351
8341
|
'[attr.data-grid]': 'dasherize(part.gridName())',
|
|
8352
8342
|
'[attr.data-active]': `part.active() ? '' : null`,
|
|
8353
|
-
}, 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"] }]
|
|
8354
8344
|
}] });
|
|
8355
8345
|
|
|
8356
8346
|
/*
|
|
@@ -9732,7 +9722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
9732
9722
|
}] });
|
|
9733
9723
|
|
|
9734
9724
|
/*
|
|
9735
|
-
* Copyright (c) 2018-
|
|
9725
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
9736
9726
|
*
|
|
9737
9727
|
* This program and the accompanying materials are made
|
|
9738
9728
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -9754,7 +9744,8 @@ class WorkbenchDialogComponent {
|
|
|
9754
9744
|
headerHeight = signal(undefined, { ...(ngDevMode ? { debugName: "headerHeight" } : {}) });
|
|
9755
9745
|
transformTranslateX = signal(0, { ...(ngDevMode ? { debugName: "transformTranslateX" } : {}) });
|
|
9756
9746
|
transformTranslateY = signal(0, { ...(ngDevMode ? { debugName: "transformTranslateY" } : {}) });
|
|
9757
|
-
|
|
9747
|
+
slotAnchorName = this.dialog.id.replace('.', '_'); // Anchor must not contain a dot.
|
|
9748
|
+
dialogSlotBounds = viewChild.required('slot_bounds', { read: (ElementRef) });
|
|
9758
9749
|
constructor() {
|
|
9759
9750
|
this.setDialogOffset();
|
|
9760
9751
|
this.trackFocus();
|
|
@@ -9856,7 +9847,7 @@ class WorkbenchDialogComponent {
|
|
|
9856
9847
|
this.focus();
|
|
9857
9848
|
}
|
|
9858
9849
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9859
|
-
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: [
|
|
9860
9851
|
configureDialogGlassPane(),
|
|
9861
9852
|
], animations: [
|
|
9862
9853
|
trigger('enter', provideEnterAnimation()),
|
|
@@ -9891,9 +9882,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
9891
9882
|
'[style.--ɵdialog-min-width]': 'dialog.size.minWidth() ?? \'100px\'',
|
|
9892
9883
|
'[style.--ɵdialog-width]': 'dialog.size.width()',
|
|
9893
9884
|
'[style.--ɵdialog-max-width]': 'dialog.size.maxWidth()',
|
|
9885
|
+
'[style.--ɵslot-anchor]': '`--${slotAnchorName}`',
|
|
9894
9886
|
'[class]': 'dialog.cssClass()',
|
|
9895
|
-
}, 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=\"
|
|
9896
|
-
}], 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: [{
|
|
9897
9889
|
type: HostListener,
|
|
9898
9890
|
args: ['keydown.escape', ['$event']]
|
|
9899
9891
|
}] } });
|
|
@@ -10175,7 +10167,7 @@ class MessageBoxHeaderComponent {
|
|
|
10175
10167
|
title = input(undefined, { ...(ngDevMode ? { debugName: "title" } : {}) });
|
|
10176
10168
|
severity = input.required({ ...(ngDevMode ? { debugName: "severity" } : {}) });
|
|
10177
10169
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MessageBoxHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10178
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: MessageBoxHeaderComponent, isStandalone: true, selector: "wb-message-box-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-severity": "severity()" } }, ngImport: i0, template: "@if (title()) {\n <span class=\"title e2e-title\">{{(title() | wbText)()}}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{--\\275message-box-severity-color: initial;display:grid;border-top:var(--sci-workbench-messagebox-severity-indicator-size) solid var(--\\275message-box-severity-color);padding-inline:var(--sci-workbench-messagebox-padding);padding-top:var(--sci-workbench-messagebox-padding);-webkit-user-select:none;user-select:none}:host[data-severity=info]{--\\275message-box-severity-color: var(--sci-color-accent)}:host[data-severity=warn]{--\\275message-box-severity-color: var(--sci-color-notice)}:host[data-severity=error]{--\\275message-box-severity-color: var(--sci-color-negative)}:host>span.title{
|
|
10170
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: MessageBoxHeaderComponent, isStandalone: true, selector: "wb-message-box-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-severity": "severity()" } }, ngImport: i0, template: "@if (title()) {\n <span class=\"title e2e-title\">{{(title() | wbText)()}}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{--\\275message-box-severity-color: initial;display:grid;border-top:var(--sci-workbench-messagebox-severity-indicator-size) solid var(--\\275message-box-severity-color);padding-inline:var(--sci-workbench-messagebox-padding);padding-top:var(--sci-workbench-messagebox-padding);-webkit-user-select:none;user-select:none}:host[data-severity=info]{--\\275message-box-severity-color: var(--sci-color-accent)}:host[data-severity=warn]{--\\275message-box-severity-color: var(--sci-color-notice)}:host[data-severity=error]{--\\275message-box-severity-color: var(--sci-color-negative)}:host>span.title{word-break:break-word;white-space:pre-line;font-family:var(--sci-workbench-messagebox-title-font-family),sans-serif;font-size:var(--sci-workbench-messagebox-title-font-size);font-weight:var(--sci-workbench-messagebox-title-font-weight);text-align:var(--sci-workbench-messagebox-title-align)}\n"], dependencies: [{ kind: "pipe", type: TextPipe, name: "wbText" }] });
|
|
10179
10171
|
}
|
|
10180
10172
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MessageBoxHeaderComponent, decorators: [{
|
|
10181
10173
|
type: Component,
|
|
@@ -10183,7 +10175,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
10183
10175
|
TextPipe,
|
|
10184
10176
|
], host: {
|
|
10185
10177
|
'[attr.data-severity]': 'severity()',
|
|
10186
|
-
}, template: "@if (title()) {\n <span class=\"title e2e-title\">{{(title() | wbText)()}}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{--\\275message-box-severity-color: initial;display:grid;border-top:var(--sci-workbench-messagebox-severity-indicator-size) solid var(--\\275message-box-severity-color);padding-inline:var(--sci-workbench-messagebox-padding);padding-top:var(--sci-workbench-messagebox-padding);-webkit-user-select:none;user-select:none}:host[data-severity=info]{--\\275message-box-severity-color: var(--sci-color-accent)}:host[data-severity=warn]{--\\275message-box-severity-color: var(--sci-color-notice)}:host[data-severity=error]{--\\275message-box-severity-color: var(--sci-color-negative)}:host>span.title{
|
|
10178
|
+
}, template: "@if (title()) {\n <span class=\"title e2e-title\">{{(title() | wbText)()}}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{--\\275message-box-severity-color: initial;display:grid;border-top:var(--sci-workbench-messagebox-severity-indicator-size) solid var(--\\275message-box-severity-color);padding-inline:var(--sci-workbench-messagebox-padding);padding-top:var(--sci-workbench-messagebox-padding);-webkit-user-select:none;user-select:none}:host[data-severity=info]{--\\275message-box-severity-color: var(--sci-color-accent)}:host[data-severity=warn]{--\\275message-box-severity-color: var(--sci-color-notice)}:host[data-severity=error]{--\\275message-box-severity-color: var(--sci-color-negative)}:host>span.title{word-break:break-word;white-space:pre-line;font-family:var(--sci-workbench-messagebox-title-font-family),sans-serif;font-size:var(--sci-workbench-messagebox-title-font-size);font-weight:var(--sci-workbench-messagebox-title-font-weight);text-align:var(--sci-workbench-messagebox-title-align)}\n"] }]
|
|
10187
10179
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: true }] }] } });
|
|
10188
10180
|
|
|
10189
10181
|
/*
|
|
@@ -10228,20 +10220,17 @@ class WorkbenchMessageBoxComponent {
|
|
|
10228
10220
|
message = input.required({ ...(ngDevMode ? { debugName: "message" } : {}), transform: nullIfEmptyMessage });
|
|
10229
10221
|
options = input(undefined, { ...(ngDevMode ? { debugName: "options" } : {}) });
|
|
10230
10222
|
_dialog = inject(ɵWorkbenchDialog);
|
|
10231
|
-
|
|
10232
|
-
tabindex = -1;
|
|
10233
|
-
empty = false;
|
|
10234
|
-
get contentSelectable() {
|
|
10235
|
-
return this.options()?.contentSelectable;
|
|
10236
|
-
}
|
|
10237
|
-
get hasTitle() {
|
|
10238
|
-
return !!this.options()?.title;
|
|
10239
|
-
}
|
|
10223
|
+
empty = signal(false, { ...(ngDevMode ? { debugName: "empty" } : {}) });
|
|
10240
10224
|
constructor() {
|
|
10241
10225
|
this._dialog.closable = false;
|
|
10242
10226
|
this._dialog.resizable = false;
|
|
10243
10227
|
this._dialog.padding = false;
|
|
10244
|
-
|
|
10228
|
+
// Limit the maximum messagebox width if text message to break the message.
|
|
10229
|
+
effect(() => {
|
|
10230
|
+
if (typeof this.message() === 'string' || this.message() === null) {
|
|
10231
|
+
this._dialog.size.maxWidth = 'var(--sci-workbench-messagebox-max-width)';
|
|
10232
|
+
}
|
|
10233
|
+
});
|
|
10245
10234
|
}
|
|
10246
10235
|
onAction(action) {
|
|
10247
10236
|
this._dialog.close(action);
|
|
@@ -10255,10 +10244,10 @@ class WorkbenchMessageBoxComponent {
|
|
|
10255
10244
|
this._dialog.size.minWidth = `${preferredSize}px`;
|
|
10256
10245
|
}
|
|
10257
10246
|
onContentDimensionChange(dimension) {
|
|
10258
|
-
this.empty
|
|
10247
|
+
this.empty.set(!dimension.offsetHeight);
|
|
10259
10248
|
}
|
|
10260
10249
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchMessageBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10261
|
-
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": "
|
|
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" }] });
|
|
10262
10251
|
}
|
|
10263
10252
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchMessageBoxComponent, decorators: [{
|
|
10264
10253
|
type: Component,
|
|
@@ -10271,23 +10260,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
10271
10260
|
MessageBoxFooterComponent,
|
|
10272
10261
|
TypeofPipe,
|
|
10273
10262
|
TextPipe,
|
|
10274
|
-
],
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
args: ['class.content-selectable']
|
|
10284
|
-
}], hasTitle: [{
|
|
10285
|
-
type: HostBinding,
|
|
10286
|
-
args: ['class.has-title']
|
|
10287
|
-
}], onEscape: [{
|
|
10288
|
-
type: HostListener,
|
|
10289
|
-
args: ['keydown.escape']
|
|
10290
|
-
}] } });
|
|
10263
|
+
], host: {
|
|
10264
|
+
// Ensure host element to be focusable in order to close the message box on Escape keystroke.
|
|
10265
|
+
'[attr.tabindex]': '-1',
|
|
10266
|
+
'[class.empty]': 'empty()',
|
|
10267
|
+
'[class.content-selectable]': 'options()?.contentSelectable',
|
|
10268
|
+
'[class.has-title]': '!!this.options()?.title',
|
|
10269
|
+
'(keydown.escape)': 'onEscape()',
|
|
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"] }]
|
|
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 }] }] } });
|
|
10291
10272
|
function nullIfEmptyMessage(message) {
|
|
10292
10273
|
return message !== '' ? message : null;
|
|
10293
10274
|
}
|
|
@@ -10424,7 +10405,7 @@ class WorkbenchPopupComponent {
|
|
|
10424
10405
|
}, { ...(ngDevMode ? { debugName: "effectRef" } : {}) });
|
|
10425
10406
|
}
|
|
10426
10407
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10427
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.1", type: WorkbenchPopupComponent, isStandalone: true, selector: "wb-popup", host: { properties: { "attr.data-popupid": "popup.id", "style.width": "popup.size
|
|
10408
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.1", type: WorkbenchPopupComponent, isStandalone: true, selector: "wb-popup", host: { properties: { "attr.data-popupid": "popup.id", "style.width": "popup.size.width()", "style.min-width": "popup.size.minWidth()", "style.max-width": "popup.size.maxWidth()", "style.height": "popup.size.height()", "style.min-height": "popup.size.minHeight()", "style.max-height": "popup.size.maxHeight()", "class": "popup.cssClass()" } }, providers: [
|
|
10428
10409
|
configurePopupGlassPane(),
|
|
10429
10410
|
], viewQueries: [{ propertyName: "_cdkTrapFocus", first: true, predicate: ["focus_trap"], descendants: true, read: CdkTrapFocus, isSignal: true }], hostDirectives: [{ directive: GlassPaneDirective }], ngImport: i0, template: "<sci-viewport cdkTrapFocus class=\"e2e-popup-viewport\" #focus_trap>\n <ng-container *ngComponentOutlet=\"popup.component; inputs: popup.inputs\"/>\n</sci-viewport>\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;outline:none;border-radius:var(--sci-corner);overflow:hidden}\n"], dependencies: [{ kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
|
|
10430
10411
|
}
|
|
@@ -10440,12 +10421,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
10440
10421
|
configurePopupGlassPane(),
|
|
10441
10422
|
], host: {
|
|
10442
10423
|
'[attr.data-popupid]': 'popup.id',
|
|
10443
|
-
'[style.width]': 'popup.size
|
|
10444
|
-
'[style.min-width]': 'popup.size
|
|
10445
|
-
'[style.max-width]': 'popup.size
|
|
10446
|
-
'[style.height]': 'popup.size
|
|
10447
|
-
'[style.min-height]': 'popup.size
|
|
10448
|
-
'[style.max-height]': 'popup.size
|
|
10424
|
+
'[style.width]': 'popup.size.width()',
|
|
10425
|
+
'[style.min-width]': 'popup.size.minWidth()',
|
|
10426
|
+
'[style.max-width]': 'popup.size.maxWidth()',
|
|
10427
|
+
'[style.height]': 'popup.size.height()',
|
|
10428
|
+
'[style.min-height]': 'popup.size.minHeight()',
|
|
10429
|
+
'[style.max-height]': 'popup.size.maxHeight()',
|
|
10449
10430
|
'[class]': 'popup.cssClass()',
|
|
10450
10431
|
}, template: "<sci-viewport cdkTrapFocus class=\"e2e-popup-viewport\" #focus_trap>\n <ng-container *ngComponentOutlet=\"popup.component; inputs: popup.inputs\"/>\n</sci-viewport>\n", styles: [":host{display:grid;grid-template-columns:100%;grid-template-rows:100%;outline:none;border-radius:var(--sci-corner);overflow:hidden}\n"] }]
|
|
10451
10432
|
}], ctorParameters: () => [], propDecorators: { _cdkTrapFocus: [{ type: i0.ViewChild, args: ['focus_trap', { ...{ read: CdkTrapFocus }, isSignal: true }] }] } });
|
|
@@ -10943,6 +10924,38 @@ const LEGACY_POPUP_INPUT = new InjectionToken('LEGACY_POPUP_INPUT');
|
|
|
10943
10924
|
*
|
|
10944
10925
|
* SPDX-License-Identifier: EPL-2.0
|
|
10945
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
|
+
*/
|
|
10946
10959
|
/**
|
|
10947
10960
|
* Creates the invocation context for given element.
|
|
10948
10961
|
*
|
|
@@ -10963,7 +10976,7 @@ function createInvocationContext(elementId, options) {
|
|
|
10963
10976
|
return {
|
|
10964
10977
|
elementId: part.id,
|
|
10965
10978
|
attached: part.slot.portal.attached,
|
|
10966
|
-
bounds: computed(() => constrainClientRect(part.slot.bounds(), part.
|
|
10979
|
+
bounds: computed(() => constrainClientRect(part.slot.bounds(), part.partBounds())),
|
|
10967
10980
|
destroyed: part.slot.portal.destroyed,
|
|
10968
10981
|
peripheral: part.peripheral,
|
|
10969
10982
|
};
|
|
@@ -10973,7 +10986,7 @@ function createInvocationContext(elementId, options) {
|
|
|
10973
10986
|
return {
|
|
10974
10987
|
elementId: view.id,
|
|
10975
10988
|
attached: view.slot.portal.attached,
|
|
10976
|
-
bounds: computed(() => constrainClientRect(view.slot.bounds(), view.part().
|
|
10989
|
+
bounds: computed(() => constrainClientRect(view.slot.bounds(), view.part().partBounds())),
|
|
10977
10990
|
destroyed: view.slot.portal.destroyed,
|
|
10978
10991
|
peripheral: computed(() => view.part().peripheral()),
|
|
10979
10992
|
};
|
|
@@ -10998,6 +11011,16 @@ function createInvocationContext(elementId, options) {
|
|
|
10998
11011
|
peripheral: signal(false),
|
|
10999
11012
|
};
|
|
11000
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
|
+
}
|
|
11001
11024
|
return null;
|
|
11002
11025
|
}
|
|
11003
11026
|
|
|
@@ -11195,7 +11218,7 @@ function provideWorkbenchDialogContext() {
|
|
|
11195
11218
|
}
|
|
11196
11219
|
|
|
11197
11220
|
/*
|
|
11198
|
-
* Copyright (c) 2018-
|
|
11221
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
11199
11222
|
*
|
|
11200
11223
|
* This program and the accompanying materials are made
|
|
11201
11224
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -11230,7 +11253,7 @@ class ɵWorkbenchDialog {
|
|
|
11230
11253
|
focused = computed(() => this._focusMonitor.activeElement()?.id === this.id, { ...(ngDevMode ? { debugName: "focused" } : {}) });
|
|
11231
11254
|
attached;
|
|
11232
11255
|
destroyed = signal(false, { ...(ngDevMode ? { debugName: "destroyed" } : {}) });
|
|
11233
|
-
bounds = boundingClientRect(computed(() => this._componentRef()?.instance.
|
|
11256
|
+
bounds = boundingClientRect(computed(() => this._componentRef()?.instance.dialogSlotBounds()));
|
|
11234
11257
|
modal;
|
|
11235
11258
|
blinking$ = new BehaviorSubject(false);
|
|
11236
11259
|
header;
|
|
@@ -11760,6 +11783,7 @@ class ɵWorkbenchView {
|
|
|
11760
11783
|
focused = computed(() => this._focusMonitor.activeElement()?.id === this.id, { ...(ngDevMode ? { debugName: "focused" } : {}) });
|
|
11761
11784
|
menuItems;
|
|
11762
11785
|
blockedBy;
|
|
11786
|
+
bounds = computed(() => this.slot.bounds(), { ...(ngDevMode ? { debugName: "bounds" } : {}) });
|
|
11763
11787
|
slot;
|
|
11764
11788
|
classList = new ClassList();
|
|
11765
11789
|
isClosable = computed(() => this._closable() && !this.blockedBy(), { ...(ngDevMode ? { debugName: "isClosable" } : {}) });
|
|
@@ -12005,7 +12029,7 @@ class ɵWorkbenchView {
|
|
|
12005
12029
|
changes?.forEachAddedItem(({ item: fn }) => menuItems.set(fn, computed(() => runInInjectionContext(constructInjector(this, this.part()), () => fn(this)))));
|
|
12006
12030
|
changes?.forEachRemovedItem(({ item: fn }) => menuItems.delete(fn));
|
|
12007
12031
|
return Array.from(menuItems.values()).map(menuItem => menuItem()).filter(menuItem => !!menuItem);
|
|
12008
|
-
}, { equal: (a, b) =>
|
|
12032
|
+
}, { equal: (a, b) => Objects.isEqual(a, b) });
|
|
12009
12033
|
function constructInjector(view, part) {
|
|
12010
12034
|
return Injector.create({
|
|
12011
12035
|
parent: injector,
|
|
@@ -12463,7 +12487,7 @@ class ViewMenuService {
|
|
|
12463
12487
|
}
|
|
12464
12488
|
const key = accelerator.at(-1).toLocaleLowerCase();
|
|
12465
12489
|
const modifierKeys = accelerator.slice(0, -1);
|
|
12466
|
-
return key === eventKey &&
|
|
12490
|
+
return key === eventKey && Objects.isEqual(modifierKeys, eventModifierKeys, { ignoreArrayOrder: true });
|
|
12467
12491
|
});
|
|
12468
12492
|
}
|
|
12469
12493
|
}
|
|
@@ -12657,18 +12681,12 @@ class ViewTabComponent {
|
|
|
12657
12681
|
}
|
|
12658
12682
|
onClose(event) {
|
|
12659
12683
|
event.stopPropagation(); // prevent the view from being activated
|
|
12660
|
-
|
|
12661
|
-
void this.view().close('other-views');
|
|
12662
|
-
}
|
|
12663
|
-
else {
|
|
12664
|
-
void this.view().close();
|
|
12665
|
-
}
|
|
12684
|
+
this.closeView(event);
|
|
12666
12685
|
}
|
|
12667
|
-
|
|
12668
|
-
if (event.
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
event.preventDefault();
|
|
12686
|
+
onAuxClick(event) {
|
|
12687
|
+
if (event.button === 1) { // primary aux button
|
|
12688
|
+
event.preventDefault(); // prevent user-agent default action
|
|
12689
|
+
this.closeView(event);
|
|
12672
12690
|
}
|
|
12673
12691
|
}
|
|
12674
12692
|
onContextmenu(event) {
|
|
@@ -12713,6 +12731,17 @@ class ViewTabComponent {
|
|
|
12713
12731
|
onDragEnd() {
|
|
12714
12732
|
this.viewDragService.unsetViewDragData();
|
|
12715
12733
|
}
|
|
12734
|
+
/**
|
|
12735
|
+
* Closes the current view or other views if the 'Alt' key is pressed.
|
|
12736
|
+
*/
|
|
12737
|
+
closeView(event) {
|
|
12738
|
+
if (event.altKey) {
|
|
12739
|
+
void this.view().close('other-views');
|
|
12740
|
+
}
|
|
12741
|
+
else {
|
|
12742
|
+
void this.view().close();
|
|
12743
|
+
}
|
|
12744
|
+
}
|
|
12716
12745
|
installMenuAccelerators() {
|
|
12717
12746
|
this._viewMenuService.installMenuAccelerators(this.host, this.view);
|
|
12718
12747
|
}
|
|
@@ -12729,7 +12758,7 @@ class ViewTabComponent {
|
|
|
12729
12758
|
});
|
|
12730
12759
|
}
|
|
12731
12760
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ViewTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12732
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: ViewTabComponent, isStandalone: true, selector: "wb-view-tab", inputs: { view: { classPropertyName: "view", publicName: "viewId", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick()", "
|
|
12761
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: ViewTabComponent, isStandalone: true, selector: "wb-view-tab", inputs: { view: { classPropertyName: "view", publicName: "viewId", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick()", "auxclick": "onAuxClick($event)", "contextmenu": "onContextmenu($event)", "dragstart": "onDragStart($event)", "dragend": "onDragEnd()" }, properties: { "attr.data-viewid": "view().id", "attr.data-active": "view().active() ? '' : null", "attr.data-dirty": "view().dirty() ? '' : null", "attr.data-focus-within-view": "view().focused() ? '' : null", "attr.draggable": "true", "attr.tabindex": "-1", "class.view-drag": "viewDragService.dragging()", "class": "view().classList.asList()", "style.--sci-workbench-tab-title-offset-right": "viewTitleOffsetRight()" } }, ngImport: i0, template: "<!-- IMPORTANT: THIS HTML FILE IS ALSO USED BY `ViewTabDragImageComponent` -->\n\n@if (view().active()) {\n <div class=\"corner-radius start\">\n <div class=\"circle\"></div>\n </div>\n}\n\n<div class=\"content\">\n <ng-container *cdkPortalOutlet=\"viewTabContentPortal()\"/>\n</div>\n\n@if (view().active()) {\n <div class=\"corner-radius end\">\n <div class=\"circle\"></div>\n </div>\n}\n\n@if (view().closable()) {\n <button (click)=\"onClose($event)\"\n [title]=\"('%workbench.close_tab.tooltip;close_others_modifier=Alt' | wbText)()\"\n [disabled]=\"!view().isClosable()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n </button>\n}\n", styles: [":host{display:grid;align-items:center;padding-left:var(--sci-workbench-tab-padding-inline);padding-right:var(--sci-workbench-tab-padding-inline);position:relative;-webkit-user-select:none;user-select:none;cursor:var(--sci-workbench-tab-cursor);box-sizing:border-box;outline:none;border-top:var(--sci-workbench-tab-border-top-width) solid transparent;border-left:var(--sci-workbench-tab-border-width) solid transparent;border-right:var(--sci-workbench-tab-border-width) solid transparent;border-top-left-radius:var(--sci-workbench-tab-border-radius);border-top-right-radius:var(--sci-workbench-tab-border-radius)}:host[data-active]{cursor:default;border-left-color:var(--sci-workbench-tab-border-color);border-right-color:var(--sci-workbench-tab-border-color);border-top-color:var(--sci-workbench-tab-border-color);background-color:var(--sci-workbench-view-background-color)}wb-part[data-peripheral] :host[data-active]{background-color:var(--sci-workbench-view-peripheral-background-color)}:host[data-active]>div.content{color:var(--sci-workbench-tab-text-color-active)}:host[data-active][data-focus-within-view]>div.content{color:var(--sci-workbench-part-active-tab-text-color-active)}:host>div.content{display:inline-grid;font-family:var(--sci-workbench-tab-font-family),sans-serif;font-size:var(--sci-workbench-tab-font-size);font-weight:var(--sci-workbench-tab-font-weight);min-width:var(--sci-workbench-tab-min-width);max-width:var(--sci-workbench-tab-max-width);isolation:isolate;transform:translateY(calc(-1 * var(--sci-workbench-tab-border-top-width)))}: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;right:calc(var(--sci-workbench-tab-padding-inline) - .125em);visibility:hidden;padding:.125em;border-radius:var(--sci-corner-small);transform:translateY(calc(-1 * var(--sci-workbench-tab-border-top-width)))}:host[data-active]>button.close:is(button,#sci-reset),:host:hover:not(.view-drag)>button.close:is(button,#sci-reset){visibility:visible}@container style(--sci-workbench-tab-background-color-hover){:host:hover:not([data-active]):not(.view-drag):before{content:\"\";position:absolute;place-self:start center;box-sizing:border-box;height:calc(100% - var(--sci-workbench-tab-padding-block-hover) - var(--sci-workbench-part-bar-border-bottom-width));width:calc(100% - var(--sci-workbench-tab-padding-inline-hover) + 2 * var(--sci-workbench-tab-border-width));background-color:var(--sci-workbench-tab-background-color-hover);border:var(--sci-workbench-tab-border-width) solid var(--sci-workbench-tab-background-color-hover);border-radius:var(--sci-workbench-tab-border-radius);pointer-events:none}:host:hover:not([data-active]):not(.view-drag)>button.close:is(button,#sci-reset):not(:disabled):hover{background-color:color-mix(in srgb,var(--sci-workbench-tab-background-color-hover) 90%,light-dark(var(--sci-static-color-black),var(--sci-static-color-white)))}}:host>div.corner-radius{height:var(--sci-workbench-tab-border-radius);width:var(--sci-workbench-tab-border-radius);overflow:hidden;position:absolute;bottom:0}:host>div.corner-radius>div.circle{position:absolute;top:calc(-2 * var(--sci-workbench-tab-border-radius));width:calc(2 * var(--sci-workbench-tab-border-radius));height:calc(2 * var(--sci-workbench-tab-border-radius));border:var(--sci-workbench-tab-border-radius) solid var(--sci-workbench-view-background-color);border-radius:50%;box-shadow:inset 0 0 0 var(--sci-workbench-tab-border-width) var(--sci-workbench-tab-border-color);box-sizing:content-box}wb-part[data-peripheral] :host>div.corner-radius>div.circle{border-color:var(--sci-workbench-view-peripheral-background-color)}:host>div.corner-radius.start{left:calc(-1 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.start>div.circle{left:calc(-2 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.end{right:calc(-1 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.end>div.circle{right:calc(-2 * var(--sci-workbench-tab-border-radius))}@container viewtab (height >= 3.5rem){:host>button.close:is(button,#sci-reset){top:5px;right:5px}}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "component", type: IconComponent, selector: "wb-icon", inputs: ["icon"] }, { kind: "pipe", type: TextPipe, name: "wbText" }] });
|
|
12733
12762
|
}
|
|
12734
12763
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ViewTabComponent, decorators: [{
|
|
12735
12764
|
type: Component,
|
|
@@ -12747,27 +12776,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
12747
12776
|
'[class.view-drag]': 'viewDragService.dragging()',
|
|
12748
12777
|
'[class]': 'view().classList.asList()',
|
|
12749
12778
|
'[style.--sci-workbench-tab-title-offset-right]': 'viewTitleOffsetRight()',
|
|
12779
|
+
'(click)': 'onClick()',
|
|
12780
|
+
'(auxclick)': 'onAuxClick($event)',
|
|
12781
|
+
'(contextmenu)': 'onContextmenu($event)',
|
|
12782
|
+
'(dragstart)': 'onDragStart($event)',
|
|
12783
|
+
'(dragend)': 'onDragEnd()',
|
|
12750
12784
|
}, template: "<!-- IMPORTANT: THIS HTML FILE IS ALSO USED BY `ViewTabDragImageComponent` -->\n\n@if (view().active()) {\n <div class=\"corner-radius start\">\n <div class=\"circle\"></div>\n </div>\n}\n\n<div class=\"content\">\n <ng-container *cdkPortalOutlet=\"viewTabContentPortal()\"/>\n</div>\n\n@if (view().active()) {\n <div class=\"corner-radius end\">\n <div class=\"circle\"></div>\n </div>\n}\n\n@if (view().closable()) {\n <button (click)=\"onClose($event)\"\n [title]=\"('%workbench.close_tab.tooltip;close_others_modifier=Alt' | wbText)()\"\n [disabled]=\"!view().isClosable()\"\n class=\"close e2e-close\">\n <wb-icon icon=\"workbench.close\"/>\n </button>\n}\n", styles: [":host{display:grid;align-items:center;padding-left:var(--sci-workbench-tab-padding-inline);padding-right:var(--sci-workbench-tab-padding-inline);position:relative;-webkit-user-select:none;user-select:none;cursor:var(--sci-workbench-tab-cursor);box-sizing:border-box;outline:none;border-top:var(--sci-workbench-tab-border-top-width) solid transparent;border-left:var(--sci-workbench-tab-border-width) solid transparent;border-right:var(--sci-workbench-tab-border-width) solid transparent;border-top-left-radius:var(--sci-workbench-tab-border-radius);border-top-right-radius:var(--sci-workbench-tab-border-radius)}:host[data-active]{cursor:default;border-left-color:var(--sci-workbench-tab-border-color);border-right-color:var(--sci-workbench-tab-border-color);border-top-color:var(--sci-workbench-tab-border-color);background-color:var(--sci-workbench-view-background-color)}wb-part[data-peripheral] :host[data-active]{background-color:var(--sci-workbench-view-peripheral-background-color)}:host[data-active]>div.content{color:var(--sci-workbench-tab-text-color-active)}:host[data-active][data-focus-within-view]>div.content{color:var(--sci-workbench-part-active-tab-text-color-active)}:host>div.content{display:inline-grid;font-family:var(--sci-workbench-tab-font-family),sans-serif;font-size:var(--sci-workbench-tab-font-size);font-weight:var(--sci-workbench-tab-font-weight);min-width:var(--sci-workbench-tab-min-width);max-width:var(--sci-workbench-tab-max-width);isolation:isolate;transform:translateY(calc(-1 * var(--sci-workbench-tab-border-top-width)))}: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;right:calc(var(--sci-workbench-tab-padding-inline) - .125em);visibility:hidden;padding:.125em;border-radius:var(--sci-corner-small);transform:translateY(calc(-1 * var(--sci-workbench-tab-border-top-width)))}:host[data-active]>button.close:is(button,#sci-reset),:host:hover:not(.view-drag)>button.close:is(button,#sci-reset){visibility:visible}@container style(--sci-workbench-tab-background-color-hover){:host:hover:not([data-active]):not(.view-drag):before{content:\"\";position:absolute;place-self:start center;box-sizing:border-box;height:calc(100% - var(--sci-workbench-tab-padding-block-hover) - var(--sci-workbench-part-bar-border-bottom-width));width:calc(100% - var(--sci-workbench-tab-padding-inline-hover) + 2 * var(--sci-workbench-tab-border-width));background-color:var(--sci-workbench-tab-background-color-hover);border:var(--sci-workbench-tab-border-width) solid var(--sci-workbench-tab-background-color-hover);border-radius:var(--sci-workbench-tab-border-radius);pointer-events:none}:host:hover:not([data-active]):not(.view-drag)>button.close:is(button,#sci-reset):not(:disabled):hover{background-color:color-mix(in srgb,var(--sci-workbench-tab-background-color-hover) 90%,light-dark(var(--sci-static-color-black),var(--sci-static-color-white)))}}:host>div.corner-radius{height:var(--sci-workbench-tab-border-radius);width:var(--sci-workbench-tab-border-radius);overflow:hidden;position:absolute;bottom:0}:host>div.corner-radius>div.circle{position:absolute;top:calc(-2 * var(--sci-workbench-tab-border-radius));width:calc(2 * var(--sci-workbench-tab-border-radius));height:calc(2 * var(--sci-workbench-tab-border-radius));border:var(--sci-workbench-tab-border-radius) solid var(--sci-workbench-view-background-color);border-radius:50%;box-shadow:inset 0 0 0 var(--sci-workbench-tab-border-width) var(--sci-workbench-tab-border-color);box-sizing:content-box}wb-part[data-peripheral] :host>div.corner-radius>div.circle{border-color:var(--sci-workbench-view-peripheral-background-color)}:host>div.corner-radius.start{left:calc(-1 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.start>div.circle{left:calc(-2 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.end{right:calc(-1 * var(--sci-workbench-tab-border-radius))}:host>div.corner-radius.end>div.circle{right:calc(-2 * var(--sci-workbench-tab-border-radius))}@container viewtab (height >= 3.5rem){:host>button.close:is(button,#sci-reset){top:5px;right:5px}}\n"] }]
|
|
12751
|
-
}], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewId", required: true }] }]
|
|
12752
|
-
type: HostListener,
|
|
12753
|
-
args: ['click']
|
|
12754
|
-
}], onMousedown: [{
|
|
12755
|
-
type: HostListener,
|
|
12756
|
-
args: ['mousedown', ['$event']]
|
|
12757
|
-
}], onContextmenu: [{
|
|
12758
|
-
type: HostListener,
|
|
12759
|
-
args: ['contextmenu', ['$event']]
|
|
12760
|
-
}], onDragStart: [{
|
|
12761
|
-
type: HostListener,
|
|
12762
|
-
args: ['dragstart', ['$event']]
|
|
12763
|
-
}], onDragEnd: [{
|
|
12764
|
-
type: HostListener,
|
|
12765
|
-
args: ['dragend']
|
|
12766
|
-
}] } });
|
|
12767
|
-
/**
|
|
12768
|
-
* Indicates that the auxilary mouse button is pressed (usually the mouse wheel button or middle button).
|
|
12769
|
-
*/
|
|
12770
|
-
const AUXILARY_MOUSE_BUTTON$1 = 4;
|
|
12785
|
+
}], ctorParameters: () => [], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewId", required: true }] }] } });
|
|
12771
12786
|
|
|
12772
12787
|
/*
|
|
12773
12788
|
* Copyright (c) 2018-2022 Swiss Federal Railways
|
|
@@ -13027,6 +13042,7 @@ class DragImageWorkbenchView {
|
|
|
13027
13042
|
menuItems = signal([], { ...(ngDevMode ? { debugName: "menuItems" } : {}) });
|
|
13028
13043
|
isClosable;
|
|
13029
13044
|
activationInstant = signal(0, { ...(ngDevMode ? { debugName: "activationInstant" } : {}) });
|
|
13045
|
+
bounds = signal(undefined, { ...(ngDevMode ? { debugName: "bounds" } : {}) });
|
|
13030
13046
|
constructor(dragData) {
|
|
13031
13047
|
this.id = dragData.viewId;
|
|
13032
13048
|
this.alternativeId = dragData.alternativeViewId;
|
|
@@ -13707,7 +13723,7 @@ class PartComponent {
|
|
|
13707
13723
|
inject(DestroyRef).onDestroy(() => logger.debug(() => `Destroying PartComponent [partId=${this.part.id}]'`, LoggerNames.LIFECYCLE));
|
|
13708
13724
|
}
|
|
13709
13725
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13710
|
-
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"] }] });
|
|
13711
13727
|
}
|
|
13712
13728
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PartComponent, decorators: [{
|
|
13713
13729
|
type: Component,
|
|
@@ -13723,7 +13739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
13723
13739
|
'[attr.data-referencepart]': `part.referencePart() ? '' : null`,
|
|
13724
13740
|
'[attr.tabindex]': '-1',
|
|
13725
13741
|
'[class]': 'part.classList.asList()',
|
|
13726
|
-
}, 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"] }]
|
|
13727
13743
|
}], ctorParameters: () => [] });
|
|
13728
13744
|
|
|
13729
13745
|
/*
|
|
@@ -13794,7 +13810,9 @@ class ɵWorkbenchPart {
|
|
|
13794
13810
|
views;
|
|
13795
13811
|
classList = new ClassList();
|
|
13796
13812
|
portal;
|
|
13797
|
-
|
|
13813
|
+
partBounds;
|
|
13814
|
+
/** Represents the bounds of the slot. Used for public API. Internally, use {@link slot.bounds()} instead. */
|
|
13815
|
+
bounds = computed(() => this.slot.bounds(), { ...(ngDevMode ? { debugName: "bounds" } : {}) });
|
|
13798
13816
|
blockedBy;
|
|
13799
13817
|
slot;
|
|
13800
13818
|
_isInMainArea;
|
|
@@ -13807,7 +13825,7 @@ class ɵWorkbenchPart {
|
|
|
13807
13825
|
this.views = computeViews(this.mPart);
|
|
13808
13826
|
this.alternativeId = this.mPart().alternativeId;
|
|
13809
13827
|
this.portal = this.createPartPortal();
|
|
13810
|
-
this.
|
|
13828
|
+
this.partBounds = boundingClientRect(computed(() => this.portal.element()));
|
|
13811
13829
|
this.blockedBy = inject(WorkbenchDialogRegistry).top(this.id);
|
|
13812
13830
|
this.slot = {
|
|
13813
13831
|
portal: this.createPartSlotPortal(),
|
|
@@ -14069,7 +14087,7 @@ function computePartActions(part) {
|
|
|
14069
14087
|
changes?.forEachAddedItem(({ item: fn }) => partActions.set(fn, computed(() => constructPartAction(fn, injector))));
|
|
14070
14088
|
changes?.forEachRemovedItem(({ item: fn }) => partActions.delete(fn));
|
|
14071
14089
|
return Array.from(partActions.values()).map(partAction => partAction()).filter(partAction => !!partAction);
|
|
14072
|
-
}, { equal: (a, b) =>
|
|
14090
|
+
}, { equal: (a, b) => Objects.isEqual(a, b) });
|
|
14073
14091
|
function constructPartAction(factoryFn, injector) {
|
|
14074
14092
|
const action = runInInjectionContext(injector, () => factoryFn(inject(ɵWorkbenchPart)));
|
|
14075
14093
|
if (action instanceof TemplateRef || typeof action === 'function') {
|
|
@@ -14090,7 +14108,7 @@ function computeActiveView(mPart) {
|
|
|
14090
14108
|
*/
|
|
14091
14109
|
function computeViews(mPart) {
|
|
14092
14110
|
const viewRegistry = inject(WorkbenchViewRegistry);
|
|
14093
|
-
return computed(() => mPart().views.map(mView => viewRegistry.get(mView.id)), { equal: (a, b) =>
|
|
14111
|
+
return computed(() => mPart().views.map(mView => viewRegistry.get(mView.id)), { equal: (a, b) => Objects.isEqual(a, b) });
|
|
14094
14112
|
}
|
|
14095
14113
|
|
|
14096
14114
|
/*
|
|
@@ -15244,8 +15262,7 @@ class MicrofrontendViewComponent {
|
|
|
15244
15262
|
installNavigator() {
|
|
15245
15263
|
// Use a root effect to emit even if detached from change detection.
|
|
15246
15264
|
toRootObservable(this.navigationContext)
|
|
15247
|
-
.pipe(tap(context => this.onPreNavigate(context)), filter((context) => !!context.capability), delayIfLazy(), serializeExecution(context => this.onNavigate(context)),
|
|
15248
|
-
takeUntilDestroyed())
|
|
15265
|
+
.pipe(tap(context => this.onPreNavigate(context)), filter((context) => !!context.capability), delayIfLazy(), serializeExecution(context => this.onNavigate(context)), takeUntilDestroyed())
|
|
15249
15266
|
.subscribe();
|
|
15250
15267
|
}
|
|
15251
15268
|
/**
|
|
@@ -15268,6 +15285,7 @@ class MicrofrontendViewComponent {
|
|
|
15268
15285
|
}),
|
|
15269
15286
|
referrer: navigationData.referrer,
|
|
15270
15287
|
}),
|
|
15288
|
+
equal: (a, b) => a.capability?.metadata.id === b.capability?.metadata.id && Objects.isEqual(a.params, b.params), // do not create new navigation context when navigating to the same capability with the same params
|
|
15271
15289
|
});
|
|
15272
15290
|
}
|
|
15273
15291
|
/**
|
|
@@ -15483,7 +15501,7 @@ class MicrofrontendViewComponent {
|
|
|
15483
15501
|
}
|
|
15484
15502
|
}))
|
|
15485
15503
|
.map(accelerator => `keydown.${accelerator.join('.')}{preventDefault=true}`);
|
|
15486
|
-
}, { equal: (a, b) =>
|
|
15504
|
+
}, { equal: (a, b) => Objects.isEqual(a, b, { ignoreArrayOrder: true }) });
|
|
15487
15505
|
}
|
|
15488
15506
|
propagateWorkbenchTheme() {
|
|
15489
15507
|
Microfrontends.propagateTheme(this._routerOutletElement);
|
|
@@ -15570,6 +15588,12 @@ class ActivatedMicrofrontend {
|
|
|
15570
15588
|
* Embeds the microfrontend of a capability provided by the workbench host application.
|
|
15571
15589
|
*/
|
|
15572
15590
|
class MicrofrontendHostComponent {
|
|
15591
|
+
/**
|
|
15592
|
+
* Parameters passed to the microfrontend, required to reduce inputs for notification capabilities.
|
|
15593
|
+
*
|
|
15594
|
+
* @see MicrofrontendNotificationIntentHandler
|
|
15595
|
+
*/
|
|
15596
|
+
params = input(undefined, { ...(ngDevMode ? { debugName: "params" } : {}) });
|
|
15573
15597
|
_logger = inject(Logger);
|
|
15574
15598
|
workbenchElement = inject(WORKBENCH_ELEMENT);
|
|
15575
15599
|
capability = inject(ActivatedMicrofrontend).capability;
|
|
@@ -15605,7 +15629,7 @@ class MicrofrontendHostComponent {
|
|
|
15605
15629
|
});
|
|
15606
15630
|
}
|
|
15607
15631
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15608
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
15632
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.1", type: MicrofrontendHostComponent, isStandalone: true, selector: "wb-microfrontend-host", inputs: { params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-capabilityid": "capability().metadata!.id", "attr.data-app": "capability().metadata!.appSymbolicName", "attr.data-focus": "workbenchElement.focused() ? '' : null" } }, providers: [
|
|
15609
15633
|
// Provide `ActivatedMicrofrontend` for DI in router outlet. Otherwise, `ActivatedMicrofrontend` would not be available, most likely because provided on the route level.
|
|
15610
15634
|
// TODO [Angular 22] Check if still required. If not, remove this TODO.
|
|
15611
15635
|
{ provide: ActivatedMicrofrontend, useFactory: () => inject(ActivatedMicrofrontend, { skipSelf: true }) },
|
|
@@ -15625,7 +15649,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
15625
15649
|
// TODO [Angular 22] Check if still required. If not, remove this TODO.
|
|
15626
15650
|
{ provide: ActivatedMicrofrontend, useFactory: () => inject(ActivatedMicrofrontend, { skipSelf: true }) },
|
|
15627
15651
|
], template: "<router-outlet [name]=\"outlet()\" wbRouterOutletRootContext/>\n", styles: [":host{display:grid}:host>router-outlet{position:absolute}\n"] }]
|
|
15628
|
-
}], ctorParameters: () => [] });
|
|
15652
|
+
}], ctorParameters: () => [], propDecorators: { params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: false }] }] } });
|
|
15629
15653
|
|
|
15630
15654
|
/*
|
|
15631
15655
|
* Copyright (c) 2018-2025 Swiss Federal Railways
|
|
@@ -15758,7 +15782,7 @@ function provideMicrofrontendViewRoute() {
|
|
|
15758
15782
|
path: '',
|
|
15759
15783
|
component: MicrofrontendHostComponent,
|
|
15760
15784
|
canMatch: [canMatchMicrofrontendView({ host: true })], // use a single matcher because Angular evaluates matchers in parallel
|
|
15761
|
-
providers: [provideActivatedMicrofrontend$
|
|
15785
|
+
providers: [provideActivatedMicrofrontend$5()],
|
|
15762
15786
|
}),
|
|
15763
15787
|
multi: true,
|
|
15764
15788
|
},
|
|
@@ -15792,7 +15816,7 @@ function canMatchMicrofrontendView(matcher) {
|
|
|
15792
15816
|
/**
|
|
15793
15817
|
* Provides {@link ActivatedMicrofrontend} for injection in the host microfrontend.
|
|
15794
15818
|
*/
|
|
15795
|
-
function provideActivatedMicrofrontend$
|
|
15819
|
+
function provideActivatedMicrofrontend$5() {
|
|
15796
15820
|
return {
|
|
15797
15821
|
provide: ActivatedMicrofrontend,
|
|
15798
15822
|
useFactory: () => {
|
|
@@ -16078,7 +16102,7 @@ function provideMicrofrontendPartRoute() {
|
|
|
16078
16102
|
path: '',
|
|
16079
16103
|
component: MicrofrontendHostComponent,
|
|
16080
16104
|
canMatch: [canMatchMicrofrontendPart({ host: true })], // use a single matcher because Angular evaluates matchers in parallel
|
|
16081
|
-
providers: [provideActivatedMicrofrontend$
|
|
16105
|
+
providers: [provideActivatedMicrofrontend$4()],
|
|
16082
16106
|
}),
|
|
16083
16107
|
multi: true,
|
|
16084
16108
|
},
|
|
@@ -16112,7 +16136,7 @@ function canMatchMicrofrontendPart(matcher) {
|
|
|
16112
16136
|
/**
|
|
16113
16137
|
* Provides {@link ActivatedMicrofrontend} for injection in the host microfrontend.
|
|
16114
16138
|
*/
|
|
16115
|
-
function provideActivatedMicrofrontend$
|
|
16139
|
+
function provideActivatedMicrofrontend$4() {
|
|
16116
16140
|
return {
|
|
16117
16141
|
provide: ActivatedMicrofrontend,
|
|
16118
16142
|
useFactory: () => {
|
|
@@ -16145,9 +16169,9 @@ class ParamValidator {
|
|
|
16145
16169
|
validatePartParams(params, partCapability, context) {
|
|
16146
16170
|
const { perspectiveCapability, partId } = context;
|
|
16147
16171
|
return this.validateParams(params, partCapability, {
|
|
16148
|
-
deprecated: param => `[PerspectiveDefinitionWarning] Perspective '${qualifier$
|
|
16149
|
-
missing: param => `[PerspectiveDefinitionError] Perspective '${qualifier$
|
|
16150
|
-
unexpected: param => `[PerspectiveDefinitionError] Perspective '${qualifier$
|
|
16172
|
+
deprecated: param => `[PerspectiveDefinitionWarning] Perspective '${qualifier$8(perspectiveCapability)}' of app '${app$8(perspectiveCapability)}' passes the deprecated parameter '${param}' to part '${partId}'. Migrate deprecated parameters as specified in the capability documentation of part '${qualifier$8(partCapability)}'.`,
|
|
16173
|
+
missing: param => `[PerspectiveDefinitionError] Perspective '${qualifier$8(perspectiveCapability)}' of app '${app$8(perspectiveCapability)}' does not pass the required parameter '${param}' to part '${partId}'. Pass required parameters as specified in the capability documentation of part '${qualifier$8(partCapability)}'. Ignoring part.`,
|
|
16174
|
+
unexpected: param => `[PerspectiveDefinitionError] Perspective '${qualifier$8(perspectiveCapability)}' of app '${app$8(perspectiveCapability)}' passes the unexpected parameter '${param}' to part '${partId}'. Pass parameters as specified in the capability documentation of part '${qualifier$8(partCapability)}'. Ignoring part.`,
|
|
16151
16175
|
});
|
|
16152
16176
|
}
|
|
16153
16177
|
/**
|
|
@@ -16158,9 +16182,9 @@ class ParamValidator {
|
|
|
16158
16182
|
validateViewParams(params, viewCapability, context) {
|
|
16159
16183
|
const { partCapability } = context;
|
|
16160
16184
|
return this.validateParams(params, viewCapability, {
|
|
16161
|
-
deprecated: param => `[PartDefinitionWarning] Part '${qualifier$
|
|
16162
|
-
missing: param => `[PartDefinitionError] Part '${qualifier$
|
|
16163
|
-
unexpected: param => `[PartDefinitionError] Part '${qualifier$
|
|
16185
|
+
deprecated: param => `[PartDefinitionWarning] Part '${qualifier$8(partCapability)}' of app '${app$8(partCapability)}' passes the deprecated parameter '${param}' to view '${qualifier$8(viewCapability)}'. Migrate deprecated parameters as specified in the capability documentation.`,
|
|
16186
|
+
missing: param => `[PartDefinitionError] Part '${qualifier$8(partCapability)}' of app '${app$8(partCapability)}' does not pass the required parameter '${param}' to view '${qualifier$8(viewCapability)}'. Pass required parameters as specified in the capability documentation. Ignoring view.`,
|
|
16187
|
+
unexpected: param => `[PartDefinitionError] Part '${qualifier$8(partCapability)}' of app '${app$8(partCapability)}' passes the unexpected parameter '${param}' to view '${qualifier$8(viewCapability)}'. Pass parameters as specified in the capability documentation. Ignoring view.`,
|
|
16164
16188
|
});
|
|
16165
16189
|
}
|
|
16166
16190
|
validateParams(params, capability, messageFactory) {
|
|
@@ -16188,13 +16212,13 @@ class ParamValidator {
|
|
|
16188
16212
|
/**
|
|
16189
16213
|
* Returns the qualifier as string.
|
|
16190
16214
|
*/
|
|
16191
|
-
function qualifier$
|
|
16215
|
+
function qualifier$8(capability) {
|
|
16192
16216
|
return Objects.toMatrixNotation(capability.qualifier);
|
|
16193
16217
|
}
|
|
16194
16218
|
/**
|
|
16195
16219
|
* Returns the app symbolic name.
|
|
16196
16220
|
*/
|
|
16197
|
-
function app$
|
|
16221
|
+
function app$8(capability) {
|
|
16198
16222
|
return capability.metadata.appSymbolicName;
|
|
16199
16223
|
}
|
|
16200
16224
|
|
|
@@ -16303,7 +16327,7 @@ class MicrofrontendPerspectiveInstaller {
|
|
|
16303
16327
|
// If a relative aligned part and the reference part cannot be found, ignore the part.
|
|
16304
16328
|
// Do not log an error to support conditional parts, i.e., if aligned relative to a conditional docked part.
|
|
16305
16329
|
if (typeof partRef.position === 'object' && partRef.position.relativeTo && !layout.hasPart(partRef.position.relativeTo)) {
|
|
16306
|
-
this._logger.debug(`[PerspectiveDefinitionInfo] Perspective '${qualifier$
|
|
16330
|
+
this._logger.debug(`[PerspectiveDefinitionInfo] Perspective '${qualifier$7(perspectiveCapability)}' of app '${app$7(perspectiveCapability)}' aligns part '${partRef.id}' relative to missing part '${partRef.position.relativeTo}'. The reference part may not be available. Ignoring part.`, LoggerNames.MICROFRONTEND);
|
|
16307
16331
|
return layout;
|
|
16308
16332
|
}
|
|
16309
16333
|
// If capability cannot be found, ignore the part if docked, or add an empty part otherwise, required to support layouts with conditional reference parts.
|
|
@@ -16420,13 +16444,13 @@ class MicrofrontendPerspectiveInstaller {
|
|
|
16420
16444
|
}
|
|
16421
16445
|
}
|
|
16422
16446
|
if (visibleCapabilities.length > 1) {
|
|
16423
|
-
this._logger.error(`[PerspectiveDefinitionError] Multiple ${type} capabilities found for qualifier '${Objects.toMatrixNotation(qualifier)}' in ${requester.type} '${Objects.toMatrixNotation(requester.qualifier)}' of app '${app$
|
|
16447
|
+
this._logger.error(`[PerspectiveDefinitionError] Multiple ${type} capabilities found for qualifier '${Objects.toMatrixNotation(qualifier)}' in ${requester.type} '${Objects.toMatrixNotation(requester.qualifier)}' of app '${app$7(requester)}'. Defaulting to first. Ensure ${type} capabilities to have a unique qualifier.`, LoggerNames.MICROFRONTEND);
|
|
16424
16448
|
}
|
|
16425
16449
|
else if (!visibleCapabilities.length && capabilities.length) {
|
|
16426
|
-
this._logger.error(`[PerspectiveDefinitionError] Application '${app$
|
|
16450
|
+
this._logger.error(`[PerspectiveDefinitionError] Application '${app$7(requester)}' is not qualified to use ${type} capability '${Objects.toMatrixNotation(qualifier)}' in ${requester.type} '${Objects.toMatrixNotation(requester.qualifier)}'. Ensure to have declared an intention and the capability is not private.`, LoggerNames.MICROFRONTEND);
|
|
16427
16451
|
}
|
|
16428
16452
|
else if (!visibleCapabilities.length) {
|
|
16429
|
-
const message = `No ${type} capability found for qualifier '${Objects.toMatrixNotation(qualifier)}' in ${requester.type} '${Objects.toMatrixNotation(requester.qualifier)}' of app '${app$
|
|
16453
|
+
const message = `No ${type} capability found for qualifier '${Objects.toMatrixNotation(qualifier)}' in ${requester.type} '${Objects.toMatrixNotation(requester.qualifier)}' of app '${app$7(requester)}'. The qualifier may be incorrect, the capability not registered, or the providing application not available.`;
|
|
16430
16454
|
if (context.logLevelIfEmpty === 'error') {
|
|
16431
16455
|
this._logger.error(`[PerspectiveDefinitionError] ${message}`, LoggerNames.MICROFRONTEND);
|
|
16432
16456
|
}
|
|
@@ -16447,14 +16471,14 @@ class MicrofrontendPerspectiveInstaller {
|
|
|
16447
16471
|
// Validate main area part not to have views.
|
|
16448
16472
|
const isMainAreaPart = partRef.id === MAIN_AREA || partRef.id === MAIN_AREA_ALTERNATIVE_ID;
|
|
16449
16473
|
if (isMainAreaPart && partCapability.properties?.views?.length) {
|
|
16450
|
-
this._logger.error(`[PerspectiveDefinitionError] Part '${qualifier$
|
|
16474
|
+
this._logger.error(`[PerspectiveDefinitionError] Part '${qualifier$7(partCapability)}' of app '${app$7(partCapability)}' is used as main area part in perspective '${qualifier$7(context.perspectiveCapability)}' and defines views. Views cannot be added to the main area of a perspective. Ignoring part.`, LoggerNames.MICROFRONTEND);
|
|
16451
16475
|
return false;
|
|
16452
16476
|
}
|
|
16453
16477
|
// Validate extras of docked part.
|
|
16454
16478
|
if ('position' in partRef && typeof partRef.position === 'string') {
|
|
16455
16479
|
const dockedPartExtras = partCapability.properties?.extras;
|
|
16456
16480
|
if (!dockedPartExtras?.label || !dockedPartExtras.icon) {
|
|
16457
|
-
this._logger.error(`[PerspectiveDefinitionError] Part '${qualifier$
|
|
16481
|
+
this._logger.error(`[PerspectiveDefinitionError] Part '${qualifier$7(partCapability)}' of app '${app$7(partCapability)}' is used as a docked part in perspective '${qualifier$7(context.perspectiveCapability)}' but does not define an icon and label. A docked part must define both an icon and a label: { properties: { extras: { icon: '<icon-name>', label: '<text>' } } }. Ignoring part.`, LoggerNames.MICROFRONTEND);
|
|
16458
16482
|
return false;
|
|
16459
16483
|
}
|
|
16460
16484
|
}
|
|
@@ -16476,13 +16500,13 @@ function createCapabilityRemoteTranslatable(translatable, capability, params) {
|
|
|
16476
16500
|
/**
|
|
16477
16501
|
* Returns the qualifier as string.
|
|
16478
16502
|
*/
|
|
16479
|
-
function qualifier$
|
|
16503
|
+
function qualifier$7(capability) {
|
|
16480
16504
|
return Objects.toMatrixNotation(capability.qualifier);
|
|
16481
16505
|
}
|
|
16482
16506
|
/**
|
|
16483
16507
|
* Returns the app symbolic name.
|
|
16484
16508
|
*/
|
|
16485
|
-
function app$
|
|
16509
|
+
function app$7(capability) {
|
|
16486
16510
|
return capability.metadata.appSymbolicName;
|
|
16487
16511
|
}
|
|
16488
16512
|
|
|
@@ -16636,61 +16660,61 @@ class MicrofrontendPerspectiveCapabilityValidator {
|
|
|
16636
16660
|
const perspectiveCapability = capability;
|
|
16637
16661
|
// Assert the perspective capability to have a qualifier.
|
|
16638
16662
|
if (!Object.keys(perspectiveCapability.qualifier ?? {}).length) {
|
|
16639
|
-
throw Error(`[PerspectiveDefinitionError] Perspective capability requires a qualifier [app=${app$
|
|
16663
|
+
throw Error(`[PerspectiveDefinitionError] Perspective capability requires a qualifier [app=${app$6(perspectiveCapability)}, perspective=${JSON.stringify(perspectiveCapability)}]`);
|
|
16640
16664
|
}
|
|
16641
16665
|
// Assert the perspective capability to have properties.
|
|
16642
16666
|
if (!perspectiveCapability.properties) {
|
|
16643
|
-
throw Error(`[PerspectiveDefinitionError] Perspective capability requires properties [app=${app$
|
|
16667
|
+
throw Error(`[PerspectiveDefinitionError] Perspective capability requires properties [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16644
16668
|
}
|
|
16645
16669
|
// Assert the perspective capability to have parts.
|
|
16646
16670
|
if (!perspectiveCapability.properties.parts) {
|
|
16647
|
-
throw Error(`[PerspectiveDefinitionError] Perspective capability requires the 'parts' property [app=${app$
|
|
16671
|
+
throw Error(`[PerspectiveDefinitionError] Perspective capability requires the 'parts' property [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16648
16672
|
}
|
|
16649
16673
|
// Assert parts to have an id.
|
|
16650
16674
|
const parts = perspectiveCapability.properties.parts;
|
|
16651
16675
|
parts.forEach((part, index) => {
|
|
16652
16676
|
if (!part.id) {
|
|
16653
|
-
throw Error(`[PerspectiveDefinitionError] Missing required 'id' property of part at index '${index}' [app=${app$
|
|
16677
|
+
throw Error(`[PerspectiveDefinitionError] Missing required 'id' property of part at index '${index}' [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16654
16678
|
}
|
|
16655
16679
|
});
|
|
16656
16680
|
// Assert unique part ids.
|
|
16657
16681
|
if (new Set(parts.map(part => part.id)).size !== parts.length) {
|
|
16658
|
-
throw Error(`[PerspectiveDefinitionError] Parts of perspective must have a unique id [app=${app$
|
|
16682
|
+
throw Error(`[PerspectiveDefinitionError] Parts of perspective must have a unique id [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16659
16683
|
}
|
|
16660
16684
|
// Assert the perspective capability to have an initial part.
|
|
16661
16685
|
const [initialPart, ...otherParts] = parts;
|
|
16662
16686
|
if (!initialPart) {
|
|
16663
|
-
throw Error(`[PerspectiveDefinitionError] Perspective capability requires an initial part [app=${app$
|
|
16687
|
+
throw Error(`[PerspectiveDefinitionError] Perspective capability requires an initial part [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16664
16688
|
}
|
|
16665
16689
|
// Assert initial part not to be positioned.
|
|
16666
16690
|
if (initialPart.position) {
|
|
16667
|
-
throw Error(`[PerspectiveDefinitionError] Initial part '${initialPart.id}' of perspective must not have the 'position' property [app=${app$
|
|
16691
|
+
throw Error(`[PerspectiveDefinitionError] Initial part '${initialPart.id}' of perspective must not have the 'position' property [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16668
16692
|
}
|
|
16669
16693
|
// Assert other parts to be positioned.
|
|
16670
16694
|
otherParts.forEach(part => {
|
|
16671
16695
|
if (!part.position) {
|
|
16672
|
-
throw Error(`[PerspectiveDefinitionError] Missing required 'position' property in part '${part.id}' [app=${app$
|
|
16696
|
+
throw Error(`[PerspectiveDefinitionError] Missing required 'position' property in part '${part.id}' [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16673
16697
|
}
|
|
16674
16698
|
if (typeof part.position === 'string' && !dockingAreas.has(part.position)) {
|
|
16675
|
-
throw Error(`[PerspectiveDefinitionError] Illegal position in docked part '${part.id}': '${part.position}'. Must be one of [${[...dockingAreas].join(',')}] [app=${app$
|
|
16699
|
+
throw Error(`[PerspectiveDefinitionError] Illegal position in docked part '${part.id}': '${part.position}'. Must be one of [${[...dockingAreas].join(',')}] [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16676
16700
|
}
|
|
16677
16701
|
if (typeof part.position === 'object' && !part.position.align) {
|
|
16678
|
-
throw Error(`[PerspectiveDefinitionError] Missing required 'align' property in part '${part.id}': { position: { align: 'left|right|top|bottom' } } [app=${app$
|
|
16702
|
+
throw Error(`[PerspectiveDefinitionError] Missing required 'align' property in part '${part.id}': { position: { align: 'left|right|top|bottom' } } [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16679
16703
|
}
|
|
16680
16704
|
if (typeof part.position === 'object' && !align.has(part.position.align)) {
|
|
16681
|
-
throw Error(`[PerspectiveDefinitionError] Illegal alignment of part '${part.id}': '${part.position.align}'. Must be one of [${[...align].join(',')}] [app=${app$
|
|
16705
|
+
throw Error(`[PerspectiveDefinitionError] Illegal alignment of part '${part.id}': '${part.position.align}'. Must be one of [${[...align].join(',')}] [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16682
16706
|
}
|
|
16683
16707
|
if (typeof part.position === 'object' && part.position.relativeTo && !parts.some(otherPart => otherPart.id === part.position.relativeTo)) {
|
|
16684
|
-
throw Error(`[PerspectiveDefinitionError] Illegal part '${part.position.relativeTo}' referenced in 'relativeTo' of part '${part.id}'. Part not found. [app=${app$
|
|
16708
|
+
throw Error(`[PerspectiveDefinitionError] Illegal part '${part.position.relativeTo}' referenced in 'relativeTo' of part '${part.id}'. Part not found. [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16685
16709
|
}
|
|
16686
16710
|
});
|
|
16687
16711
|
// Assert parts to have a qualifier.
|
|
16688
16712
|
parts.forEach(part => {
|
|
16689
16713
|
if (!Object.keys(part.qualifier ?? {}).length) {
|
|
16690
|
-
throw Error(`[PerspectiveDefinitionError] Missing required qualifier for part '${part.id}' [app=${app$
|
|
16714
|
+
throw Error(`[PerspectiveDefinitionError] Missing required qualifier for part '${part.id}' [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16691
16715
|
}
|
|
16692
16716
|
if (Object.entries(part.qualifier).some(([key, value]) => key === '*' || value === '*')) {
|
|
16693
|
-
throw Error(`[PerspectiveDefinitionError] Qualifier for part '${part.id}' must be explicit and not contain wildcards: '${Objects.toMatrixNotation(part.qualifier)}' [app=${app$
|
|
16717
|
+
throw Error(`[PerspectiveDefinitionError] Qualifier for part '${part.id}' must be explicit and not contain wildcards: '${Objects.toMatrixNotation(part.qualifier)}' [app=${app$6(perspectiveCapability)}, perspective=${qualifier$6(perspectiveCapability)}]`);
|
|
16694
16718
|
}
|
|
16695
16719
|
});
|
|
16696
16720
|
return capability;
|
|
@@ -16704,13 +16728,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
16704
16728
|
/**
|
|
16705
16729
|
* Returns the qualifier as string.
|
|
16706
16730
|
*/
|
|
16707
|
-
function qualifier$
|
|
16731
|
+
function qualifier$6(capability) {
|
|
16708
16732
|
return Objects.toMatrixNotation(capability.qualifier);
|
|
16709
16733
|
}
|
|
16710
16734
|
/**
|
|
16711
16735
|
* Returns the app symbolic name.
|
|
16712
16736
|
*/
|
|
16713
|
-
function app$
|
|
16737
|
+
function app$6(capability) {
|
|
16714
16738
|
return capability.metadata.appSymbolicName;
|
|
16715
16739
|
}
|
|
16716
16740
|
const dockingAreas = new Set()
|
|
@@ -16840,24 +16864,24 @@ class MicrofrontendPartCapabilityValidator {
|
|
|
16840
16864
|
const partCapability = capability;
|
|
16841
16865
|
// Assert the part capability to have a qualifier.
|
|
16842
16866
|
if (!Object.keys(partCapability.qualifier ?? {}).length) {
|
|
16843
|
-
throw Error(`[PartDefinitionError] Part capability requires a qualifier [app=${app$
|
|
16867
|
+
throw Error(`[PartDefinitionError] Part capability requires a qualifier [app=${app$5(partCapability)}, part=${JSON.stringify(partCapability)}]`);
|
|
16844
16868
|
}
|
|
16845
16869
|
// Assert docked part extras, if set.
|
|
16846
16870
|
if (partCapability.properties?.extras) {
|
|
16847
16871
|
if (!partCapability.properties.extras.icon) {
|
|
16848
|
-
throw Error(`[PartDefinitionError] Missing required 'icon' property in docked part extras [app=${app$
|
|
16872
|
+
throw Error(`[PartDefinitionError] Missing required 'icon' property in docked part extras [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16849
16873
|
}
|
|
16850
16874
|
if (!partCapability.properties.extras.label) {
|
|
16851
|
-
throw Error(`[PartDefinitionError] Missing required 'label' property in docked part extras [app=${app$
|
|
16875
|
+
throw Error(`[PartDefinitionError] Missing required 'label' property in docked part extras [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16852
16876
|
}
|
|
16853
16877
|
}
|
|
16854
16878
|
// Assert referenced views to have a qualifier.
|
|
16855
16879
|
partCapability.properties?.views?.forEach((view) => {
|
|
16856
16880
|
if (!Object.keys(view.qualifier ?? {}).length) {
|
|
16857
|
-
throw Error(`[PartDefinitionError] Missing required qualifier for view [app=${app$
|
|
16881
|
+
throw Error(`[PartDefinitionError] Missing required qualifier for view [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16858
16882
|
}
|
|
16859
16883
|
if (Object.entries(view.qualifier).some(([key, value]) => key === '*' || value === '*')) {
|
|
16860
|
-
throw Error(`[PartDefinitionError] View qualifier must be explicit and not contain wildcards: '${Objects.toMatrixNotation(view.qualifier)}' [app=${app$
|
|
16884
|
+
throw Error(`[PartDefinitionError] View qualifier must be explicit and not contain wildcards: '${Objects.toMatrixNotation(view.qualifier)}' [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16861
16885
|
}
|
|
16862
16886
|
});
|
|
16863
16887
|
// Assert the path of the part capability.
|
|
@@ -16866,11 +16890,11 @@ class MicrofrontendPartCapabilityValidator {
|
|
|
16866
16890
|
}
|
|
16867
16891
|
// Assert host part capabilities not to define the "showSplash" property.
|
|
16868
16892
|
if (Microfrontends.isHostProvider(capability) && partCapability.properties?.showSplash !== undefined) {
|
|
16869
|
-
throw Error(`[PartDefinitionError] Property "showSplash" not supported for part capabilities of the host application [app=${app$
|
|
16893
|
+
throw Error(`[PartDefinitionError] Property "showSplash" not supported for part capabilities of the host application [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16870
16894
|
}
|
|
16871
16895
|
// Assert "showSplash" property not to be defined if part has no path.
|
|
16872
16896
|
if (partCapability.properties?.path === undefined && partCapability.properties?.showSplash !== undefined) {
|
|
16873
|
-
throw Error(`[PartDefinitionError] Property "showSplash" only supported for part capabilities with a path [app=${app$
|
|
16897
|
+
throw Error(`[PartDefinitionError] Property "showSplash" only supported for part capabilities with a path [app=${app$5(partCapability)}, part=${qualifier$5(partCapability)}]`);
|
|
16874
16898
|
}
|
|
16875
16899
|
return capability;
|
|
16876
16900
|
}
|
|
@@ -16878,12 +16902,12 @@ class MicrofrontendPartCapabilityValidator {
|
|
|
16878
16902
|
const path = capability.properties?.path;
|
|
16879
16903
|
if (Microfrontends.isHostProvider(capability)) {
|
|
16880
16904
|
if (path === null || path.length) {
|
|
16881
|
-
throw Error(`[PartDefinitionError] Part capabilities of the host application require an empty path. [app=${app$
|
|
16905
|
+
throw Error(`[PartDefinitionError] Part capabilities of the host application require an empty path. [app=${app$5(capability)}, part=${qualifier$5(capability)}]. Change the path '${path}' to empty and add 'canMatchWorkbenchPartCapability(${JSON.stringify(capability.qualifier)})' guard to the route.\n\nExample:\nCapability: { type: 'part', qualifier: ${JSON.stringify(capability.qualifier)}, properties: {path: ''} }\nRoute: { path: '', canMatch: [canMatchWorkbenchPartCapability(${JSON.stringify(capability.qualifier)})], component: PartComponent }`);
|
|
16882
16906
|
}
|
|
16883
16907
|
}
|
|
16884
16908
|
else {
|
|
16885
16909
|
if (path === null) {
|
|
16886
|
-
throw Error(`[PartDefinitionError] Part capabilities require a path. [app=${app$
|
|
16910
|
+
throw Error(`[PartDefinitionError] Part capabilities require a path. [app=${app$5(capability)}, part=${qualifier$5(capability)}]`);
|
|
16887
16911
|
}
|
|
16888
16912
|
}
|
|
16889
16913
|
}
|
|
@@ -16896,13 +16920,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
16896
16920
|
/**
|
|
16897
16921
|
* Returns the qualifier as string.
|
|
16898
16922
|
*/
|
|
16899
|
-
function qualifier$
|
|
16923
|
+
function qualifier$5(capability) {
|
|
16900
16924
|
return Objects.toMatrixNotation(capability.qualifier);
|
|
16901
16925
|
}
|
|
16902
16926
|
/**
|
|
16903
16927
|
* Returns the app symbolic name.
|
|
16904
16928
|
*/
|
|
16905
|
-
function app$
|
|
16929
|
+
function app$5(capability) {
|
|
16906
16930
|
return capability.metadata.appSymbolicName;
|
|
16907
16931
|
}
|
|
16908
16932
|
|
|
@@ -17391,21 +17415,21 @@ class MicrofrontendViewCapabilityValidator {
|
|
|
17391
17415
|
const viewCapability = capability;
|
|
17392
17416
|
// Assert the view capability to have a qualifier.
|
|
17393
17417
|
if (!Object.keys(viewCapability.qualifier ?? {}).length) {
|
|
17394
|
-
throw Error(`[ViewDefinitionError] View capability requires a qualifier [app=${app$
|
|
17418
|
+
throw Error(`[ViewDefinitionError] View capability requires a qualifier [app=${app$4(viewCapability)}, view=${qualifier$4(viewCapability)}]`);
|
|
17395
17419
|
}
|
|
17396
17420
|
// Assert the view capability to have properties.
|
|
17397
17421
|
if (!viewCapability.properties) {
|
|
17398
|
-
throw Error(`[ViewDefinitionError] View capability requires properties [app=${app$
|
|
17422
|
+
throw Error(`[ViewDefinitionError] View capability requires properties [app=${app$4(viewCapability)}, view=${qualifier$4(viewCapability)}]`);
|
|
17399
17423
|
}
|
|
17400
17424
|
// Assert the view capability to have a path, unless provided by the host application.
|
|
17401
17425
|
this.assertPath(viewCapability);
|
|
17402
17426
|
// Assert host view capabilities not to define the "lazy" property.
|
|
17403
17427
|
if (Microfrontends.isHostProvider(capability) && viewCapability.properties.lazy !== undefined) {
|
|
17404
|
-
throw Error(`[ViewDefinitionError] Property "lazy" not supported for view capabilities of the host application [app=${app$
|
|
17428
|
+
throw Error(`[ViewDefinitionError] Property "lazy" not supported for view capabilities of the host application [app=${app$4(viewCapability)}, view=${qualifier$4(viewCapability)}]`);
|
|
17405
17429
|
}
|
|
17406
17430
|
// Assert host view capabilities not to define the "showSplash" property.
|
|
17407
17431
|
if (Microfrontends.isHostProvider(capability) && viewCapability.properties.showSplash !== undefined) {
|
|
17408
|
-
throw Error(`[ViewDefinitionError] Property "showSplash" not supported for view capabilities of the host application [app=${app$
|
|
17432
|
+
throw Error(`[ViewDefinitionError] Property "showSplash" not supported for view capabilities of the host application [app=${app$4(viewCapability)}, view=${qualifier$4(viewCapability)}]`);
|
|
17409
17433
|
}
|
|
17410
17434
|
return capability;
|
|
17411
17435
|
}
|
|
@@ -17413,12 +17437,12 @@ class MicrofrontendViewCapabilityValidator {
|
|
|
17413
17437
|
const path = capability.properties?.path;
|
|
17414
17438
|
if (Microfrontends.isHostProvider(capability)) {
|
|
17415
17439
|
if (path !== '') {
|
|
17416
|
-
throw Error(`[ViewDefinitionError] View capabilities of the host application require an empty path. [app=${app$
|
|
17440
|
+
throw Error(`[ViewDefinitionError] View capabilities of the host application require an empty path. [app=${app$4(capability)}, view=${qualifier$4(capability)}]. Change the path '${path}' to empty and add 'canMatchWorkbenchViewCapability(${JSON.stringify(capability.qualifier)})' guard to the route.\n\nExample:\nCapability: { type: 'view', qualifier: ${JSON.stringify(capability.qualifier)}, properties: {path: ''} }\nRoute: { path: '', canMatch: [canMatchWorkbenchViewCapability(${JSON.stringify(capability.qualifier)})], component: ViewComponent }`);
|
|
17417
17441
|
}
|
|
17418
17442
|
}
|
|
17419
17443
|
else {
|
|
17420
17444
|
if (path === null || path == undefined) {
|
|
17421
|
-
throw Error(`[ViewDefinitionError] View capabilities require a path. [app=${app$
|
|
17445
|
+
throw Error(`[ViewDefinitionError] View capabilities require a path. [app=${app$4(capability)}, view=${qualifier$4(capability)}]`);
|
|
17422
17446
|
}
|
|
17423
17447
|
}
|
|
17424
17448
|
}
|
|
@@ -17431,13 +17455,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
17431
17455
|
/**
|
|
17432
17456
|
* Returns the qualifier as string.
|
|
17433
17457
|
*/
|
|
17434
|
-
function qualifier$
|
|
17458
|
+
function qualifier$4(capability) {
|
|
17435
17459
|
return Objects.toMatrixNotation(capability.qualifier);
|
|
17436
17460
|
}
|
|
17437
17461
|
/**
|
|
17438
17462
|
* Returns the app symbolic name.
|
|
17439
17463
|
*/
|
|
17440
|
-
function app$
|
|
17464
|
+
function app$4(capability) {
|
|
17441
17465
|
return capability.metadata.appSymbolicName;
|
|
17442
17466
|
}
|
|
17443
17467
|
|
|
@@ -17637,9 +17661,107 @@ function provideMicrofrontendView() {
|
|
|
17637
17661
|
}
|
|
17638
17662
|
}
|
|
17639
17663
|
|
|
17664
|
+
/*
|
|
17665
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
17666
|
+
*
|
|
17667
|
+
* This program and the accompanying materials are made
|
|
17668
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
17669
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
17670
|
+
*
|
|
17671
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
17672
|
+
*/
|
|
17673
|
+
/**
|
|
17674
|
+
* Displays the notification for the built-in notification capability.
|
|
17675
|
+
*
|
|
17676
|
+
* This component is designed to be displayed in {@link MicrofrontendHostComponent}.
|
|
17677
|
+
*/
|
|
17678
|
+
class NotificationTextMessageComponent {
|
|
17679
|
+
message;
|
|
17680
|
+
constructor() {
|
|
17681
|
+
const { params, referrer } = inject(ActivatedMicrofrontend);
|
|
17682
|
+
const translatable = params().get(eNOTIFICATION_MESSAGE_PARAM);
|
|
17683
|
+
this.message = createRemoteTranslatable(translatable, { appSymbolicName: referrer() });
|
|
17684
|
+
}
|
|
17685
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationTextMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17686
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.1", type: NotificationTextMessageComponent, isStandalone: true, selector: "wb-notification-text-message", host: { properties: { "class.empty": "!message?.length" } }, ngImport: i0, template: "{{(message | wbText)()}}\n", styles: [":host{word-break:break-word;white-space:pre-line}:host.empty{display:none}\n"], dependencies: [{ kind: "pipe", type: TextPipe, name: "wbText" }] });
|
|
17687
|
+
}
|
|
17688
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationTextMessageComponent, decorators: [{
|
|
17689
|
+
type: Component,
|
|
17690
|
+
args: [{ selector: 'wb-notification-text-message', imports: [
|
|
17691
|
+
TextPipe,
|
|
17692
|
+
], host: {
|
|
17693
|
+
'[class.empty]': '!message?.length',
|
|
17694
|
+
}, template: "{{(message | wbText)()}}\n", styles: [":host{word-break:break-word;white-space:pre-line}:host.empty{display:none}\n"] }]
|
|
17695
|
+
}], ctorParameters: () => [] });
|
|
17696
|
+
/**
|
|
17697
|
+
* Property to identify the built-in text notification capability.
|
|
17698
|
+
*/
|
|
17699
|
+
const TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY = 'ɵidentity';
|
|
17700
|
+
/**
|
|
17701
|
+
* Value to identify the built-in text notification capability.
|
|
17702
|
+
*/
|
|
17703
|
+
const TEXT_NOTIFICATION_CAPABILITY_IDENTITY = UUID.randomUUID();
|
|
17704
|
+
|
|
17705
|
+
var notificationTextMessage_component = /*#__PURE__*/Object.freeze({
|
|
17706
|
+
__proto__: null,
|
|
17707
|
+
TEXT_NOTIFICATION_CAPABILITY_IDENTITY: TEXT_NOTIFICATION_CAPABILITY_IDENTITY,
|
|
17708
|
+
TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY: TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY,
|
|
17709
|
+
default: NotificationTextMessageComponent
|
|
17710
|
+
});
|
|
17711
|
+
|
|
17712
|
+
/*
|
|
17713
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
17714
|
+
*
|
|
17715
|
+
* This program and the accompanying materials are made
|
|
17716
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
17717
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
17718
|
+
*
|
|
17719
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
17720
|
+
*/
|
|
17721
|
+
/**
|
|
17722
|
+
* Intercepts the host manifest, registering the built-in text notification capability.
|
|
17723
|
+
*/
|
|
17724
|
+
class MicrofrontendTextNotificationCapabilityProvider {
|
|
17725
|
+
intercept(hostManifest) {
|
|
17726
|
+
hostManifest.capabilities = [
|
|
17727
|
+
...hostManifest.capabilities ?? [],
|
|
17728
|
+
provideBuiltInTextNotificationCapability(),
|
|
17729
|
+
];
|
|
17730
|
+
}
|
|
17731
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendTextNotificationCapabilityProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17732
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendTextNotificationCapabilityProvider });
|
|
17733
|
+
}
|
|
17734
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendTextNotificationCapabilityProvider, decorators: [{
|
|
17735
|
+
type: Injectable
|
|
17736
|
+
}] });
|
|
17737
|
+
/**
|
|
17738
|
+
* Provides the built-in notification capability to display text.
|
|
17739
|
+
*
|
|
17740
|
+
* @see MicrofrontendNotificationIntentHandler
|
|
17741
|
+
*/
|
|
17742
|
+
function provideBuiltInTextNotificationCapability() {
|
|
17743
|
+
return {
|
|
17744
|
+
type: WorkbenchCapabilities.Notification,
|
|
17745
|
+
qualifier: {},
|
|
17746
|
+
params: [
|
|
17747
|
+
{
|
|
17748
|
+
name: eNOTIFICATION_MESSAGE_PARAM,
|
|
17749
|
+
required: false,
|
|
17750
|
+
description: 'Text to display in the notification.',
|
|
17751
|
+
},
|
|
17752
|
+
],
|
|
17753
|
+
properties: {
|
|
17754
|
+
path: '',
|
|
17755
|
+
[TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY]: TEXT_NOTIFICATION_CAPABILITY_IDENTITY,
|
|
17756
|
+
},
|
|
17757
|
+
private: false,
|
|
17758
|
+
description: 'Displays a text notification.',
|
|
17759
|
+
};
|
|
17760
|
+
}
|
|
17761
|
+
|
|
17640
17762
|
/**
|
|
17641
|
-
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered.
|
|
17642
|
-
* It informs about system events, task completion or errors.
|
|
17763
|
+
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered or focused.
|
|
17764
|
+
* It informs about system events, task completion, or errors. Severity indicates importance or urgency.
|
|
17643
17765
|
*
|
|
17644
17766
|
* The notification component can inject this handle to interact with the notification.
|
|
17645
17767
|
*
|
|
@@ -17736,47 +17858,211 @@ class Notification {
|
|
|
17736
17858
|
* SPDX-License-Identifier: EPL-2.0
|
|
17737
17859
|
*/
|
|
17738
17860
|
/**
|
|
17739
|
-
*
|
|
17861
|
+
* TODO [Angular 22] Remove with Angular 22. Used for backward compatiblity.
|
|
17740
17862
|
*/
|
|
17741
|
-
class
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
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
|
+
}
|
|
17914
|
+
/**
|
|
17915
|
+
* Closes this notification when pressing escape if it is the most recently displayed notification.
|
|
17916
|
+
*/
|
|
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());
|
|
17750
17928
|
});
|
|
17751
|
-
this.top = computed(() => this.elements().at(-1), { ...(ngDevMode ? { debugName: "top" } : {}) });
|
|
17752
17929
|
}
|
|
17753
|
-
|
|
17754
|
-
|
|
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
|
+
};
|
|
17755
18037
|
}
|
|
17756
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationRegistry, decorators: [{
|
|
17757
|
-
type: Injectable,
|
|
17758
|
-
args: [{ providedIn: 'root' }]
|
|
17759
|
-
}], ctorParameters: () => [] });
|
|
17760
18038
|
|
|
17761
18039
|
/** @inheritDoc */
|
|
17762
18040
|
class ɵWorkbenchNotification {
|
|
17763
18041
|
id;
|
|
17764
18042
|
_options;
|
|
17765
18043
|
/** Injector for the notification; destroyed when the notification is closed. */
|
|
17766
|
-
|
|
18044
|
+
injector = inject(Injector);
|
|
17767
18045
|
slot;
|
|
17768
18046
|
_notificationRegistry = inject(WorkbenchNotificationRegistry);
|
|
18047
|
+
_focusMonitor = inject(WorkbenchFocusMonitor);
|
|
17769
18048
|
_title;
|
|
17770
18049
|
_severity;
|
|
17771
18050
|
_duration;
|
|
17772
18051
|
_cssClass;
|
|
18052
|
+
portal;
|
|
18053
|
+
size = new ɵWorkbenchNotificationSize();
|
|
18054
|
+
focused = computed(() => this._focusMonitor.activeElement()?.id === this.id, { ...(ngDevMode ? { debugName: "focused" } : {}) });
|
|
18055
|
+
/** Checks if this notification is the most recently displayed notification. */
|
|
18056
|
+
top = computed(() => this._notificationRegistry.top() === this, { ...(ngDevMode ? { debugName: "top" } : {}) });
|
|
17773
18057
|
destroyed = signal(false, { ...(ngDevMode ? { debugName: "destroyed" } : {}) });
|
|
18058
|
+
bounds;
|
|
18059
|
+
blockedBy;
|
|
17774
18060
|
group;
|
|
17775
18061
|
constructor(id, content, _options) {
|
|
17776
18062
|
this.id = id;
|
|
17777
18063
|
this._options = _options;
|
|
18064
|
+
this.portal = this.createPortal();
|
|
17778
18065
|
this.slot = {
|
|
17779
|
-
injector: this.createInjector(),
|
|
17780
18066
|
component: typeof content === 'function' ? content : undefined,
|
|
17781
18067
|
text: typeof content === 'string' ? content : undefined,
|
|
17782
18068
|
};
|
|
@@ -17785,24 +18071,25 @@ class ɵWorkbenchNotification {
|
|
|
17785
18071
|
this._duration = signal(this._options.duration ?? 'medium', { ...(ngDevMode ? { debugName: "_duration" } : {}) });
|
|
17786
18072
|
this._cssClass = signal(Arrays.coerce(this._options.cssClass), { ...(ngDevMode ? { debugName: "_cssClass" } : {}) });
|
|
17787
18073
|
this.group = this._options.group;
|
|
17788
|
-
this.
|
|
18074
|
+
this.blockedBy = inject(WorkbenchDialogRegistry).top(this.id);
|
|
18075
|
+
this.bounds = boundingClientRect(computed(() => this.portal.componentRef()?.instance.notificationSlotBounds()));
|
|
17789
18076
|
inject(DestroyRef).onDestroy(() => this.destroyed.set(true));
|
|
17790
18077
|
}
|
|
17791
18078
|
/**
|
|
17792
|
-
* Creates
|
|
18079
|
+
* Creates a portal to render {@link WorkbenchNotificationComponent} in the notification's injection context.
|
|
17793
18080
|
*/
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
18081
|
+
createPortal() {
|
|
18082
|
+
return new WbComponentPortal(WorkbenchNotificationComponent, {
|
|
18083
|
+
injector: this._options.injector,
|
|
17797
18084
|
providers: [
|
|
17798
18085
|
{ provide: ɵWorkbenchNotification, useValue: this },
|
|
17799
18086
|
{ provide: WorkbenchNotification, useExisting: ɵWorkbenchNotification },
|
|
17800
18087
|
{ provide: Notification, useClass: ɵNotification },
|
|
18088
|
+
{ provide: WORKBENCH_ELEMENT, useExisting: ɵWorkbenchNotification },
|
|
18089
|
+
inject(WORKBENCH_NOTIFICATION_CONTEXT, { optional: true }) ?? [],
|
|
17801
18090
|
...this._options.providers ?? [],
|
|
17802
18091
|
],
|
|
17803
18092
|
});
|
|
17804
|
-
inject(DestroyRef).onDestroy(() => injector.destroy());
|
|
17805
|
-
return injector;
|
|
17806
18093
|
}
|
|
17807
18094
|
/** @inheritDoc */
|
|
17808
18095
|
get title() {
|
|
@@ -17838,6 +18125,9 @@ class ɵWorkbenchNotification {
|
|
|
17838
18125
|
}
|
|
17839
18126
|
/** @inheritDoc */
|
|
17840
18127
|
close() {
|
|
18128
|
+
if (this.blockedBy()) {
|
|
18129
|
+
return;
|
|
18130
|
+
}
|
|
17841
18131
|
this.destroy();
|
|
17842
18132
|
}
|
|
17843
18133
|
/**
|
|
@@ -17846,33 +18136,175 @@ class ɵWorkbenchNotification {
|
|
|
17846
18136
|
get inputs() {
|
|
17847
18137
|
return this._options.inputs;
|
|
17848
18138
|
}
|
|
17849
|
-
/**
|
|
17850
|
-
* Closes the notification on escape keystroke, but only if this is the topmost notification.
|
|
17851
|
-
*/
|
|
17852
|
-
closeOnEscape() {
|
|
17853
|
-
const zone = inject(NgZone);
|
|
17854
|
-
const document = inject(DOCUMENT);
|
|
17855
|
-
const top = inject(WorkbenchNotificationRegistry).top;
|
|
17856
|
-
effect(onCleanup => {
|
|
17857
|
-
if (top() !== this) {
|
|
17858
|
-
return;
|
|
17859
|
-
}
|
|
17860
|
-
const subscription = fromEvent(document, 'keydown')
|
|
17861
|
-
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), filter((event) => event.key === 'Escape'), observeIn(fn => zone.run(fn)))
|
|
17862
|
-
.subscribe(() => this.close());
|
|
17863
|
-
onCleanup(() => subscription.unsubscribe());
|
|
17864
|
-
});
|
|
17865
|
-
}
|
|
17866
18139
|
/**
|
|
17867
18140
|
* Destroys this dialog and associated resources.
|
|
17868
18141
|
*/
|
|
17869
18142
|
destroy() {
|
|
17870
18143
|
if (!this.destroyed()) {
|
|
17871
|
-
this.
|
|
18144
|
+
this.injector.destroy();
|
|
17872
18145
|
this._notificationRegistry.unregister(this.id);
|
|
17873
18146
|
}
|
|
17874
18147
|
}
|
|
17875
18148
|
}
|
|
18149
|
+
/** @inheritDoc */
|
|
18150
|
+
class ɵWorkbenchNotificationSize {
|
|
18151
|
+
_height = signal(undefined, { ...(ngDevMode ? { debugName: "_height" } : {}) });
|
|
18152
|
+
_minHeight = signal(undefined, { ...(ngDevMode ? { debugName: "_minHeight" } : {}) });
|
|
18153
|
+
_maxHeight = signal(undefined, { ...(ngDevMode ? { debugName: "_maxHeight" } : {}) });
|
|
18154
|
+
/** @inheritDoc */
|
|
18155
|
+
get height() {
|
|
18156
|
+
return this._height;
|
|
18157
|
+
}
|
|
18158
|
+
/** @inheritDoc */
|
|
18159
|
+
set height(height) {
|
|
18160
|
+
untracked(() => this._height.set(height));
|
|
18161
|
+
}
|
|
18162
|
+
/** @inheritDoc */
|
|
18163
|
+
get minHeight() {
|
|
18164
|
+
return this._minHeight;
|
|
18165
|
+
}
|
|
18166
|
+
/** @inheritDoc */
|
|
18167
|
+
set minHeight(minHeight) {
|
|
18168
|
+
untracked(() => this._minHeight.set(minHeight));
|
|
18169
|
+
}
|
|
18170
|
+
/** @inheritDoc */
|
|
18171
|
+
get maxHeight() {
|
|
18172
|
+
return this._maxHeight;
|
|
18173
|
+
}
|
|
18174
|
+
/** @inheritDoc */
|
|
18175
|
+
set maxHeight(maxHeight) {
|
|
18176
|
+
untracked(() => this._maxHeight.set(maxHeight));
|
|
18177
|
+
}
|
|
18178
|
+
}
|
|
18179
|
+
|
|
18180
|
+
/*
|
|
18181
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
18182
|
+
*
|
|
18183
|
+
* This program and the accompanying materials are made
|
|
18184
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
18185
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
18186
|
+
*
|
|
18187
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
18188
|
+
*/
|
|
18189
|
+
/**
|
|
18190
|
+
* Displays the microfrontend of a given {@link WorkbenchNotficationCapability}.
|
|
18191
|
+
*
|
|
18192
|
+
* This component is designed to be displayed in a workbench notification.
|
|
18193
|
+
*/
|
|
18194
|
+
class MicrofrontendNotificationComponent {
|
|
18195
|
+
capability = input.required({ ...(ngDevMode ? { debugName: "capability" } : {}) });
|
|
18196
|
+
params = input.required({ ...(ngDevMode ? { debugName: "params" } : {}) });
|
|
18197
|
+
referrer = input.required({ ...(ngDevMode ? { debugName: "referrer" } : {}) });
|
|
18198
|
+
_host = inject(ElementRef).nativeElement;
|
|
18199
|
+
_outletRouter = inject(OutletRouter);
|
|
18200
|
+
_messageClient = inject(MessageClient);
|
|
18201
|
+
_logger = inject(Logger);
|
|
18202
|
+
_routerOutletElement = viewChild.required('router_outlet');
|
|
18203
|
+
/** Splash to display until the microfrontend signals readiness. */
|
|
18204
|
+
splash = inject(MicrofrontendPlatformConfig).splash ?? MicrofrontendSplashComponent;
|
|
18205
|
+
workbenchLayoutService = inject(WorkbenchLayoutService);
|
|
18206
|
+
notification = inject(ɵWorkbenchNotification);
|
|
18207
|
+
focusWithin = signal(false, { ...(ngDevMode ? { debugName: "focusWithin" } : {}) });
|
|
18208
|
+
constructor() {
|
|
18209
|
+
this._logger.debug(() => 'Constructing MicrofrontendNotificationComponent.', LoggerNames.MICROFRONTEND);
|
|
18210
|
+
this.installNavigator();
|
|
18211
|
+
this.installNotificationCloseListener();
|
|
18212
|
+
this.installNotificationFocusedPublisher();
|
|
18213
|
+
this.setNotificationProperties();
|
|
18214
|
+
this.propagateNotificationContext();
|
|
18215
|
+
this.propagateWorkbenchTheme();
|
|
18216
|
+
inject(DestroyRef).onDestroy(() => {
|
|
18217
|
+
// Clear the outlet.
|
|
18218
|
+
void this._outletRouter.navigate(null, { outlet: this.notification.id });
|
|
18219
|
+
// Delete retained messages to free resources.
|
|
18220
|
+
void this._messageClient.publish(_WorkbenchCommands.notificationFocusedTopic(this.notification.id), undefined, { retain: true });
|
|
18221
|
+
});
|
|
18222
|
+
}
|
|
18223
|
+
installNavigator() {
|
|
18224
|
+
const manifestService = inject(ManifestService);
|
|
18225
|
+
const injector = inject(Injector);
|
|
18226
|
+
effect(() => {
|
|
18227
|
+
const capability = this.capability();
|
|
18228
|
+
const params = this.params();
|
|
18229
|
+
void untracked(async () => {
|
|
18230
|
+
const application = manifestService.getApplication(capability.metadata.appSymbolicName);
|
|
18231
|
+
this._logger.debug(() => `Loading microfrontend into workbench notification [app=${capability.metadata.appSymbolicName}, baseUrl=${application.baseUrl}, path=${capability.properties.path}].`, LoggerNames.MICROFRONTEND, params, capability);
|
|
18232
|
+
// Wait for the context to be set on the router outlet, as @scion/workbench-client expects it to be available on startup.
|
|
18233
|
+
await Microfrontends.waitForContext(this._routerOutletElement, _NOTIFICATION_CONTEXT, { injector });
|
|
18234
|
+
void this._outletRouter.navigate(capability.properties.path, {
|
|
18235
|
+
outlet: this.notification.id,
|
|
18236
|
+
relativeTo: application.baseUrl,
|
|
18237
|
+
params: params,
|
|
18238
|
+
pushStateToSessionHistoryStack: false,
|
|
18239
|
+
showSplash: capability.properties.showSplash,
|
|
18240
|
+
});
|
|
18241
|
+
});
|
|
18242
|
+
});
|
|
18243
|
+
}
|
|
18244
|
+
installNotificationCloseListener() {
|
|
18245
|
+
this._messageClient.observe$(_WorkbenchCommands.notificationCloseTopic(this.notification.id))
|
|
18246
|
+
.pipe(takeUntilDestroyed())
|
|
18247
|
+
.subscribe(() => {
|
|
18248
|
+
this.notification.close();
|
|
18249
|
+
});
|
|
18250
|
+
}
|
|
18251
|
+
installNotificationFocusedPublisher() {
|
|
18252
|
+
effect(() => {
|
|
18253
|
+
const focused = this.notification.focused();
|
|
18254
|
+
untracked(() => {
|
|
18255
|
+
const commandTopic = _WorkbenchCommands.notificationFocusedTopic(this.notification.id);
|
|
18256
|
+
void this._messageClient.publish(commandTopic, focused, { retain: true });
|
|
18257
|
+
});
|
|
18258
|
+
});
|
|
18259
|
+
}
|
|
18260
|
+
setNotificationProperties() {
|
|
18261
|
+
effect(() => {
|
|
18262
|
+
const properties = this.capability().properties;
|
|
18263
|
+
untracked(() => {
|
|
18264
|
+
this.notification.size.height = properties.size?.height;
|
|
18265
|
+
this.notification.size.minHeight = properties.size?.minHeight;
|
|
18266
|
+
this.notification.size.maxHeight = properties.size?.maxHeight;
|
|
18267
|
+
});
|
|
18268
|
+
});
|
|
18269
|
+
}
|
|
18270
|
+
onFocusWithin(event) {
|
|
18271
|
+
const { detail: focusWithin } = event;
|
|
18272
|
+
this.focusWithin.set(focusWithin);
|
|
18273
|
+
if (focusWithin) {
|
|
18274
|
+
this._host.dispatchEvent(new CustomEvent('sci-microfrontend-focusin', { bubbles: true }));
|
|
18275
|
+
}
|
|
18276
|
+
}
|
|
18277
|
+
/**
|
|
18278
|
+
* Provides the notification context to embedded content.
|
|
18279
|
+
*/
|
|
18280
|
+
propagateNotificationContext() {
|
|
18281
|
+
effect(() => {
|
|
18282
|
+
const context = {
|
|
18283
|
+
notificationId: this.notification.id,
|
|
18284
|
+
capability: this.capability(),
|
|
18285
|
+
params: this.params(),
|
|
18286
|
+
referrer: {
|
|
18287
|
+
appSymbolicName: this.referrer(),
|
|
18288
|
+
},
|
|
18289
|
+
};
|
|
18290
|
+
const routerOutletElement = this._routerOutletElement().nativeElement;
|
|
18291
|
+
untracked(() => routerOutletElement.setContextValue(_NOTIFICATION_CONTEXT, context));
|
|
18292
|
+
});
|
|
18293
|
+
}
|
|
18294
|
+
propagateWorkbenchTheme() {
|
|
18295
|
+
Microfrontends.propagateTheme(this._routerOutletElement);
|
|
18296
|
+
}
|
|
18297
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18298
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.1", type: MicrofrontendNotificationComponent, isStandalone: true, selector: "wb-microfrontend-notification", inputs: { capability: { classPropertyName: "capability", publicName: "capability", isSignal: true, isRequired: true, transformFunction: null }, params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: true, transformFunction: null }, referrer: { classPropertyName: "referrer", publicName: "referrer", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.workbench-drag": "workbenchLayoutService.dragging()" } }, viewQueries: [{ propertyName: "_routerOutletElement", first: true, predicate: ["router_outlet"], descendants: true, isSignal: true }], ngImport: i0, template: "<sci-router-outlet #router_outlet\n [name]=\"notification.id\"\n [attr.data-capabilityid]=\"capability().metadata!.id\"\n [attr.data-app]=\"capability().metadata!.appSymbolicName\"\n [attr.data-focus]=\"focusWithin() ? '' : null\"\n keystrokes=\"keydown.escape\"\n [class]=\"notification.cssClass()\"\n (focuswithin)=\"onFocusWithin($event)\">\n <ng-container *ngComponentOutlet=\"splash\"/>\n</sci-router-outlet>\n", styles: [":host{display:grid}:host.workbench-drag>sci-router-outlet{pointer-events:none}:host>sci-router-outlet::part(splash){display:grid}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
|
|
18299
|
+
}
|
|
18300
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationComponent, decorators: [{
|
|
18301
|
+
type: Component,
|
|
18302
|
+
args: [{ selector: 'wb-microfrontend-notification', imports: [
|
|
18303
|
+
NgComponentOutlet,
|
|
18304
|
+
], schemas: [CUSTOM_ELEMENTS_SCHEMA], host: {
|
|
18305
|
+
'[class.workbench-drag]': 'workbenchLayoutService.dragging()',
|
|
18306
|
+
}, template: "<sci-router-outlet #router_outlet\n [name]=\"notification.id\"\n [attr.data-capabilityid]=\"capability().metadata!.id\"\n [attr.data-app]=\"capability().metadata!.appSymbolicName\"\n [attr.data-focus]=\"focusWithin() ? '' : null\"\n keystrokes=\"keydown.escape\"\n [class]=\"notification.cssClass()\"\n (focuswithin)=\"onFocusWithin($event)\">\n <ng-container *ngComponentOutlet=\"splash\"/>\n</sci-router-outlet>\n", styles: [":host{display:grid}:host.workbench-drag>sci-router-outlet{pointer-events:none}:host>sci-router-outlet::part(splash){display:grid}\n"] }]
|
|
18307
|
+
}], ctorParameters: () => [], propDecorators: { capability: [{ type: i0.Input, args: [{ isSignal: true, alias: "capability", required: true }] }], params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: true }] }], referrer: [{ type: i0.Input, args: [{ isSignal: true, alias: "referrer", required: true }] }], _routerOutletElement: [{ type: i0.ViewChild, args: ['router_outlet', { isSignal: true }] }] } });
|
|
17876
18308
|
|
|
17877
18309
|
/*
|
|
17878
18310
|
* Copyright (c) 2018-2025 Swiss Federal Railways
|
|
@@ -17887,6 +18319,7 @@ class ɵWorkbenchNotification {
|
|
|
17887
18319
|
class ɵWorkbenchNotificationService {
|
|
17888
18320
|
_rootInjector = inject(ApplicationRef).injector;
|
|
17889
18321
|
_notificationRegistry = inject(WorkbenchNotificationRegistry);
|
|
18322
|
+
_mutex = new SingleTaskExecutor();
|
|
17890
18323
|
_zone = inject(NgZone);
|
|
17891
18324
|
/** @inheritDoc */
|
|
17892
18325
|
show(message, options) {
|
|
@@ -17896,17 +18329,20 @@ class ɵWorkbenchNotificationService {
|
|
|
17896
18329
|
this._zone.run(() => this.show(message, options));
|
|
17897
18330
|
return;
|
|
17898
18331
|
}
|
|
17899
|
-
//
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
17903
|
-
|
|
17904
|
-
|
|
17905
|
-
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
18332
|
+
// Prevent race conditions with asynchronous group reducer, ensuring to not have a "stale" previous notification.
|
|
18333
|
+
void this._mutex.submit(async () => {
|
|
18334
|
+
const previousNotification = options?.group ? this._notificationRegistry.elements().find(element => element.group === options.group) : undefined;
|
|
18335
|
+
// Replace previous notification of the same group, or add it otherwise.
|
|
18336
|
+
if (previousNotification) {
|
|
18337
|
+
const reducedInputs = options?.groupInputReduceFn ? await options.groupInputReduceFn(previousNotification.inputs ?? {}, options.inputs ?? {}) : options?.inputs;
|
|
18338
|
+
const notification = this.createNotification(message, { ...options, inputs: reducedInputs });
|
|
18339
|
+
this._notificationRegistry.replace(previousNotification.id, { key: notification.id, element: notification });
|
|
18340
|
+
}
|
|
18341
|
+
else {
|
|
18342
|
+
const notification = this.createNotification(message, options);
|
|
18343
|
+
this._notificationRegistry.register(notification.id, notification);
|
|
18344
|
+
}
|
|
18345
|
+
});
|
|
17910
18346
|
}
|
|
17911
18347
|
/**
|
|
17912
18348
|
* Creates the notification handle.
|
|
@@ -17941,8 +18377,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
17941
18377
|
/**
|
|
17942
18378
|
* Shows a notification.
|
|
17943
18379
|
*
|
|
17944
|
-
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered.
|
|
17945
|
-
* It informs about system events, task completion or errors.
|
|
18380
|
+
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered or focused.
|
|
18381
|
+
* It informs about system events, task completion, or errors. Severity indicates importance or urgency.
|
|
17946
18382
|
*
|
|
17947
18383
|
* Notifications can be grouped. Only the most recent notification within a group is displayed.
|
|
17948
18384
|
*
|
|
@@ -17958,7 +18394,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
17958
18394
|
}] });
|
|
17959
18395
|
|
|
17960
18396
|
/*
|
|
17961
|
-
* Copyright (c) 2018-
|
|
18397
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
18398
|
+
*
|
|
18399
|
+
* This program and the accompanying materials are made
|
|
18400
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
18401
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
18402
|
+
*
|
|
18403
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
18404
|
+
*/
|
|
18405
|
+
/** @inheritDoc */
|
|
18406
|
+
class MicrofrontendHostNotification {
|
|
18407
|
+
_notification;
|
|
18408
|
+
capability;
|
|
18409
|
+
params;
|
|
18410
|
+
referrer;
|
|
18411
|
+
constructor(_notification, capability, params, referrer) {
|
|
18412
|
+
this._notification = _notification;
|
|
18413
|
+
this.capability = signal(capability).asReadonly();
|
|
18414
|
+
this.params = signal(params).asReadonly();
|
|
18415
|
+
this.referrer = signal(referrer).asReadonly();
|
|
18416
|
+
this.setNotificationProperties();
|
|
18417
|
+
}
|
|
18418
|
+
setNotificationProperties() {
|
|
18419
|
+
const properties = this.capability().properties;
|
|
18420
|
+
this._notification.size.height = properties.size?.height;
|
|
18421
|
+
this._notification.size.minHeight = properties.size?.minHeight;
|
|
18422
|
+
this._notification.size.maxHeight = properties.size?.maxHeight;
|
|
18423
|
+
}
|
|
18424
|
+
}
|
|
18425
|
+
|
|
18426
|
+
/*
|
|
18427
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
17962
18428
|
*
|
|
17963
18429
|
* This program and the accompanying materials are made
|
|
17964
18430
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -17967,77 +18433,196 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
17967
18433
|
* SPDX-License-Identifier: EPL-2.0
|
|
17968
18434
|
*/
|
|
17969
18435
|
/**
|
|
17970
|
-
*
|
|
18436
|
+
* Handles notification intents, opening a notification based on resolved capability.
|
|
18437
|
+
*
|
|
18438
|
+
* Microfrontends of the host are displayed in {@link MicrofrontendHostComponent}, microfrontends of other applications in {@link MicrofrontendNotificationComponent}.
|
|
18439
|
+
*
|
|
18440
|
+
* Notification intents are handled in this interceptor and are not transported to the providing application to support applications not connected to the SCION Workbench.
|
|
17971
18441
|
*/
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
17975
|
-
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
|
|
17979
|
-
|
|
17980
|
-
|
|
17981
|
-
|
|
17982
|
-
|
|
18442
|
+
class MicrofrontendNotificationIntentHandler {
|
|
18443
|
+
_notificationService = inject(WorkbenchNotificationService);
|
|
18444
|
+
_logger = inject(Logger);
|
|
18445
|
+
/**
|
|
18446
|
+
* Notification intents are handled in this interceptor and then swallowed.
|
|
18447
|
+
*/
|
|
18448
|
+
async intercept(intentMessage, next) {
|
|
18449
|
+
if (intentMessage.intent.type === WorkbenchCapabilities.Notification) {
|
|
18450
|
+
const replyTo = intentMessage.headers.get(MessageHeaders.ReplyTo);
|
|
18451
|
+
await this.showNotification(intentMessage);
|
|
18452
|
+
void Beans.get(MessageClient).publish(replyTo, undefined, { headers: new Map().set(MessageHeaders.Status, ResponseStatusCodes.TERMINAL) });
|
|
18453
|
+
// Do not continue the handler chain to swallow the intent.
|
|
18454
|
+
}
|
|
18455
|
+
else {
|
|
18456
|
+
return next.handle(intentMessage);
|
|
18457
|
+
}
|
|
18458
|
+
}
|
|
18459
|
+
/**
|
|
18460
|
+
* Displays the microfrontend declared by the resolved capability in a notification.
|
|
18461
|
+
*/
|
|
18462
|
+
async showNotification(intentMessage) {
|
|
18463
|
+
const command = intentMessage.body;
|
|
18464
|
+
const capability = intentMessage.capability;
|
|
18465
|
+
const capabilityId = capability.metadata.id;
|
|
18466
|
+
const groupParamsReducer = capability.properties.groupParamsReducer;
|
|
18467
|
+
const params = intentMessage.intent.params ?? new Map();
|
|
18468
|
+
const referrer = intentMessage.headers.get(MessageHeaders.AppSymbolicName);
|
|
18469
|
+
const isHostProvider = Microfrontends.isHostProvider(capability);
|
|
18470
|
+
const legacyTextNotification = isLegacyTextNotification(capability, intentMessage);
|
|
18471
|
+
if (legacyTextNotification) {
|
|
18472
|
+
params.set(eNOTIFICATION_MESSAGE_PARAM, command.content);
|
|
18473
|
+
}
|
|
18474
|
+
this._logger.debug(() => 'Handling microfrontend notification intent', LoggerNames.MICROFRONTEND, command);
|
|
18475
|
+
this._notificationService.show(isHostProvider ? MicrofrontendHostComponent : MicrofrontendNotificationComponent, prune({
|
|
18476
|
+
inputs: isHostProvider ? { params } : { capability, params, referrer },
|
|
18477
|
+
providers: isHostProvider ? [provideActivatedMicrofrontend$3(capability, params, referrer)] : undefined,
|
|
17983
18478
|
title: createRemoteTranslatable(command.title, { appSymbolicName: referrer }),
|
|
17984
18479
|
severity: command.severity,
|
|
17985
|
-
duration:
|
|
17986
|
-
group: command.group,
|
|
17987
|
-
|
|
18480
|
+
duration: legacyTextNotification && typeof command.duration === 'number' ? command.duration * 1000 : command.duration,
|
|
18481
|
+
group: command.group ? `${command.group}_${capabilityId}_${referrer}` : undefined, // Use distinct group name for different referrers and capabilities not to overwrite each other
|
|
18482
|
+
groupInputReduceFn: groupParamsReducer ? createParamsReducerFn(groupParamsReducer) : undefined,
|
|
18483
|
+
cssClass: Arrays.coerce(capability.properties.cssClass).concat(Arrays.coerce(command.cssClass)),
|
|
17988
18484
|
}));
|
|
17989
|
-
}
|
|
18485
|
+
}
|
|
18486
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationIntentHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
18487
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationIntentHandler });
|
|
18488
|
+
}
|
|
18489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationIntentHandler, decorators: [{
|
|
18490
|
+
type: Injectable
|
|
18491
|
+
}] });
|
|
18492
|
+
/**
|
|
18493
|
+
* Returns a function to reduce inputs by sending a request to passed topic.
|
|
18494
|
+
*/
|
|
18495
|
+
function createParamsReducerFn(reducerTopic) {
|
|
18496
|
+
return async (prevInput, currInput) => {
|
|
18497
|
+
const currParams = Object.fromEntries(currInput['params']);
|
|
18498
|
+
const prevParams = Object.fromEntries(prevInput['params']);
|
|
18499
|
+
const reducedParams = await firstValueFrom(Beans.get(MessageClient).request$(reducerTopic, { prevParams, currParams }, { retain: true }));
|
|
18500
|
+
return { ...currInput, params: new Map(Object.entries(reducedParams.body ?? currParams)) };
|
|
18501
|
+
};
|
|
18502
|
+
}
|
|
18503
|
+
/**
|
|
18504
|
+
* Indicates whether the notification is opened by a legacy client.
|
|
18505
|
+
*
|
|
18506
|
+
* TODO [Angular 22] Remove with Angular 22. Used for backward compatiblity.
|
|
18507
|
+
*/
|
|
18508
|
+
function isLegacyTextNotification(capability, intentMessage) {
|
|
18509
|
+
const isTextMessage = capability.properties[TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY] === TEXT_NOTIFICATION_CAPABILITY_IDENTITY;
|
|
18510
|
+
return isTextMessage && !intentMessage.intent.params?.has(eNOTIFICATION_MESSAGE_PARAM);
|
|
17990
18511
|
}
|
|
17991
18512
|
/**
|
|
17992
|
-
* Provides
|
|
18513
|
+
* Provides {@link ActivatedMicrofrontend} for injection in the host microfrontend.
|
|
18514
|
+
*/
|
|
18515
|
+
function provideActivatedMicrofrontend$3(capability, params, referrer) {
|
|
18516
|
+
return {
|
|
18517
|
+
provide: ActivatedMicrofrontend,
|
|
18518
|
+
useFactory: () => {
|
|
18519
|
+
const notification = inject(ɵWorkbenchNotification);
|
|
18520
|
+
const reducedParams = notification.inputs?.['params'];
|
|
18521
|
+
// Create in notification's injection context to bind 'MicrofrontendNotification' to the notification's lifecycle.
|
|
18522
|
+
return runInInjectionContext(notification.injector, () => new MicrofrontendHostNotification(notification, capability, reducedParams ?? params, referrer));
|
|
18523
|
+
},
|
|
18524
|
+
};
|
|
18525
|
+
}
|
|
18526
|
+
|
|
18527
|
+
/*
|
|
18528
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
18529
|
+
*
|
|
18530
|
+
* This program and the accompanying materials are made
|
|
18531
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
18532
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
17993
18533
|
*
|
|
17994
|
-
*
|
|
18534
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
18535
|
+
*/
|
|
18536
|
+
/**
|
|
18537
|
+
* Provides the route for the built-in {@link WorkbenchNotificationCapability}.
|
|
17995
18538
|
*/
|
|
17996
|
-
function
|
|
18539
|
+
function provideMicrofrontendTextNotificationRoute() {
|
|
17997
18540
|
return makeEnvironmentProviders([
|
|
17998
|
-
|
|
18541
|
+
{
|
|
18542
|
+
provide: WORKBENCH_ROUTE,
|
|
18543
|
+
useFactory: () => ({
|
|
18544
|
+
path: '',
|
|
18545
|
+
loadComponent: () => Promise.resolve().then(function () { return notificationTextMessage_component; }),
|
|
18546
|
+
canMatch: [canMatchWorkbenchNotificationCapability({})],
|
|
18547
|
+
}),
|
|
18548
|
+
multi: true,
|
|
18549
|
+
},
|
|
17999
18550
|
]);
|
|
18000
18551
|
}
|
|
18001
18552
|
|
|
18002
18553
|
/**
|
|
18003
|
-
*
|
|
18554
|
+
* Asserts notification capabilities to have required properties.
|
|
18004
18555
|
*/
|
|
18005
|
-
class
|
|
18006
|
-
intercept(
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18556
|
+
class MicrofrontendNotificationCapabilityValidator {
|
|
18557
|
+
async intercept(capability) {
|
|
18558
|
+
if (capability.type !== WorkbenchCapabilities.Notification) {
|
|
18559
|
+
return capability;
|
|
18560
|
+
}
|
|
18561
|
+
const notificationCapability = capability;
|
|
18562
|
+
// Assert capability other than the built-in text notification capability to have a qualifier.
|
|
18563
|
+
if (!isBuiltinNotificationCapability(notificationCapability) && !Object.keys(notificationCapability.qualifier ?? {}).length) {
|
|
18564
|
+
throw Error(`[NotificationDefinitionError] Notification capability requires a qualifier [app=${app$3(notificationCapability)}, notification=${qualifier$3(notificationCapability)}]`);
|
|
18565
|
+
}
|
|
18566
|
+
// Assert capability to have properties.
|
|
18567
|
+
if (!notificationCapability.properties) {
|
|
18568
|
+
throw Error(`[NotificationDefinitionError] Notification capability requires properties [app=${app$3(notificationCapability)}, notification=${qualifier$3(notificationCapability)}]`);
|
|
18569
|
+
}
|
|
18570
|
+
// Assert the notification capability to have a path, unless provided by the host application.
|
|
18571
|
+
this.assertPath(notificationCapability);
|
|
18572
|
+
// Assert the notification capability to have a height, unless provided by the host application.
|
|
18573
|
+
this.assertSize(notificationCapability);
|
|
18574
|
+
// Assert host notification capabilities not to define the "showSplash" property.
|
|
18575
|
+
if (Microfrontends.isHostProvider(capability) && notificationCapability.properties.showSplash !== undefined) {
|
|
18576
|
+
throw Error(`[NotificationDefinitionError] Property "showSplash" not supported for notification capabilities of the host application [app=${app$3(notificationCapability)}, notification=${qualifier$3(notificationCapability)}]`);
|
|
18577
|
+
}
|
|
18578
|
+
return capability;
|
|
18011
18579
|
}
|
|
18012
|
-
|
|
18013
|
-
|
|
18580
|
+
assertPath(capability) {
|
|
18581
|
+
const path = capability.properties?.path;
|
|
18582
|
+
if (Microfrontends.isHostProvider(capability)) {
|
|
18583
|
+
if (path !== '') {
|
|
18584
|
+
throw Error(`[NotificationDefinitionError] Notification capabilities of the host application require an empty path. [app=${app$3(capability)}, notification=${qualifier$3(capability)}]. Change the path '${path}' to empty and add 'canMatchWorkbenchNotificationCapability(${JSON.stringify(capability.qualifier)})' guard to the route.\n\nExample:\nCapability: { type: 'notification', qualifier: ${JSON.stringify(capability.qualifier)}, properties: {path: ''} }\nRoute: { path: '', canMatch: [canMatchWorkbenchNotificationCapability(${JSON.stringify(capability.qualifier)})], component: NotificationComponent }`);
|
|
18585
|
+
}
|
|
18586
|
+
}
|
|
18587
|
+
else {
|
|
18588
|
+
if (path === null || path == undefined) {
|
|
18589
|
+
throw Error(`[NotificationDefinitionError] Notification capabilities require a path. [app=${app$3(capability)}, notification=${qualifier$3(capability)}]`);
|
|
18590
|
+
}
|
|
18591
|
+
}
|
|
18592
|
+
}
|
|
18593
|
+
assertSize(capability) {
|
|
18594
|
+
if (Microfrontends.isHostProvider(capability)) {
|
|
18595
|
+
return;
|
|
18596
|
+
}
|
|
18597
|
+
const size = capability.properties?.size;
|
|
18598
|
+
if (!size?.height) {
|
|
18599
|
+
throw Error(`[NotificationDefinitionError] Notification capability requires the 'size' property with a height [app=${app$3(capability)}, notification=${qualifier$3(capability)}]`);
|
|
18600
|
+
}
|
|
18601
|
+
}
|
|
18602
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationCapabilityValidator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
18603
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationCapabilityValidator });
|
|
18014
18604
|
}
|
|
18015
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type:
|
|
18605
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: MicrofrontendNotificationCapabilityValidator, decorators: [{
|
|
18016
18606
|
type: Injectable
|
|
18017
18607
|
}] });
|
|
18608
|
+
function isBuiltinNotificationCapability(capability) {
|
|
18609
|
+
return capability.properties?.[TEXT_NOTIFICATION_CAPABILITY_IDENTITY_PROPERTY] === TEXT_NOTIFICATION_CAPABILITY_IDENTITY;
|
|
18610
|
+
}
|
|
18018
18611
|
/**
|
|
18019
|
-
*
|
|
18020
|
-
*
|
|
18021
|
-
* @see MicrofrontendNotificationIntentHandler
|
|
18612
|
+
* Returns the qualifier as string.
|
|
18022
18613
|
*/
|
|
18023
|
-
function
|
|
18024
|
-
return
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
|
|
18031
|
-
description: 'Text to display in the notification.',
|
|
18032
|
-
},
|
|
18033
|
-
],
|
|
18034
|
-
private: false,
|
|
18035
|
-
description: 'Displays a text notification.',
|
|
18036
|
-
};
|
|
18614
|
+
function qualifier$3(capability) {
|
|
18615
|
+
return Objects.toMatrixNotation(capability.qualifier);
|
|
18616
|
+
}
|
|
18617
|
+
/**
|
|
18618
|
+
* Returns the app symbolic name.
|
|
18619
|
+
*/
|
|
18620
|
+
function app$3(capability) {
|
|
18621
|
+
return capability.metadata.appSymbolicName;
|
|
18037
18622
|
}
|
|
18038
18623
|
|
|
18039
18624
|
/*
|
|
18040
|
-
* Copyright (c) 2018-
|
|
18625
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
18041
18626
|
*
|
|
18042
18627
|
* This program and the accompanying materials are made
|
|
18043
18628
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -18052,13 +18637,34 @@ function provideBuiltInTextNotificationCapability() {
|
|
|
18052
18637
|
*/
|
|
18053
18638
|
function provideMicrofrontendNotification() {
|
|
18054
18639
|
return makeEnvironmentProviders([
|
|
18640
|
+
MicrofrontendNotificationCapabilityValidator,
|
|
18055
18641
|
MicrofrontendTextNotificationCapabilityProvider,
|
|
18056
|
-
|
|
18642
|
+
MicrofrontendNotificationIntentHandler,
|
|
18643
|
+
provideWorkbenchNotificationContext(),
|
|
18644
|
+
provideMicrofrontendTextNotificationRoute(),
|
|
18057
18645
|
provideMicrofrontendPlatformInitializer(onPreStartup, { phase: MicrofrontendPlatformStartupPhase.PreStartup }),
|
|
18058
18646
|
]);
|
|
18059
18647
|
function onPreStartup() {
|
|
18060
18648
|
// Register built-in text notification capability in the host manifest.
|
|
18061
18649
|
Beans.register(HostManifestInterceptor, { useValue: inject(MicrofrontendTextNotificationCapabilityProvider), multi: true });
|
|
18650
|
+
// Register notification capability validator.
|
|
18651
|
+
Beans.register(CapabilityInterceptor, { useValue: inject(MicrofrontendNotificationCapabilityValidator), multi: true });
|
|
18652
|
+
// Register notification intent handler.
|
|
18653
|
+
Beans.register(IntentInterceptor, { useValue: inject(MicrofrontendNotificationIntentHandler), multi: true });
|
|
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
|
+
};
|
|
18062
18668
|
}
|
|
18063
18669
|
}
|
|
18064
18670
|
|
|
@@ -18707,15 +19313,19 @@ class TextMessageComponent {
|
|
|
18707
19313
|
const { params, referrer } = inject(ActivatedMicrofrontend);
|
|
18708
19314
|
const translatable = params().get(eMESSAGE_BOX_MESSAGE_PARAM);
|
|
18709
19315
|
this.message = createRemoteTranslatable(translatable, { appSymbolicName: referrer() });
|
|
19316
|
+
// Limit the maximum messagebox width to break the message.
|
|
19317
|
+
inject(WorkbenchDialog).size.maxWidth = 'var(--sci-workbench-messagebox-max-width)';
|
|
18710
19318
|
}
|
|
18711
19319
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TextMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18712
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
19320
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.1", type: TextMessageComponent, isStandalone: true, selector: "wb-text-message", host: { properties: { "class.empty": "!message?.length" } }, ngImport: i0, template: "{{(message | wbText)()}}\n", styles: [":host{word-break:break-word;white-space:pre-line;text-align:var(--sci-workbench-messagebox-text-align)}:host.empty{display:none}\n"], dependencies: [{ kind: "pipe", type: TextPipe, name: "wbText" }] });
|
|
18713
19321
|
}
|
|
18714
19322
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TextMessageComponent, decorators: [{
|
|
18715
19323
|
type: Component,
|
|
18716
19324
|
args: [{ selector: 'wb-text-message', imports: [
|
|
18717
19325
|
TextPipe,
|
|
18718
|
-
],
|
|
19326
|
+
], host: {
|
|
19327
|
+
'[class.empty]': '!message?.length',
|
|
19328
|
+
}, template: "{{(message | wbText)()}}\n", styles: [":host{word-break:break-word;white-space:pre-line;text-align:var(--sci-workbench-messagebox-text-align)}:host.empty{display:none}\n"] }]
|
|
18719
19329
|
}], ctorParameters: () => [] });
|
|
18720
19330
|
/**
|
|
18721
19331
|
* Property to identify the built-in text message box capability.
|
|
@@ -19902,6 +20512,7 @@ function provideWorkbench(config) {
|
|
|
19902
20512
|
provideWorkbenchViewContext(),
|
|
19903
20513
|
provideWorkbenchDialogContext(),
|
|
19904
20514
|
provideWorkbenchPopupContext(),
|
|
20515
|
+
provideWorkbenchNotificationContext(),
|
|
19905
20516
|
provideWorkbenchMicrofrontendSupport(config),
|
|
19906
20517
|
]);
|
|
19907
20518
|
}
|
|
@@ -19996,114 +20607,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
19996
20607
|
}] });
|
|
19997
20608
|
|
|
19998
20609
|
/*
|
|
19999
|
-
* Copyright (c) 2018-
|
|
20000
|
-
*
|
|
20001
|
-
* This program and the accompanying materials are made
|
|
20002
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
20003
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
20004
|
-
*
|
|
20005
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
20006
|
-
*/
|
|
20007
|
-
/**
|
|
20008
|
-
* TODO [Angular 22] Remove with Angular 22. Used for backward compatiblity.
|
|
20009
|
-
*/
|
|
20010
|
-
class RemoveLegacyInputPipe {
|
|
20011
|
-
transform(inputs) {
|
|
20012
|
-
const inputsCopy = { ...inputs ?? {} };
|
|
20013
|
-
delete inputsCopy[LEGACY_NOTIFICATION_INPUT]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
|
|
20014
|
-
return inputsCopy;
|
|
20015
|
-
}
|
|
20016
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
20017
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, isStandalone: true, name: "wbRemoveLegacyInput" });
|
|
20018
|
-
}
|
|
20019
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RemoveLegacyInputPipe, decorators: [{
|
|
20020
|
-
type: Pipe,
|
|
20021
|
-
args: [{ name: 'wbRemoveLegacyInput' }]
|
|
20022
|
-
}] });
|
|
20023
|
-
|
|
20024
|
-
/*
|
|
20025
|
-
* Copyright (c) 2018-2025 Swiss Federal Railways
|
|
20026
|
-
*
|
|
20027
|
-
* This program and the accompanying materials are made
|
|
20028
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
20029
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
20030
|
-
*
|
|
20031
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
20032
|
-
*/
|
|
20033
|
-
/**
|
|
20034
|
-
* Renders the content of a workbench notification.
|
|
20035
|
-
*/
|
|
20036
|
-
class WorkbenchNotificationComponent {
|
|
20037
|
-
notification = input.required({ ...(ngDevMode ? { debugName: "notification" } : {}) });
|
|
20038
|
-
hover = signal(false, { ...(ngDevMode ? { debugName: "hover" } : {}) });
|
|
20039
|
-
constructor() {
|
|
20040
|
-
this.installAutoCloseTimer();
|
|
20041
|
-
}
|
|
20042
|
-
onMousedown(event) {
|
|
20043
|
-
if (event.buttons === AUXILARY_MOUSE_BUTTON) {
|
|
20044
|
-
this.notification().close();
|
|
20045
|
-
}
|
|
20046
|
-
}
|
|
20047
|
-
onClose() {
|
|
20048
|
-
this.notification().close();
|
|
20049
|
-
}
|
|
20050
|
-
/**
|
|
20051
|
-
* Installs a timer to close the notification.
|
|
20052
|
-
*/
|
|
20053
|
-
installAutoCloseTimer() {
|
|
20054
|
-
effect(onCleanup => {
|
|
20055
|
-
const duration = this.notification().duration();
|
|
20056
|
-
const hover = this.hover();
|
|
20057
|
-
if (hover) {
|
|
20058
|
-
return;
|
|
20059
|
-
}
|
|
20060
|
-
untracked(() => {
|
|
20061
|
-
const subscription = fromDuration$(duration).subscribe(() => this.notification().close());
|
|
20062
|
-
onCleanup(() => subscription.unsubscribe());
|
|
20063
|
-
});
|
|
20064
|
-
});
|
|
20065
|
-
function fromDuration$(duration) {
|
|
20066
|
-
switch (duration) {
|
|
20067
|
-
case 'short':
|
|
20068
|
-
return timer(7000);
|
|
20069
|
-
case 'medium':
|
|
20070
|
-
return timer(15000);
|
|
20071
|
-
case 'long':
|
|
20072
|
-
return timer(30000);
|
|
20073
|
-
default:
|
|
20074
|
-
if (typeof duration === 'number') {
|
|
20075
|
-
return timer(duration);
|
|
20076
|
-
}
|
|
20077
|
-
return NEVER;
|
|
20078
|
-
}
|
|
20079
|
-
}
|
|
20080
|
-
}
|
|
20081
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20082
|
-
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)", "mousedown": "onMousedown($event)" }, properties: { "attr.data-notificationid": "notification().id", "attr.data-severity": "notification().severity()", "class": "notification().cssClass()" } }, ngImport: i0, template: "<div class=\"outline\">\n <!-- Title -->\n @if (notification().title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n }\n\n <!-- Message -->\n @if (notification().slot.text) {\n <span class=\"e2e-message\">{{(notification().slot.text | wbText)()}}</span>\n } @else {\n <ng-container *ngComponentOutlet=\"notification().slot.component!; inputs: notification().inputs | wbRemoveLegacyInput; injector: notification().slot.injector\"/>\n }\n</div>\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:grid;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:1rem;border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);border-left:var(--sci-workbench-notification-severity-indicator-size) solid transparent;position:relative}:host[data-severity=info]{border-left-color:var(--sci-color-accent)}:host[data-severity=warn]{border-left-color:var(--sci-color-notice)}:host[data-severity=error]{border-left-color:var(--sci-color-negative)}:host>div.outline{border:1px solid var(--sci-color-border);border-left:none;padding:1em 1.5em;border-top-right-radius:var(--sci-corner);border-bottom-right-radius:var(--sci-corner);font-size:.9em;white-space:pre-line;overflow-wrap:break-word;overflow:hidden}:host>div.outline>header{font-weight:700;margin-bottom:.75em}: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)}\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: "pipe", type: TextPipe, name: "wbText" }, { kind: "pipe", type: RemoveLegacyInputPipe, name: "wbRemoveLegacyInput" }] });
|
|
20083
|
-
}
|
|
20084
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: WorkbenchNotificationComponent, decorators: [{
|
|
20085
|
-
type: Component,
|
|
20086
|
-
args: [{ selector: 'wb-notification', imports: [
|
|
20087
|
-
TextPipe,
|
|
20088
|
-
IconComponent,
|
|
20089
|
-
NgComponentOutlet,
|
|
20090
|
-
RemoveLegacyInputPipe,
|
|
20091
|
-
], host: {
|
|
20092
|
-
'[attr.data-notificationid]': 'notification().id',
|
|
20093
|
-
'[attr.data-severity]': 'notification().severity()',
|
|
20094
|
-
'(mouseenter)': 'hover.set(true)',
|
|
20095
|
-
'(mouseleave)': 'hover.set(false)',
|
|
20096
|
-
'(mousedown)': 'onMousedown($event)',
|
|
20097
|
-
'[class]': 'notification().cssClass()',
|
|
20098
|
-
}, template: "<div class=\"outline\">\n <!-- Title -->\n @if (notification().title(); as title) {\n <header class=\"e2e-title\">{{(title | wbText)()}}</header>\n }\n\n <!-- Message -->\n @if (notification().slot.text) {\n <span class=\"e2e-message\">{{(notification().slot.text | wbText)()}}</span>\n } @else {\n <ng-container *ngComponentOutlet=\"notification().slot.component!; inputs: notification().inputs | wbRemoveLegacyInput; injector: notification().slot.injector\"/>\n }\n</div>\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:grid;background-color:var(--sci-color-background-elevation);color:var(--sci-color-text);font-size:1rem;border-radius:var(--sci-corner);box-shadow:var(--sci-elevation) var(--sci-static-color-black);border-left:var(--sci-workbench-notification-severity-indicator-size) solid transparent;position:relative}:host[data-severity=info]{border-left-color:var(--sci-color-accent)}:host[data-severity=warn]{border-left-color:var(--sci-color-notice)}:host[data-severity=error]{border-left-color:var(--sci-color-negative)}:host>div.outline{border:1px solid var(--sci-color-border);border-left:none;padding:1em 1.5em;border-top-right-radius:var(--sci-corner);border-bottom-right-radius:var(--sci-corner);font-size:.9em;white-space:pre-line;overflow-wrap:break-word;overflow:hidden}:host>div.outline>header{font-weight:700;margin-bottom:.75em}: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)}\n"] }]
|
|
20099
|
-
}], ctorParameters: () => [], propDecorators: { notification: [{ type: i0.Input, args: [{ isSignal: true, alias: "notification", required: true }] }] } });
|
|
20100
|
-
/**
|
|
20101
|
-
* Indicates that the auxilary mouse button is pressed (usually the mouse wheel button or middle button).
|
|
20102
|
-
*/
|
|
20103
|
-
const AUXILARY_MOUSE_BUTTON = 4;
|
|
20104
|
-
|
|
20105
|
-
/*
|
|
20106
|
-
* Copyright (c) 2018-2022 Swiss Federal Railways
|
|
20610
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
20107
20611
|
*
|
|
20108
20612
|
* This program and the accompanying materials are made
|
|
20109
20613
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -20117,13 +20621,13 @@ const AUXILARY_MOUSE_BUTTON = 4;
|
|
|
20117
20621
|
class NotificationListComponent {
|
|
20118
20622
|
notifications = inject(WorkbenchNotificationRegistry).elements;
|
|
20119
20623
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20120
|
-
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"] }] });
|
|
20121
20625
|
}
|
|
20122
20626
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotificationListComponent, decorators: [{
|
|
20123
20627
|
type: Component,
|
|
20124
20628
|
args: [{ selector: 'wb-notification-list', imports: [
|
|
20125
|
-
|
|
20126
|
-
], 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"] }]
|
|
20127
20631
|
}] });
|
|
20128
20632
|
|
|
20129
20633
|
/*
|
|
@@ -20295,7 +20799,7 @@ class ActivityPanelComponent {
|
|
|
20295
20799
|
sash1: `${1 / (1 - ratio)}`,
|
|
20296
20800
|
sash2: `${1 / ratio}`,
|
|
20297
20801
|
};
|
|
20298
|
-
}, { equal: Objects
|
|
20802
|
+
}, { equal: Objects.isEqual });
|
|
20299
20803
|
}
|
|
20300
20804
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ActivityPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20301
20805
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: ActivityPanelComponent, isStandalone: true, selector: "wb-activity-panel", inputs: { panel: { classPropertyName: "panel", publicName: "panel", isSignal: true, isRequired: true, transformFunction: null }, activityId1: { classPropertyName: "activityId1", publicName: "activityId1", isSignal: true, isRequired: true, transformFunction: null }, activityId2: { classPropertyName: "activityId2", publicName: "activityId2", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-panel": "panel()" } }, ngImport: i0, template: "@if (activityId1() && activityId2()) {\n <sci-sashbox [direction]=\"direction()\" (sashStart)=\"onSashStart()\" (sashEnd)=\"onSashEnd($event)\">\n <ng-template sciSash [size]=\"sashSizes().sash1\" key=\"sash1\">\n <ng-container *ngTemplateOutlet=\"activity_template; context: {$implicit: activityId1()}\"/>\n </ng-template>\n\n <ng-template sciSash [size]=\"sashSizes().sash2\" key=\"sash2\">\n <ng-container *ngTemplateOutlet=\"activity_template; context: {$implicit: activityId2()}\"/>\n </ng-template>\n </sci-sashbox>\n} @else if (activityId1()) {\n <ng-container *ngTemplateOutlet=\"activity_template; context: {$implicit: activityId1()}\"/>\n} @else if (activityId2()) {\n <ng-container *ngTemplateOutlet=\"activity_template; context: {$implicit: activityId2()}\"/>\n}\n\n<ng-template #activity_template let-activityId>\n <wb-grid [grid]=\"layout().grids[activityId]!\"\n [attr.data-grid]=\"activityId\"\n [gridDropZone]=\"{\n dropRegionSize: .15,\n dropPlaceholderSize: .15,\n dropZoneAttributes: {'data-grid': activityId},\n }\"/>\n</ng-template>\n", styles: [":host{display:grid}:host>sci-sashbox{z-index:auto}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SciSashboxComponent, selector: "sci-sashbox", inputs: ["direction"], outputs: ["sashStart", "sashEnd"] }, { kind: "directive", type: SciSashDirective, selector: "ng-template[sciSash]", inputs: ["size", "minSize", "key", "animate"], exportAs: ["sciSash"] }, { kind: "component", type: GridComponent, selector: "wb-grid", inputs: ["grid", "gridDropZone"] }] });
|
|
@@ -20534,7 +21038,7 @@ function configureWorkbenchGlassPane() {
|
|
|
20534
21038
|
},
|
|
20535
21039
|
{
|
|
20536
21040
|
provide: GLASS_PANE_OPTIONS,
|
|
20537
|
-
|
|
21041
|
+
useFactory: () => ({ cssClass: 'e2e-workbench' }),
|
|
20538
21042
|
},
|
|
20539
21043
|
];
|
|
20540
21044
|
}
|
|
@@ -21074,8 +21578,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
21074
21578
|
/**
|
|
21075
21579
|
* Shows a notification.
|
|
21076
21580
|
*
|
|
21077
|
-
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered.
|
|
21078
|
-
* It informs about system events, task completion or errors.
|
|
21581
|
+
* A notification is a closable message displayed in the upper-right corner that disappears after a few seconds unless hovered or focused.
|
|
21582
|
+
* It informs about system events, task completion, or errors. Severity indicates importance or urgency.
|
|
21079
21583
|
*
|
|
21080
21584
|
* Notifications can be grouped. Only the most recent notification within a group is displayed.
|
|
21081
21585
|
*
|
|
@@ -21143,7 +21647,7 @@ function migrateGroupInputReduceFn(config) {
|
|
|
21143
21647
|
*/
|
|
21144
21648
|
|
|
21145
21649
|
/*
|
|
21146
|
-
* Copyright (c) 2018-
|
|
21650
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
21147
21651
|
*
|
|
21148
21652
|
* This program and the accompanying materials are made
|
|
21149
21653
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -21205,7 +21709,7 @@ class PopupConfig {
|
|
|
21205
21709
|
*/
|
|
21206
21710
|
|
|
21207
21711
|
/*
|
|
21208
|
-
* Copyright (c) 2018-
|
|
21712
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
21209
21713
|
*
|
|
21210
21714
|
* This program and the accompanying materials are made
|
|
21211
21715
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -21285,7 +21789,7 @@ class PopupConfig {
|
|
|
21285
21789
|
*/
|
|
21286
21790
|
|
|
21287
21791
|
/*
|
|
21288
|
-
* Copyright (c) 2018-
|
|
21792
|
+
* Copyright (c) 2018-2026 Swiss Federal Railways
|
|
21289
21793
|
*
|
|
21290
21794
|
* This program and the accompanying materials are made
|
|
21291
21795
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -21311,5 +21815,5 @@ class PopupConfig {
|
|
|
21311
21815
|
* Generated bundle index. Do not edit.
|
|
21312
21816
|
*/
|
|
21313
21817
|
|
|
21314
|
-
export { ActivatedMicrofrontend, IconComponent, LogAppender, LogLevel, Logger, LoggerName, MAIN_AREA, MAIN_AREA_INITIAL_PART_ID, MicrofrontendPlatformConfigLoader, MicrofrontendPlatformStartupPhase, Notification, NotificationService, Popup, PopupConfig, PopupService, TextPipe, VIEW_TAB_RENDERING_CONTEXT, WORKBENCH_DIALOG_CONTEXT, WORKBENCH_ID, WORKBENCH_PART_CONTEXT, WORKBENCH_POPUP_CONTEXT, WORKBENCH_POPUP_REFERRER, WORKBENCH_VIEW_CONTEXT, WorkbenchComponent, WorkbenchConfig, WorkbenchDesktopDirective, WorkbenchDialog, WorkbenchDialogActionDirective, WorkbenchDialogFooterDirective, WorkbenchDialogHeaderDirective, WorkbenchDialogService, WorkbenchLauncher, WorkbenchLayoutFactory, WorkbenchMessageBoxService, WorkbenchNotification, WorkbenchNotificationService, WorkbenchPart, WorkbenchPartActionDirective, WorkbenchPerspectiveData, WorkbenchPopup, WorkbenchPopupService, WorkbenchRouteData, WorkbenchRouter, WorkbenchRouterLinkDirective, WorkbenchService, WorkbenchStartup, WorkbenchStartupPhase, WorkbenchStorage, WorkbenchView, WorkbenchViewMenuItemDirective, canMatchWorkbenchDialogCapability, canMatchWorkbenchMessageBoxCapability, canMatchWorkbenchOutlet, canMatchWorkbenchPart, canMatchWorkbenchPartCapability, canMatchWorkbenchPerspective, canMatchWorkbenchPopupCapability, canMatchWorkbenchView, canMatchWorkbenchViewCapability, provideMicrofrontendPlatformInitializer, provideWorkbench, provideWorkbenchInitializer, text };
|
|
21818
|
+
export { ActivatedMicrofrontend, IconComponent, LogAppender, LogLevel, Logger, LoggerName, MAIN_AREA, MAIN_AREA_INITIAL_PART_ID, MicrofrontendPlatformConfigLoader, MicrofrontendPlatformStartupPhase, Notification, NotificationService, Popup, PopupConfig, PopupService, TextPipe, VIEW_TAB_RENDERING_CONTEXT, WORKBENCH_DIALOG_CONTEXT, WORKBENCH_ID, WORKBENCH_PART_CONTEXT, WORKBENCH_POPUP_CONTEXT, WORKBENCH_POPUP_REFERRER, WORKBENCH_VIEW_CONTEXT, WorkbenchComponent, WorkbenchConfig, WorkbenchDesktopDirective, WorkbenchDialog, WorkbenchDialogActionDirective, WorkbenchDialogFooterDirective, WorkbenchDialogHeaderDirective, WorkbenchDialogService, WorkbenchLauncher, WorkbenchLayoutFactory, WorkbenchMessageBoxService, WorkbenchNotification, WorkbenchNotificationService, WorkbenchPart, WorkbenchPartActionDirective, WorkbenchPerspectiveData, WorkbenchPopup, WorkbenchPopupService, WorkbenchRouteData, WorkbenchRouter, WorkbenchRouterLinkDirective, WorkbenchService, WorkbenchStartup, WorkbenchStartupPhase, WorkbenchStorage, WorkbenchView, WorkbenchViewMenuItemDirective, canMatchWorkbenchDialogCapability, canMatchWorkbenchMessageBoxCapability, canMatchWorkbenchNotificationCapability, canMatchWorkbenchOutlet, canMatchWorkbenchPart, canMatchWorkbenchPartCapability, canMatchWorkbenchPerspective, canMatchWorkbenchPopupCapability, canMatchWorkbenchView, canMatchWorkbenchViewCapability, provideMicrofrontendPlatformInitializer, provideWorkbench, provideWorkbenchInitializer, text };
|
|
21315
21819
|
//# sourceMappingURL=scion-workbench.mjs.map
|