Skip to content

Commit 47e50cf

Browse files
prasepicspike-rabbit
authored andcommitted
feat(launchpad): support routerLink for launchpad apps
1 parent fb75106 commit 47e50cf

File tree

7 files changed

+90
-36
lines changed

7 files changed

+90
-36
lines changed

playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
- link "Rocket":
1616
- /url: .
1717
- link "Statistics":
18-
- /url: .
18+
- /url: "#/viewer/viewer/stats"
1919
- button "Close launchpad"

playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- text: Favorite apps
88
- link "Fischbach":
99
- /url: .
10+
- link "Rocket":
11+
- /url: .
1012
- button "Show less"
1113
- link "Assets":
1214
- /url: .
@@ -15,5 +17,5 @@
1517
- link "Rocket":
1618
- /url: .
1719
- link "Statistics":
18-
- /url: .
20+
- /url: "#/viewer/viewer/stats"
1921
- button "Close launchpad"

playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
- link "Rocket":
1616
- /url: .
1717
- link "Statistics":
18-
- /url: .
18+
- /url: "#/viewer/viewer/stats"
1919
- button "Close launchpad"

projects/element-ng/application-header/launchpad/si-launchpad-factory.component.html

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<!-- eslint-disable @angular-eslint/template/no-any -->
2+
<!-- temporary until old primary-navbar is removed -->
13
<div
24
class="app-switcher pt-8 g-5 g-sm-9 container-fluid"
35
cdkTrapFocus
@@ -21,24 +23,51 @@
2123
}
2224
<div class="mt-4 d-flex flex-wrap gap-4">
2325
@for (app of category.apps; track app) {
24-
<!-- eslint-disable @angular-eslint/template/no-any -->
25-
<!-- temporary until old primary-navbar is removed -->
26-
<a
27-
si-launchpad-app
28-
[enableFavoriteToggle]="enableFavorites() && !$any(app)._noFavorite"
29-
[favorite]="!!app.favorite"
30-
[href]="app.href"
31-
[target]="app.target ?? ''"
32-
[active]="app.active"
33-
[external]="app.external"
34-
[iconUrl]="app.iconUrl"
35-
[iconClass]="app.iconClass"
36-
(favoriteChange)="toggleFavorite(app, $event)"
37-
>
38-
<span app-name>{{ app.name | translate }}</span>
39-
<span app-systemName>{{ app.systemName | translate }}</span>
40-
</a>
41-
<!-- eslint-enable @angular-eslint/template/no-any -->
26+
@switch (app.type) {
27+
@case ('router-link') {
28+
<a
29+
si-launchpad-app
30+
routerLinkActive="active"
31+
[routerLinkActiveOptions]="app.activeMatchOptions ?? { exact: false }"
32+
[enableFavoriteToggle]="enableFavorites() && !$any(app)._noFavorite"
33+
[external]="app.external"
34+
[iconUrl]="app.iconUrl"
35+
[iconClass]="app.iconClass"
36+
[favorite]="!!app.favorite"
37+
[routerLink]="app.routerLink"
38+
[queryParams]="app.extras?.queryParams"
39+
[queryParamsHandling]="app.extras?.queryParamsHandling"
40+
[fragment]="app.extras?.fragment"
41+
[state]="app.extras?.state"
42+
[relativeTo]="app.extras?.relativeTo ?? this.activatedRoute"
43+
[preserveFragment]="app.extras?.preserveFragment"
44+
[skipLocationChange]="app.extras?.skipLocationChange"
45+
[replaceUrl]="app.extras?.replaceUrl"
46+
(favoriteChange)="toggleFavorite(app, $event)"
47+
>
48+
<span app-name>{{ app.name | translate }}</span>
49+
<span app-systemName>{{ app.systemName | translate }}</span>
50+
</a>
51+
}
52+
@default {
53+
<!--fallback for existing apps that do not have a type defined -->
54+
<a
55+
si-launchpad-app
56+
[enableFavoriteToggle]="enableFavorites() && !$any(app)._noFavorite"
57+
[favorite]="!!app.favorite"
58+
[href]="app.href"
59+
[target]="app.target ?? ''"
60+
[active]="app.active"
61+
[external]="app.external"
62+
[iconUrl]="app.iconUrl"
63+
[iconClass]="app.iconClass"
64+
(favoriteChange)="toggleFavorite(app, $event)"
65+
>
66+
<span app-name>{{ app.name | translate }}</span>
67+
<span app-systemName>{{ app.systemName | translate }}</span>
68+
</a>
69+
}
70+
}
4271
}
4372
</div>
4473
</div>

