@scion/workbench 18.0.0-beta.4 → 18.0.0-beta.6

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.
Files changed (58) hide show
  1. package/esm2022/lib/executor/single-task-executor.mjs +3 -3
  2. package/esm2022/lib/layout//311/265workbench-layout.factory.mjs +2 -1
  3. package/esm2022/lib/layout//311/265workbench-layout.mjs +3 -1
  4. package/esm2022/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.mjs +5 -4
  5. package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.mjs +5 -4
  6. package/esm2022/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.mjs +9 -8
  7. package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.mjs +7 -8
  8. package/esm2022/lib/microfrontend-platform/workbench-microfrontend-support.mjs +2 -2
  9. package/esm2022/lib/part/view-context-menu/text.component.mjs +16 -12
  10. package/esm2022/lib/part/view-context-menu/view-menu.service.mjs +19 -19
  11. package/esm2022/lib/perspective//311/265workbench-perspective.model.mjs +32 -29
  12. package/esm2022/lib/popup/popup.config.mjs +4 -13
  13. package/esm2022/lib/popup/popup.service.mjs +4 -9
  14. package/esm2022/lib/portal/wb-component-portal.mjs +4 -2
  15. package/esm2022/lib/routing/public_api.mjs +2 -1
  16. package/esm2022/lib/routing/workbench-navigational-states.mjs +2 -2
  17. package/esm2022/lib/routing/workbench-route-guards.mjs +57 -0
  18. package/esm2022/lib/routing/workbench-url-observer.service.mjs +3 -2
  19. package/esm2022/lib/routing//311/265workbench-router.service.mjs +22 -16
  20. package/esm2022/lib/startup/workbench-launcher.service.mjs +7 -10
  21. package/esm2022/lib/view/public_api.mjs +1 -2
  22. package/esm2022/lib/view/view.component.mjs +22 -11
  23. package/esm2022/lib/view//311/265workbench-view.model.mjs +3 -5
  24. package/esm2022/lib/workbench-config.mjs +2 -2
  25. package/esm2022/lib/workbench.component.mjs +24 -4
  26. package/esm2022/lib/workbench.model.mjs +1 -1
  27. package/esm2022/lib/workbench.service.mjs +1 -1
  28. package/esm2022/lib//311/265workbench.service.mjs +1 -1
  29. package/fesm2022/scion-workbench.mjs +190 -151
  30. package/fesm2022/scion-workbench.mjs.map +1 -1
  31. package/lib/executor/single-task-executor.d.ts +2 -2
  32. package/lib/layout//311/265workbench-layout.d.ts +2 -0
  33. package/lib/layout//311/265workbench-layout.factory.d.ts +1 -0
  34. package/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.d.ts +2 -1
  35. package/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.d.ts +2 -1
  36. package/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.d.ts +2 -1
  37. package/lib/part/view-context-menu/text.component.d.ts +3 -4
  38. package/lib/part/view-context-menu/view-menu.service.d.ts +5 -5
  39. package/lib/perspective/workbench-perspective.service.d.ts +1 -1
  40. package/lib/perspective//311/265workbench-perspective.model.d.ts +6 -7
  41. package/lib/popup/popup.config.d.ts +9 -10
  42. package/lib/popup/popup.service.d.ts +1 -1
  43. package/lib/portal/wb-component-portal.d.ts +18 -0
  44. package/lib/routing/public_api.d.ts +1 -0
  45. package/lib/routing/workbench-navigational-states.d.ts +5 -1
  46. package/lib/{view/workbench-view-route-guards.d.ts → routing/workbench-route-guards.d.ts} +6 -0
  47. package/lib/routing//311/265workbench-router.service.d.ts +4 -1
  48. package/lib/startup/workbench-launcher.service.d.ts +4 -5
  49. package/lib/view/public_api.d.ts +0 -1
  50. package/lib/view/view.component.d.ts +13 -3
  51. package/lib/view//311/265workbench-view.model.d.ts +0 -2
  52. package/lib/workbench-config.d.ts +15 -3
  53. package/lib/workbench.component.d.ts +5 -0
  54. package/lib/workbench.model.d.ts +7 -3
  55. package/lib/workbench.service.d.ts +2 -2
  56. package/lib//311/265workbench.service.d.ts +1 -1
  57. package/package.json +2 -2
  58. package/esm2022/lib/view/workbench-view-route-guards.mjs +0 -47
@@ -1,8 +1,8 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  /**
3
- * Serializes navigation requests to the Angular Router to prevent cancelling of parallel navigations or race conditions when modifying the currently active workbench layout.
3
+ * Serializes navigation requests to the Angular Router to prevent the cancellation of previously initiated asynchronous navigations.
4
4
  */
5
- export declare const SINGLE_NAVIGATION_EXECUTOR: InjectionToken<SingleTaskExecutor>;
5
+ export declare const ANGULAR_ROUTER_MUTEX: InjectionToken<SingleTaskExecutor>;
6
6
  /**
7
7
  * Allows the serial execution of tasks.
8
8
  *
@@ -30,6 +30,8 @@ export declare class ɵWorkbenchLayout implements WorkbenchLayout {
30
30
  private readonly _serializer;
31
31
  private readonly _injector;
32
32
  private _maximized;
33
+ /** Identifies the perspective of this layout, if any. */
34
+ readonly perspectiveId: string | undefined;
33
35
  /**
34
36
  * Reference to the main workbench grid.
35
37
  */