projects/element-ng/application-header/launchpad/si-launchpad-factory.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
input,
1414
output
1515
} from '@angular/core';
16+
import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router';
1617
import {
1718
addIcons,
1819
elementCancel,
@@ -39,7 +40,9 @@ export interface FavoriteChangeEvent {
3940
SiLinkModule,
4041
SiTranslatePipe,
4142
SiLaunchpadAppComponent,
42-
SiIconNextComponent
43+
SiIconNextComponent,
44+
RouterLinkActive,
45+
RouterLink
4346
],
4447
templateUrl: './si-launchpad-factory.component.html',
4548
styleUrl: './si-launchpad-factory.component.scss',
@@ -144,6 +147,7 @@ export class SiLaunchpadFactoryComponent {
144147
);
145148
protected readonly hasFavorites = computed(() => this.favorites().length > 0);
146149
protected readonly icons = addIcons({ elementDown2, elementCancel });
150+
protected readonly activatedRoute = inject(ActivatedRoute, { optional: true });
147151
private header = inject(SiApplicationHeaderComponent);
148152

149153
protected closeLaunchpad(): void {

projects/element-ng/application-header/launchpad/si-launchpad.model.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,52 @@
22
* Copyright (c) Siemens 2016 - 2025
33
* SPDX-License-Identifier: MIT
44
*/
5+
import { IsActiveMatchOptions, NavigationExtras } from '@angular/router';
56
import { TranslatableString } from '@siemens/element-translate-ng/translate';
67

78
/** Represents an app to be shown in the launchpad. */
8-
export interface App {
9-
/** Name of the app */
10-
name: TranslatableString;
11-
/** Name of the related system. */
12-
systemName?: TranslatableString;
9+
export interface AppLink extends AppBase {
10+
/** The type of the app. can be either 'link' or 'router-link' */
11+
type?: 'link';
1312
/** URL destination of the app. */
1413
href: string;
1514
/** Value for the anchor target attribute. */
1615
target?: string;
17-
/** Icon of the app. */
18-
iconUrl?: string;
19-
/** CSS class to apply, which should render the icon. Typically, "element-*". */
20-
iconClass?: string;
21-
/** Whether the app is marked as favorite. */
22-
favorite?: boolean;
23-
/** Whether the app should be marked as external. */
24-
external?: boolean;
2516
/** Whether the app is the currently running app. */
2617
active?: boolean;
2718
}
2819

20+
export interface AppRouterLink extends AppBase {
21+
type: 'router-link';
22+
/** Link for the angular router. Accepts the same values as {@link https://angular.dev/api/router/RouterLink}. */
23+
routerLink: string | any[];
24+
/** Navigation extras that are passed to the {@link https://angular.dev/api/router/NavigationExtras}. */
25+
extras?: NavigationExtras;
26+
/** Active match options for routerLinkActive {@link https://angular.dev/api/router/IsActiveMatchOptions}.*/
27+
activeMatchOptions?: { exact: boolean } | IsActiveMatchOptions;
28+
}
29+
2930
/** Represents a categories in the launchpad. */
3031
export interface AppCategory {
3132
/** The name of the app category. */
3233
name?: TranslatableString;
3334
/** The apps to show under this category. */
3435
apps: App[];
3536
}
37+
38+
export interface AppBase {
39+
/** Name of the app */
40+
name: TranslatableString;
41+
/** Name of the related system. */
42+
systemName?: TranslatableString;
43+
/** Icon of the app. */
44+
iconUrl?: string;
45+
/** CSS class to apply, which should render the icon. Typically, "element-*". */
46+
iconClass?: string;
47+
/** Whether the app is marked as favorite. */
48+
favorite?: boolean;
49+
/** Whether the app should be marked as external. */
50+
external?: boolean;
51+
}
52+
53+
export type App = AppLink | AppRouterLink;

src/app/examples/si-application-header/si-launchpad.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ export class SampleComponent {
4545
{
4646
name: 'Statistics',
4747
iconUrl: './assets/app-icons/statistics.svg',
48-
href: '.'
48+
type: 'router-link',
49+
routerLink: 'stats'
4950
}
5051
];
5152

0 commit comments

Comments
 (0)