@@ -26,6 +26,7 @@ export declare class ɵWorkbenchLayoutFactory implements WorkbenchLayoutFactory
26
26
  create(options?: {
27
27
  workbenchGrid?: string | MPartGrid | null;
28
28
  mainAreaGrid?: string | MPartGrid | null;
29
+ perspectiveId?: string;
29
30
  viewOutlets?: ViewOutlets | string;
30
31
  navigationStates?: NavigationStates;
31
32
  injector?: Injector;
@@ -19,7 +19,8 @@ export declare class MicrofrontendHostDialogComponent implements OnDestroy, OnIn
19
19
  params: Map<string, unknown>;
20
20
  protected outletName: string;
21
21
  protected outletInjector: Injector;
22
- private _singleNavigationExecutor;
22
+ /** Mutex to serialize Angular Router navigation requests, preventing the cancellation of previously initiated asynchronous navigations. */
23
+ private _angularRouterMutex;
23
24
  constructor(_dialog: ɵWorkbenchDialog, _injector: Injector, _router: Router);
24
25
  ngOnInit(): void;
25
26
  /**
@@ -20,7 +20,8 @@ export declare class MicrofrontendHostMessageBoxComponent implements OnDestroy,
20
20
  params: Map<string, unknown>;
21
21
  protected outletName: string;
22
22
  protected outletInjector: Injector;
23
- private _singleNavigationExecutor;
23
+ /** Mutex to serialize Angular Router navigation requests, preventing the cancellation of previously initiated asynchronous navigations. */
24
+ private _angularRouterMutex;
24
25
  constructor(_host: ElementRef<HTMLElement>, _dialog: ɵWorkbenchDialog, _injector: Injector, _router: Router);
25
26
  ngOnInit(): void;
26
27
  /**
@@ -14,7 +14,8 @@ export declare class MicrofrontendHostPopupComponent implements OnDestroy {
14
14
  private _router;
15
15
  readonly outletName: string;
16
16
  readonly outletInjector: Injector;
17
- private _singleNavigationExecutor;
17
+ /** Mutex to serialize Angular Router navigation requests, preventing the cancellation of previously initiated asynchronous navigations. */
18
+ private _angularRouterMutex;
18
19
  constructor(popup: ɵPopup<ɵPopupContext>, _injector: Injector, _router: Router);
19
20
  /**
20
21
  * Performs navigation in the specified outlet, substituting path params if any. To clear navigation, pass `null` as the path.
@@ -1,12 +1,11 @@
1
- import { InjectionToken } from '@angular/core';
1
+ import { InjectionToken, Signal } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
- export declare const TEXT: InjectionToken<string>;
3
+ export declare const TEXT: InjectionToken<string | (() => string | Signal<string>)>;
4
4
  /**
5
5
  * Component which renders text injected via {@link TEXT} injection token.
6
6
  */
7
7
  export declare class TextComponent {
8
- text: string;
9
- constructor(text: string);
8
+ protected text: Signal<string>;
10
9
  static ɵfac: i0.ɵɵFactoryDeclaration<TextComponent, never>;
11
10
  static ɵcmp: i0.ɵɵComponentDeclaration<TextComponent, "wb-text", never, {}, {}, never, never, true, never>;
12
11
  }
@@ -28,11 +28,11 @@ export declare class ViewMenuService {
28
28
  * Upon subscription, installs keyboard accelerators of the menu items registered in {@link WorkbenchView}.
29
29
  */
30
30
  installMenuItemAccelerators$(target: ElementRef<HTMLElement> | HTMLElement, view: ɵWorkbenchView): Observable<void>;
31
- private registerCloseViewMenuItem;
32
- private registerCloseOtherViewsMenuItem;
33
- private registerCloseAllViewsMenuItem;
34
- private registerCloseViewsToTheRightMenuItem;
35
- private registerCloseViewsToTheLeftMenuItem;
31
+ private registerCloseMenuItem;
32
+ private registerCloseOtherTabsMenuItem;
33
+ private registerCloseAllTabsMenuItem;
34
+ private registerCloseRightTabsMenuItem;
35
+ private registerCloseLeftTabsMenuItem;
36
36
  private registerMoveRightMenuItem;
37
37
  private registerMoveLeftMenuItem;
38
38
  private registerMoveUpMenuItem;
@@ -11,7 +11,7 @@ export declare class WorkbenchPerspectiveService implements WorkbenchInitializer
11
11
  private readonly _environmentInjector;
12
12
  private readonly _applicationInitStatus;
13
13
  private readonly _workbenchPerspectiveStorageService;
14
- readonly activePerspective: import("@angular/core").WritableSignal<ɵWorkbenchPerspective | null>;
14
+ readonly activePerspective: import("@angular/core").Signal<ɵWorkbenchPerspective | undefined>;
15
15
  init(): Promise<void>;
16
16
  /**
17
17
  * Registers perspectives configured in {@link WorkbenchConfig}.
@@ -1,9 +1,5 @@
1
- import { InjectionToken, Injector, Signal, WritableSignal } from '@angular/core';
1
+ import { InjectionToken, Injector, Signal } from '@angular/core';
2
2
  import { WorkbenchPerspective, WorkbenchPerspectiveDefinition } from './workbench-perspective.model';
3
- /**
4
- * Provides the activated perspective.
5
- */
6
- export declare const ACTIVE_PERSPECTIVE: InjectionToken<WritableSignal<ɵWorkbenchPerspective | null>>;
7
3
  /**
8
4
  * @inheritDoc
9
5
  */
@@ -15,7 +11,6 @@ export declare class ɵWorkbenchPerspective implements WorkbenchPerspective {
15
11
  private readonly _workbenchLayoutService;
16
12
  private readonly _workbenchRouter;
17
13
  private readonly _initialLayoutFn;
18
- private readonly _activePerspective;
19
14
  private readonly _perspectiveViewConflictResolver;
20
15
  readonly id: string;
21
16
  readonly transient: boolean;
@@ -39,7 +34,7 @@ export declare class ɵWorkbenchPerspective implements WorkbenchPerspective {
39
34
  */
40
35
  get injector(): Injector;
41
36
  /**
42
- * Creates layout with the workbench grid of this perspective and the main area of the current layout.
37
+ * Creates the perspective layout using the main area of the current layout.
43
38
  *
44
39
  * When switching perspective, id clashes between the views contained in the perspective and the
45
40
  * views contained in the main area are possible. The activation detects and resolves conflicts,
@@ -71,3 +66,7 @@ export declare class ɵWorkbenchPerspective implements WorkbenchPerspective {
71
66
  private storePerspectiveLayout;
72
67
  destroy(): void;
73
68
  }
69
+ /**
70
+ * Provides the currently active perspective in the workbench.
71
+ */
72
+ export declare const ACTIVE_PERSPECTIVE: InjectionToken<Signal<ɵWorkbenchPerspective | undefined>>;
@@ -111,14 +111,13 @@ export declare abstract class PopupConfig {
111
111
  */
112
112
  export interface CloseStrategy {
113
113
  /**
114
- * If `true`, which is by default, will close the popup on focus loss.
115
- * No return value will be passed to the popup opener.
114
+ * Controls if to close the popup on focus loss, returning the result set via {@link Popup#setResult} to the popup opener.
115
+ * Defaults to `true`.
116
116
  */
117
117
  onFocusLost?: boolean;
118
118
  /**
119
- * If `true`, which is by default, will close the popup when the user
120
- * hits the escape key. No return value will be passed to the popup
121
- * opener.
119
+ * Controls if to close the popup when pressing escape. Defaults to `true`.
120
+ * No return value will be passed to the popup opener.
122
121
  */
123
122
  onEscape?: boolean;
124
123
  }
@@ -155,7 +154,7 @@ export interface PopupSize {
155
154
  * Represents a handle that a popup component can inject to interact with the popup, for example,
156
155
  * to read input data or the configured size, or to close the popup.
157
156
  */
158
- export declare abstract class Popup<T = any> {
157
+ export declare abstract class Popup<T = unknown, R = unknown> {
159
158
  /**
160
159
  * Input data as passed by the popup opener when opened the popup, or `undefined` if not passed.
161
160
  */
@@ -175,13 +174,13 @@ export declare abstract class Popup<T = any> {
175
174
  */
176
175
  abstract readonly cssClasses: string[];
177
176
  /**
178
- * Closes the popup. Optionally, pass a result to the popup opener.
177
+ * Sets a result that will be passed to the popup opener when the popup is closed on focus loss {@link CloseStrategy#onFocusLost}.
179
178
  */
180
- abstract close<R = any>(result?: R | undefined): void;
179
+ abstract setResult(result?: R): void;
181
180
  /**
182
- * Closes the popup returning the given error to the popup opener.
181
+ * Closes the popup. Optionally, pass a result or an error to the popup opener.
183
182
  */
184
- abstract closeWithError(error: Error | string): void;
183
+ abstract close(result?: R | Error): void;
185
184
  }
186
185
  /**
187
186
  * Information about the context in which a popup was opened.
@@ -41,7 +41,7 @@ export declare class PopupService {
41
41
  * - resolves to the result if closed with a result
42
42
  * - resolves to `undefined` if closed without a result
43
43
  */
44
- open<R>(config: PopupConfig): Promise<R>;
44
+ open<R>(config: PopupConfig): Promise<R | undefined>;
45
45
  /**
46
46
  * Creates the popup handle.
47
47
  */
@@ -63,3 +63,21 @@ export interface PortalOptions {
63
63
  */
64
64
  providers?: Provider[];
65
65
  }
66
+ /**
67
+ * Lifecycle hook for component rendered by {@link WbComponentPortal} when attaching to the DOM.
68
+ */
69
+ export interface OnAttach {
70
+ /**
71
+ * Method invoked after attached this component to the DOM.
72
+ */
73
+ onAttach(): void;
74
+ }
75
+ /**
76
+ * Lifecycle hook for component rendered by {@link WbComponentPortal} when detaching from the DOM.
77
+ */
78
+ export interface OnDetach {
79
+ /**
80
+ * Method invoked before detaching this component from the DOM.
81
+ */
82
+ onDetach(): void;
83
+ }
@@ -2,3 +2,4 @@ export { WorkbenchRouter } from './workbench-router.service';
2
2
  export { WorkbenchRouterLinkDirective } from './workbench-router-link.directive';
3
3
  export { WorkbenchRouteData } from './workbench-route-data';
4
4
  export { Commands, NavigationData, NavigationState, WorkbenchNavigationExtras, NavigateFn } from './routing.model';
5
+ export { canMatchWorkbenchView, canMatchWorkbenchPerspective } from './workbench-route-guards';
@@ -5,7 +5,7 @@ import { NavigationStates } from './routing.model';
5
5
  */
6
6
  export declare const WorkbenchNavigationalStates: {
7
7
  /**
8
- * Returns workbench-specific state associated with given navigation, or `null` if not a workbench navigation.
8
+ * Returns workbench-specific state associated with given navigation, or `null` if the navigation was not performed through the workbench router.
9
9
  */
10
10
  readonly fromNavigation: (navigation: Navigation) => WorkbenchNavigationalState | null;
11
11
  /**
@@ -25,6 +25,10 @@ export interface WorkbenchNavigationalState {
25
25
  * Note: The main area grid is not passed as navigational state, but as query parameter {@link MAIN_AREA_LAYOUT_QUERY_PARAM}.
26
26
  */
27
27
  workbenchGrid: string;
28
+ /**
29
+ * Identifies the perspective that is navigated.
30
+ */
31
+ perspectiveId?: string | undefined;
28
32
  /**
29
33
  * Indicates whether to maximize the main area.
30
34
  */
@@ -28,6 +28,12 @@ export declare function canMatchWorkbenchView(navigationHint: string): CanMatchF
28
28
  * Can be used to guard the application's root route from matching an empty path view navigation.
29
29
  */
30
30
  export declare function canMatchWorkbenchView(canMatch: boolean): CanMatchFn;
31
+ /**
32
+ * Matches the route based on the active perspective.
33
+ *
34
+ * Can be used to have a different start page per perspective.
35
+ */
36
+ export declare function canMatchWorkbenchPerspective(id: string): CanMatchFn;
31
37
  /**
32
38
  * Matches if the view has been navigated.
33
39
  *
@@ -11,7 +11,10 @@ export declare class ɵWorkbenchRouter implements WorkbenchRouter {
11
11
  private readonly _injector;
12
12
  private readonly _logger;
13
13
  private readonly _zone;
14
- private readonly _singleNavigationExecutor;
14
+ /** Mutex to serialize Workbench Router navigation requests, preventing race conditions when modifying the active workbench layout to operate on the most-recent layout. */
15
+ private readonly _workbenchRouterMutex;
16
+ /** Mutex to serialize Angular Router navigation requests, preventing the cancellation of previously initiated asynchronous navigations. */
17
+ private readonly _angularRouterMutex;
15
18
  /** Holds the current navigational context during a workbench navigation, or `null` if no navigation is in progress. */
16
19
  private _currentNavigationContext;
17
20
  constructor();
@@ -82,15 +82,14 @@ export declare class WorkbenchLauncher {
82
82
  * Allows waiting for the workbench startup to complete.
83
83
  */
84
84
  export declare class WorkbenchStartup {
85
- private _started;
86
85
  /**
87
- * Promise that resolves when the workbench has completed the startup.
86
+ * Signals when the workbench completed startup.
88
87
  */
89
- readonly whenStarted: Promise<true>;
88
+ readonly isStarted: import("@angular/core").WritableSignal<boolean>;
90
89
  /**
91
- * Returns whether the workbench completed startup.
90
+ * Promise that resolves when the workbench has completed the startup.
92
91
  */
93
- isStarted(): boolean;
92
+ readonly whenStarted: Promise<true>;
94
93
  static ɵfac: i0.ɵɵFactoryDeclaration<WorkbenchStartup, never>;
95
94
  static ɵprov: i0.ɵɵInjectableDeclaration<WorkbenchStartup>;
96
95
  }
@@ -1,2 +1 @@
1
1
  export { WorkbenchView, ViewId } from './workbench-view.model';
2
- export { canMatchWorkbenchView } from './workbench-view-route-guards';
@@ -2,24 +2,34 @@ import { OnDestroy } from '@angular/core';
2
2
  import { ɵWorkbenchView } from './ɵworkbench-view.model';
3
3
  import { Logger } from '../logging';
4
4
  import { ViewDragService } from '../view-dnd/view-drag.service';
5
+ import { OnAttach, OnDetach } from '../portal/wb-component-portal';
5
6
  import * as i0 from "@angular/core";
6
7
  import * as i1 from "../glass-pane/glass-pane.directive";
7
8
  import * as i2 from "@angular/common";
8
9
  /**
9
10
  * Renders the workbench view, using a router-outlet to display view content.
10
11
  */
11
- export declare class ViewComponent implements OnDestroy {
12
+ export declare class ViewComponent implements OnDestroy, OnAttach, OnDetach {
12
13
  private _view;
13
14
  private _viewDragService;
14
15
  private _logger;
15
16
  private _viewport;
17
+ private _scrollTop;
18
+ private _scrollLeft;
16
19
  get viewId(): string;
17
20
  get isViewDragActive(): boolean;
18
21
  constructor(_view: ɵWorkbenchView, _viewDragService: ViewDragService, _logger: Logger);
22
+ /**
23
+ * Method invoked after attached this component to the DOM.
24
+ */
25
+ onAttach(): void;
26
+ /**
27
+ * Method invoked before detaching this component from the DOM.
28
+ */
29
+ onDetach(): void;
19
30
  private onActivateView;
20
- private onDeactivateView;
21
31
  private installMenuItemAccelerators;
22
- private subscribeForViewActivation;
32
+ private installOnActivateView;
23
33
  private addHostCssClasses;
24
34
  ngOnDestroy(): void;
25
35
  static ɵfac: i0.ɵɵFactoryDeclaration<ViewComponent, never>;
@@ -50,8 +50,6 @@ export declare class ɵWorkbenchView implements WorkbenchView, Blockable {
50
50
  position: Signal<number>;
51
51
  first: Signal<boolean>;
52
52
  last: Signal<boolean>;
53
- scrollTop: number;
54
- scrollLeft: number;
55
53
  readonly part: import("@angular/core").WritableSignal<ɵWorkbenchPart>;
56
54
  readonly active: import("@angular/core").WritableSignal<boolean>;
57
55
  readonly menuItems$: Observable<WorkbenchMenuItem[]>;
@@ -1,5 +1,5 @@
1
1
  import { ComponentType } from '@angular/cdk/portal';
2
- import { Type } from '@angular/core';
2
+ import { Signal, Type } from '@angular/core';
3
3
  import { LogAppender, LogLevel } from './logging';
4
4
  import { MicrofrontendPlatformConfig } from '@scion/microfrontend-platform';
5
5
  import { MicrofrontendPlatformConfigLoader } from './microfrontend-platform/microfrontend-platform-config-loader';
@@ -126,7 +126,9 @@ export declare abstract class WorkbenchConfig {
126
126
  };
127
127
  }
128
128
  /**
129
- * Controls which built-in menu items to display in the view context menu.
129
+ * Configuration of built-in menu items in the view's context menu.
130
+ *
131
+ * Each property represents a menu item, allowing customization of visibility, text, accelerators, and more.
130
132
  */
131
133
  export interface ViewMenuItemsConfig {
132
134
  close?: MenuItemConfig;
@@ -140,9 +142,19 @@ export interface ViewMenuItemsConfig {
140
142
  moveLeft?: MenuItemConfig;
141
143
  moveToNewWindow?: MenuItemConfig;
142
144
  }
145
+ /**
146
+ * Configures a built-in menu item.
147
+ */
143
148
  export interface MenuItemConfig {
144
149
  visible?: boolean;
145
- text?: string;
150
+ /**
151
+ * Specifies the text of this menu item.
152
+ *
153
+ * Can be a string or a function that returns a string or a {@link Signal}.
154
+ *
155
+ * The function can call `inject` to get any required dependencies, or use `toSignal` to convert an observable to a signal.
156
+ */
157
+ text?: string | (() => string | Signal<string>);
146
158
  accelerator?: string[];
147
159
  group?: string;
148
160
  cssClass?: string | string[];
@@ -42,6 +42,11 @@ export declare class WorkbenchComponent implements OnDestroy {
42
42
  * Unsets view container references when this component is destroyed.
43
43
  */
44
44
  private unsetViewContainerReferences;
45
+ /**
46
+ * Disables change detection during navigation to avoid partial DOM updates of the workbench layout
47
+ * if the navigation is asynchronous (e.g., because of lazy loading, async guards, or resolvers).
48
+ */
49
+ private disableChangeDetectionDuringNavigation;
45
50
  ngOnDestroy(): void;
46
51
  static ɵfac: i0.ɵɵFactoryDeclaration<WorkbenchComponent, never>;
47
52
  static ɵcmp: i0.ɵɵComponentDeclaration<WorkbenchComponent, "wb-workbench", never, {}, {}, never, never, true, never>;
@@ -48,7 +48,10 @@ export interface WorkbenchPartAction {
48
48
  *
49
49
  * By default, if not specified, matches any part.
50
50
  *
51
- * The function can call `inject` to get any required dependencies.
51
+ * The function:
52
+ * - Can call `inject` to get any required dependencies.
53
+ * - Runs in a reactive context, re-evaluating when tracked signals change.
54
+ * To execute code outside this reactive context, use Angular's `untracked` function.
52
55
  */
53
56
  canMatch?: CanMatchPartFn;
54
57
  /**
@@ -59,8 +62,9 @@ export interface WorkbenchPartAction {
59
62
  /**
60
63
  * The signature of a function used as a `canMatch` condition for a part.
61
64
  *
62
- * - The function can call `inject` to get any required dependencies.
63
- * - The function runs in a reactive context, re-evaluating when tracked signals change.
65
+ * The function:
66
+ * - Can call `inject` to get any required dependencies.
67
+ * - Runs in a reactive context, re-evaluating when tracked signals change.
64
68
  * To execute code outside this reactive context, use Angular's `untracked` function.
65
69
  */
66
70
  export type CanMatchPartFn = (part: WorkbenchPart) => boolean;
@@ -38,9 +38,9 @@ export declare abstract class WorkbenchService {
38
38
  */
39
39
  abstract readonly perspectives: Signal<WorkbenchPerspective[]>;
40
40
  /**
41
- * Provides the currently active perspective, or `null` if the initial perspective is not yet activated, e.g., during startup.
41
+ * Provides the active perspective, or `undefined` if none is active (e.g., during workbench startup).
42
42
  */
43
- abstract readonly activePerspective: Signal<WorkbenchPerspective | null>;
43
+ abstract readonly activePerspective: Signal<WorkbenchPerspective | undefined>;
44
44
  /**
45
45
  * Returns the handle of the specified perspective, or `null` if not found.
46
46
  */
@@ -24,7 +24,7 @@ export declare class ɵWorkbenchService implements WorkbenchService {
24
24
  readonly parts: Signal<ɵWorkbenchPart[]>;
25
25
  readonly views: Signal<ɵWorkbenchView[]>;
26
26
  readonly theme: Signal<WorkbenchTheme | null>;
27
- readonly activePerspective: Signal<WorkbenchPerspective | null>;
27
+ readonly activePerspective: Signal<WorkbenchPerspective | undefined>;
28
28
  readonly viewMenuItemProviders$: BehaviorSubject<WorkbenchMenuItemFactoryFn[]>;
29
29
  constructor();
30
30
  /** @inheritDoc */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scion/workbench",
3
- "version": "18.0.0-beta.4",
3
+ "version": "18.0.0-beta.6",
4
4
  "description": "SCION Workbench enables the creation of Angular web applications that require a flexible layout to arrange content side-by-side or stacked, all personalizable by the user via drag & drop.",
5
5
  "license": "EPL-2.0",
6
6
  "private": false,
@@ -39,7 +39,7 @@
39
39
  "@scion/components": "^18.0.0",
40
40
  "@scion/toolkit": "^1.4.0",
41
41
  "@scion/microfrontend-platform": "^1.3.0",
42
- "@scion/workbench-client": "^1.0.0-beta.24",
42
+ "@scion/workbench-client": "^1.0.0-beta.26",
43
43
  "rxjs": "^7.8.0"
44
44
  },
45
45
  "peerDependenciesMeta": {
@@ -1,47 +0,0 @@
1
- /*
2
- * Copyright (c) 2018-2024 Swiss Federal Railways
3
- *
4
- * This program and the accompanying materials are made
5
- * available under the terms of the Eclipse Public License 2.0
6
- * which is available at https://www.eclipse.org/legal/epl-2.0/
7
- *
8
- * SPDX-License-Identifier: EPL-2.0
9
- */
10
- import { inject } from '@angular/core';
11
- import { ɵWorkbenchRouter } from '../routing/ɵworkbench-router.service';
12
- import { WorkbenchLayouts } from '../layout/workbench-layouts.util';
13
- import { WORKBENCH_AUXILIARY_ROUTE_OUTLET } from '../routing/workbench-auxiliary-route-installer.service';
14
- export function canMatchWorkbenchView(condition) {
15
- return () => {
16
- const outlet = inject(WORKBENCH_AUXILIARY_ROUTE_OUTLET, { optional: true });
17
- switch (condition) {
18
- case true:
19
- return WorkbenchLayouts.isViewId(outlet);
20
- case false:
21
- return !WorkbenchLayouts.isViewId(outlet);
22
- default: { // hint
23
- if (!WorkbenchLayouts.isViewId(outlet)) {
24
- return false;
25
- }
26
- const layout = inject(ɵWorkbenchRouter).getCurrentNavigationContext().layout;
27
- const view = layout.view({ viewId: outlet }, { orElse: null });
28
- return view?.navigation?.hint === condition;
29
- }
30
- }
31
- };
32
- }
33
- /**
34
- * Matches if the view has been navigated.
35
- *
36
- * Does not match if no navigation information is available, e.g., during initial navigation because the layout is loaded asynchronously, or when closing the view.
37
- */
38
- export const canMatchNotFoundPage = () => {
39
- const outlet = inject(WORKBENCH_AUXILIARY_ROUTE_OUTLET, { optional: true });
40
- if (!WorkbenchLayouts.isViewId(outlet)) {
41
- throw Error(`[ViewError] CanMatchFn must be installed on a view auxiliary route. [outlet=${outlet}]`);
42
- }
43
- const layout = inject(ɵWorkbenchRouter).getCurrentNavigationContext().layout;
44
- const view = layout.view({ viewId: outlet }, { orElse: null });
45
- return !!view?.navigation;
46
- };
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2JlbmNoLXZpZXctcm91dGUtZ3VhcmRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vd29ya2JlbmNoL3NyYy9saWIvdmlldy93b3JrYmVuY2gtdmlldy1yb3V0ZS1ndWFyZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFHSCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQ2xFLE9BQU8sRUFBQyxnQ0FBZ0MsRUFBQyxNQUFNLHdEQUF3RCxDQUFDO0FBK0J4RyxNQUFNLFVBQVUscUJBQXFCLENBQUMsU0FBMkI7SUFDL0QsT0FBTyxHQUFZLEVBQUU7UUFDbkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGdDQUFnQyxFQUFFLEVBQUMsUUFBUSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7UUFFMUUsUUFBUSxTQUFTLEVBQUUsQ0FBQztZQUNsQixLQUFLLElBQUk7Z0JBQ1AsT0FBTyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0MsS0FBSyxLQUFLO2dCQUNSLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU87Z0JBQ2hCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztvQkFDdkMsT0FBTyxLQUFLLENBQUM7Z0JBQ2YsQ0FBQztnQkFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQywyQkFBMkIsRUFBRSxDQUFDLE1BQU0sQ0FBQztnQkFDN0UsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO2dCQUMzRCxPQUFPLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxLQUFLLFNBQVMsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQWUsR0FBWSxFQUFFO0lBQzVELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxnQ0FBZ0MsRUFBRSxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO0lBRTFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUN2QyxNQUFNLEtBQUssQ0FBQywrRUFBK0UsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN4RyxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxNQUFNLENBQUM7SUFDN0UsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO0lBQzNELE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUM7QUFDNUIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOC0yMDI0IFN3aXNzIEZlZGVyYWwgUmFpbHdheXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlXG4gKiBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIDIuMFxuICogd2hpY2ggaXMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0Nhbk1hdGNoRm59IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge2luamVjdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge8m1V29ya2JlbmNoUm91dGVyfSBmcm9tICcuLi9yb3V0aW5nL8m1d29ya2JlbmNoLXJvdXRlci5zZXJ2aWNlJztcbmltcG9ydCB7V29ya2JlbmNoTGF5b3V0c30gZnJvbSAnLi4vbGF5b3V0L3dvcmtiZW5jaC1sYXlvdXRzLnV0aWwnO1xuaW1wb3J0IHtXT1JLQkVOQ0hfQVVYSUxJQVJZX1JPVVRFX09VVExFVH0gZnJvbSAnLi4vcm91dGluZy93b3JrYmVuY2gtYXV4aWxpYXJ5LXJvdXRlLWluc3RhbGxlci5zZXJ2aWNlJztcblxuLyoqXG4gKiBNYXRjaGVzIHRoZSByb3V0ZSBpZiB0YXJnZXQgb2YgYSB3b3JrYmVuY2ggdmlldyBhbmQgbmF2aWdhdGluZyB3aXRoIHRoZSBnaXZlbiBoaW50LlxuICpcbiAqIENhbiBiZSB1c2VkIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiByb3V0ZXMgd2l0aCBhbiBpZGVudGljYWwgcGF0aC4gRm9yIGV4YW1wbGUsIHRoZSB2aWV3cyBvZiB0aGUgaW5pdGlhbCBsYXlvdXQgb3IgYSBwZXJzcGVjdGl2ZVxuICogYXJlIHVzdWFsbHkgbmF2aWdhdGVkIHRvIHRoZSBlbXB0eSBwYXRoIHJvdXRlIHRvIGF2b2lkIGNsdXR0ZXJpbmcgdGhlIFVSTC4gQSBoaW50IGNhbiBiZSBzZXQgd2hlbiBuYXZpZ2F0aW5nIHRoZSB2aWV3IHRvIG1hdGNoIGFcbiAqIHBhcnRpY3VsYXIgcm91dGUuXG4gKlxuICogIyMjIEV4YW1wbGU6XG4gKlxuICogVGhlIGZvbGxvd2luZyByb3V0ZXMgYm90aCBtYXRjaCB0aGUgZW1wdHkgcGF0aCwgYnV0IG9ubHkgaWYgbmF2aWdhdGVkIHdpdGggYSBzcGVjaWZpYyBoaW50LlxuICogYGBgdHNcbiAqIGNvbnN0IHJvdXRlczogUm91dGVzID0gW1xuICogICB7cGF0aDogJycsIGNhbk1hdGNoOiBbY2FuTWF0Y2hXb3JrYmVuY2hWaWV3KCduYXZpZ2F0b3InKV0sIGNvbXBvbmVudDogTmF2aWdhdG9yQ29tcG9uZW50fSxcbiAqICAge3BhdGg6ICcnLCBjYW5NYXRjaDogW2Nhbk1hdGNoV29ya2JlbmNoVmlldygnb3V0bGluZScpXSwgY29tcG9uZW50OiBPdXRsaW5lQ29tcG9uZW50fSxcbiAqIF07XG4gKiBgYGBcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgbmF2aWdhdGVzIHRvIHRoZSBgT3V0bGluZUNvbXBvbmVudGAsIHBhc3NpbmcgYSBoaW50IHRvIG1hdGNoIHRoZSByb3V0ZS5cbiAqIGBgYHRzXG4gKiBpbmplY3QoV29ya2JlbmNoUm91dGVyKS5uYXZpZ2F0ZShbXSwge2hpbnQ6ICdvdXRsaW5lJ30pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5NYXRjaFdvcmtiZW5jaFZpZXcobmF2aWdhdGlvbkhpbnQ6IHN0cmluZyk6IENhbk1hdGNoRm47XG4vKipcbiAqIE1hdGNoZXMgdGhlIHJvdXRlIGlmLCBvciBpZiBub3QgdGFyZ2V0IG9mIGEgd29ya2JlbmNoIHZpZXcuXG4gKlxuICogQ2FuIGJlIHVzZWQgdG8gZ3VhcmQgdGhlIGFwcGxpY2F0aW9uJ3Mgcm9vdCByb3V0ZSBmcm9tIG1hdGNoaW5nIGFuIGVtcHR5IHBhdGggdmlldyBuYXZpZ2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FuTWF0Y2hXb3JrYmVuY2hWaWV3KGNhbk1hdGNoOiBib29sZWFuKTogQ2FuTWF0Y2hGbjtcbmV4cG9ydCBmdW5jdGlvbiBjYW5NYXRjaFdvcmtiZW5jaFZpZXcoY29uZGl0aW9uOiBzdHJpbmcgfCBib29sZWFuKTogQ2FuTWF0Y2hGbiB7XG4gIHJldHVybiAoKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3Qgb3V0bGV0ID0gaW5qZWN0KFdPUktCRU5DSF9BVVhJTElBUllfUk9VVEVfT1VUTEVULCB7b3B0aW9uYWw6IHRydWV9KTtcblxuICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7XG4gICAgICBjYXNlIHRydWU6XG4gICAgICAgIHJldHVybiBXb3JrYmVuY2hMYXlvdXRzLmlzVmlld0lkKG91dGxldCk7XG4gICAgICBjYXNlIGZhbHNlOlxuICAgICAgICByZXR1cm4gIVdvcmtiZW5jaExheW91dHMuaXNWaWV3SWQob3V0bGV0KTtcbiAgICAgIGRlZmF1bHQ6IHsgLy8gaGludFxuICAgICAgICBpZiAoIVdvcmtiZW5jaExheW91dHMuaXNWaWV3SWQob3V0bGV0KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxheW91dCA9IGluamVjdCjJtVdvcmtiZW5jaFJvdXRlcikuZ2V0Q3VycmVudE5hdmlnYXRpb25Db250ZXh0KCkubGF5b3V0O1xuICAgICAgICBjb25zdCB2aWV3ID0gbGF5b3V0LnZpZXcoe3ZpZXdJZDogb3V0bGV0fSwge29yRWxzZTogbnVsbH0pO1xuICAgICAgICByZXR1cm4gdmlldz8ubmF2aWdhdGlvbj8uaGludCA9PT0gY29uZGl0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBNYXRjaGVzIGlmIHRoZSB2aWV3IGhhcyBiZWVuIG5hdmlnYXRlZC5cbiAqXG4gKiBEb2VzIG5vdCBtYXRjaCBpZiBubyBuYXZpZ2F0aW9uIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZSwgZS5nLiwgZHVyaW5nIGluaXRpYWwgbmF2aWdhdGlvbiBiZWNhdXNlIHRoZSBsYXlvdXQgaXMgbG9hZGVkIGFzeW5jaHJvbm91c2x5LCBvciB3aGVuIGNsb3NpbmcgdGhlIHZpZXcuXG4gKi9cbmV4cG9ydCBjb25zdCBjYW5NYXRjaE5vdEZvdW5kUGFnZTogQ2FuTWF0Y2hGbiA9ICgpOiBib29sZWFuID0+IHtcbiAgY29uc3Qgb3V0bGV0ID0gaW5qZWN0KFdPUktCRU5DSF9BVVhJTElBUllfUk9VVEVfT1VUTEVULCB7b3B0aW9uYWw6IHRydWV9KTtcblxuICBpZiAoIVdvcmtiZW5jaExheW91dHMuaXNWaWV3SWQob3V0bGV0KSkge1xuICAgIHRocm93IEVycm9yKGBbVmlld0Vycm9yXSBDYW5NYXRjaEZuIG11c3QgYmUgaW5zdGFsbGVkIG9uIGEgdmlldyBhdXhpbGlhcnkgcm91dGUuIFtvdXRsZXQ9JHtvdXRsZXR9XWApO1xuICB9XG5cbiAgY29uc3QgbGF5b3V0ID0gaW5qZWN0KMm1V29ya2JlbmNoUm91dGVyKS5nZXRDdXJyZW50TmF2aWdhdGlvbkNvbnRleHQoKS5sYXlvdXQ7XG4gIGNvbnN0IHZpZXcgPSBsYXlvdXQudmlldyh7dmlld0lkOiBvdXRsZXR9LCB7b3JFbHNlOiBudWxsfSk7XG4gIHJldHVybiAhIXZpZXc/Lm5hdmlnYXRpb247XG59O1xuIl19