From 3f7c3c3c1d7d3ba43f8db92e3b031b19500f88cc Mon Sep 17 00:00:00 2001 From: Marco D'Auria Date: Tue, 20 Jan 2026 21:36:17 +0100 Subject: [PATCH] feat(launchpad): align to new style and responsive design Align the launchpad to match iX/Element styling, improve responsiveness, animations and accessibility. NOTE: The `subtitleText` input no longer shows "Access all your apps" by default. To maintain the previous behavior, explicitly set the input. --- .../application-header/index.api.md | 12 +-- api-goldens/element-ng/translate/index.api.md | 4 +- .../e2e/element-examples/si-launchpad.spec.ts | 2 +- ...e-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- ...bar--si-navbar-launchpad--medium-size.yaml | 6 +- ...s-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- ...avbar--si-navbar-launchpad-categories.yaml | 8 +- ...d-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- .../si-navbar--si-navbar-launchpad.yaml | 6 +- ...e-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- ...lication-header--si-launchpad--mobile.yaml | 61 +++++++++-- ...e-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- ...on-header--si-launchpad--new-favorite.yaml | 59 ++++++++-- ...d-element-examples-chromium-dark-linux.png | 4 +- ...-element-examples-chromium-light-linux.png | 4 +- .../si-application-header--si-launchpad.yaml | 61 +++++++++-- .../launchpad/si-launchpad-app.component.html | 24 +++-- .../launchpad/si-launchpad-app.component.scss | 61 +++++++++-- .../launchpad/si-launchpad-app.component.ts | 15 ++- .../si-launchpad-factory.component.html | 48 +++++---- .../si-launchpad-factory.component.scss | 35 +++++- .../si-launchpad-factory.component.ts | 20 ++-- .../launchpad/si-launchpad.spec.ts | 2 +- .../si-application-header.component.ts | 3 - .../testing/si-launchpad-category.harness.ts | 2 +- .../testing/si-launchpad.harness.ts | 2 +- .../si-translatable-keys.interface.ts | 2 +- .../components/_application-header.scss | 5 +- .../si-application-header/si-launchpad.html | 102 ++++++++++++++++-- .../si-application-header/si-launchpad.ts | 84 +++++++++++++-- 35 files changed, 515 insertions(+), 157 deletions(-) diff --git a/api-goldens/element-ng/application-header/index.api.md b/api-goldens/element-ng/application-header/index.api.md index a316bc714..53167d835 100644 --- a/api-goldens/element-ng/application-header/index.api.md +++ b/api-goldens/element-ng/application-header/index.api.md @@ -135,15 +135,15 @@ export class SiHeaderSiemensLogoComponent extends SiHeaderLogoDirective { // @public (undocumented) export class SiLaunchpadFactoryComponent { readonly apps: _angular_core.InputSignal; - readonly closeText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; + readonly closeText: _angular_core.InputSignal; readonly enableFavorites: _angular_core.InputSignalWithTransform; - readonly favoriteAppsText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; + readonly favoriteAppsText: _angular_core.InputSignal; // (undocumented) readonly favoriteChange: _angular_core.OutputEmitterRef; - readonly showLessAppsText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; - readonly showMoreAppsText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; - readonly subtitleText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; - readonly titleText: _angular_core.InputSignal<_siemens_element_translate_ng_translate.TranslatableString>; + readonly showLessAppsText: _angular_core.InputSignal; + readonly showMoreAppsText: _angular_core.InputSignal; + readonly subtitleText: _angular_core.InputSignal; + readonly titleText: _angular_core.InputSignal; } // (No @packageDocumentation comment for this package) diff --git a/api-goldens/element-ng/translate/index.api.md b/api-goldens/element-ng/translate/index.api.md index d7e5013e3..308e5ff6e 100644 --- a/api-goldens/element-ng/translate/index.api.md +++ b/api-goldens/element-ng/translate/index.api.md @@ -296,6 +296,8 @@ export interface SiTranslatableKeys { // (undocumented) 'SI_LAUNCHPAD.DEFAULT_CATEGORY_TITLE'?: string; // (undocumented) + 'SI_LAUNCHPAD.EXTERNAL_LINK'?: string; + // (undocumented) 'SI_LAUNCHPAD.FAVORITE_APPS'?: string; // (undocumented) 'SI_LAUNCHPAD.SHOW_LESS'?: string; @@ -304,8 +306,6 @@ export interface SiTranslatableKeys { // (undocumented) 'SI_LAUNCHPAD.SUB_TITLE'?: string; // (undocumented) - 'SI_LAUNCHPAD.SUBTITLE'?: string; - // (undocumented) 'SI_LAUNCHPAD.TITLE'?: string; // (undocumented) 'SI_LIST_DETAILS.BACK'?: string; diff --git a/playwright/e2e/element-examples/si-launchpad.spec.ts b/playwright/e2e/element-examples/si-launchpad.spec.ts index 84307f0c0..0d1de305c 100644 --- a/playwright/e2e/element-examples/si-launchpad.spec.ts +++ b/playwright/e2e/element-examples/si-launchpad.spec.ts @@ -13,7 +13,7 @@ test.describe('launchpad', () => { await page.getByText('Show more').click(); await si.runVisualAndA11yTests(); - await page.getByRole('link', { name: 'Rocket' }).locator('.favorite-icon').click(); + await page.getByRole('link', { name: 'Fischbach' }).first().locator('.favorite-icon').click(); await si.runVisualAndA11yTests('new favorite'); }); diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-dark-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-dark-linux.png index aeb365589..5c398d8cf 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e7d11df6c94a349ab52ac0586ae893d2134b640f4c3981b9b2689c49713b766 -size 20700 +oid sha256:df75ee30ca86465f9230e09d2f2b3d89e222b336c66e6f6f31544e090bc92d90 +size 23750 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-light-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-light-linux.png index 22fab506e..182436c39 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c5fa0fb3fc93a53bd7d26fcde9d3359e105bae8cbd25404e4a9708db5305f39 -size 19956 +oid sha256:325b5f10332ed5c8f7ec50b8372a040851fbd24a80207eabcf985042e7975f17 +size 22825 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size.yaml b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size.yaml index ecb5d869b..bd66cd558 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size.yaml +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad--medium-size.yaml @@ -8,8 +8,9 @@ - /url: "#/viewer/viewer/item2" - button "Help" - button "Jane Smith" -- paragraph: Launchpad +- paragraph: Switch applications - paragraph: Access all your apps +- button "Close launchpad" - link "Assets": - /url: . - link "Water": @@ -19,5 +20,4 @@ - link "Statistics": - /url: . - link "Add more": - - /url: https://example.org -- button "Close launchpad" \ No newline at end of file + - /url: https://example.org \ No newline at end of file diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-dark-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-dark-linux.png index a45e8287a..06bcc374c 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48d086f14afc36b3b6f1c32889e70fd011134b5be8e750c7e5d882a8a879c6e3 -size 32411 +oid sha256:a667f8a3115ea5b3b57a55180ed71c7c18869d422ff452dbcbb9210a539a1ea6 +size 30158 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-light-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-light-linux.png index 0a468220b..f37d1342a 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:784861dfe1a5eaeeb325dc6cd6b1d757a6e05f1b05f0ed481a882c4b3a0eb33b -size 31441 +oid sha256:6f7d9e3d12591f67fb9795bbf5b6d794262dc28b29b887ec2cc989e02a04df42 +size 29251 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories.yaml b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories.yaml index 1a3ace920..169c35542 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories.yaml +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-categories.yaml @@ -10,9 +10,10 @@ - /url: "#/viewer/viewer/item2" - button "Help" - button "Jane Smith" -- paragraph: Launchpad +- paragraph: Switch applications - paragraph: Access all your apps -- text: Favorite apps +- button "Close launchpad" +- text: Favorites - link "Water": - /url: . - button "Show less" @@ -27,5 +28,4 @@ - link "Statistics": - /url: . - link "Add more": - - /url: https://example.org -- button "Close launchpad" \ No newline at end of file + - /url: https://example.org \ No newline at end of file diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-dark-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-dark-linux.png index be3b34914..0b178d578 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c0873818c060d6714c0e12ec1dd78c1d74e2b951ae3a15e3a49f3725c3e054f -size 23002 +oid sha256:9ffdff6331a200bcebd52e472156e87cbac463368149a0b09a0cd9461fdb9b81 +size 24436 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-light-linux.png b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-light-linux.png index 9d1440174..d6b61153b 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29c14f6e86a2276a335571454d2f1f48731c534553404a1b62bcf056bdfd047d -size 22175 +oid sha256:d9de655d4b558b605c297fef29a4da3092420a61e7e3c88ce15c04f37e9ae9de +size 23749 diff --git a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad.yaml b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad.yaml index ed09e6bf1..d83fd1510 100644 --- a/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad.yaml +++ b/playwright/snapshots/navbar-launchpad.spec.ts-snapshots/si-navbar--si-navbar-launchpad.yaml @@ -10,8 +10,9 @@ - /url: "#/viewer/viewer/item2" - button "Help" - button "Jane Smith" -- paragraph: Launchpad +- paragraph: Switch applications - paragraph: Access all your apps +- button "Close launchpad" - link "Assets": - /url: . - link "Water": @@ -21,5 +22,4 @@ - link "Statistics": - /url: . - link "Add more": - - /url: https://example.org -- button "Close launchpad" \ No newline at end of file + - /url: https://example.org \ No newline at end of file diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-dark-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-dark-linux.png index 1f5479b22..ce373217f 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56989f38b4e64a0e5180e347bb6b668a13c771cd4db3d1e19073e0f35efc0584 -size 21377 +oid sha256:b1ce840fa589cfdc282799dcc1ab9c2cea1c66cb575d7cc69054deaa7e28634b +size 31782 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-light-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-light-linux.png index 7a3f6aaf8..dc46ddf90 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27ac44fe8531b5f27f87004bc6fab04f3edce8ca0964b124be543676a6d22f25 -size 20654 +oid sha256:0ff965e05cda61e9821ea6bc86f73a9a48e25d787cde919f216ba166e9ddcfa8 +size 31052 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile.yaml b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile.yaml index c698b8391..29bdb8f94 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile.yaml +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--mobile.yaml @@ -2,18 +2,59 @@ - button "Launchpad" [expanded] - link "Siemens logo": - /url: "#/" -- paragraph: Launchpad -- paragraph: Access all your apps -- text: Favorite apps -- link "Fischbach": +- paragraph: Switch applications +- button "Close launchpad" +- text: Favorites +- link "Assets System name": - /url: . -- button "Show less" -- link "Assets": +- link "Fischbach System name": - /url: . -- link "Fischbach": +- link "Statistics System name": + - /url: "#/viewer/viewer/stats" +- link "Rocket System name": - /url: . -- link "Rocket": +- button "Show less" +- link "Assets System name": - /url: . -- link "Statistics": +- link "Fischbach System name": + - /url: . +- link "Statistics System name": - /url: "#/viewer/viewer/stats" -- button "Close launchpad" \ No newline at end of file +- link "Rocket System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 1 External application System name": + - /url: . + - text: "" +- link "App name 2 System name": + - /url: . +- link "App name 3 System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 4 System name": + - /url: . +- link "App name 5 System name": + - /url: . +- link "App name 6 This is a really long name": + - /url: . +- link "App name 7 System name": + - /url: . +- link "App name 8 System name": + - /url: . +- link "App name 9 System name": + - /url: . +- link /App name \d+ System name/: + - /url: . +- heading "Launchpad Configuration" [level=2] +- paragraph: Configure your launchpad settings and test different display modes. +- text: Enable Favorites Show favorite apps at the top +- switch "Enable Favorites Show favorite apps at the top" [checked] +- text: Enable Categories Group apps into organized categories +- switch "Enable Categories Group apps into organized categories" +- paragraph: + - strong: "Demo note:" + - text: Click the header icon to open the launchpad and test your settings \ No newline at end of file diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-dark-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-dark-linux.png index 4cfb77646..23422831e 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e981b58c90a6aad54bb519136823252946d17453b3cc47ebaa36e38ec347cc7 -size 25077 +oid sha256:d6ec5df7f377c30980b02c2e0eecec5405594c12b6f789cee3ca04965167856e +size 40542 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-light-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-light-linux.png index 89f345391..e43f7aee3 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52b21044da053c9ac62cb9298ed2b54477e8ea137a87ea521bb08e1367d85a6b -size 24480 +oid sha256:829d8798c44209aec61df87d0498886f0bc44be46a8f255576165e1e64ce2702 +size 39571 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite.yaml b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite.yaml index d89abcb8d..b6f567695 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite.yaml +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad--new-favorite.yaml @@ -2,20 +2,57 @@ - button "Launchpad" [expanded] - link "Siemens logo": - /url: "#/" -- paragraph: Launchpad -- paragraph: Access all your apps -- text: Favorite apps -- link "Fischbach": +- paragraph: Switch applications +- button "Close launchpad" +- text: Favorites +- link "Assets System name": - /url: . -- link "Rocket": +- link "Statistics System name": + - /url: "#/viewer/viewer/stats" +- link "Rocket System name": - /url: . - button "Show less" -- link "Assets": - - /url: . -- link "Fischbach": +- link "Assets System name": - /url: . -- link "Rocket": +- link "Fischbach System name": - /url: . -- link "Statistics": +- link "Statistics System name": - /url: "#/viewer/viewer/stats" -- button "Close launchpad" \ No newline at end of file +- link "Rocket System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 1 External application System name": + - /url: . + - text: "" +- link "App name 2 System name": + - /url: . +- link "App name 3 System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 4 System name": + - /url: . +- link "App name 5 System name": + - /url: . +- link "App name 6 This is a really long name": + - /url: . +- link "App name 7 System name": + - /url: . +- link "App name 8 System name": + - /url: . +- link "App name 9 System name": + - /url: . +- link /App name \d+ System name/: + - /url: . +- heading "Launchpad Configuration" [level=2] +- paragraph: Configure your launchpad settings and test different display modes. +- text: Enable Favorites Show favorite apps at the top +- switch "Enable Favorites Show favorite apps at the top" [checked] +- text: Enable Categories Group apps into organized categories +- switch "Enable Categories Group apps into organized categories" +- paragraph: + - strong: "Demo note:" + - text: Click the header icon to open the launchpad and test your settings \ No newline at end of file diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-dark-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-dark-linux.png index 99f53002e..8a7e4ab99 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-dark-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-dark-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:038f8a475cfd2a28b25e878bf5da3016e373752be85a750b698667e09fea70c9 -size 22076 +oid sha256:9417958df59a32ead47b7e22096acd94083706a401718d69e347f733e46db639 +size 42121 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-light-linux.png b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-light-linux.png index f3f430dba..481cb1253 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-light-linux.png +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad-element-examples-chromium-light-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:930e7ebe86f3ea01f8c586e03423b94700634434796888e1dd2a72f254e5b603 -size 21517 +oid sha256:7da6e3151c57ca5f9cc69583bc562b90322741975ebe7a266285c151649f621c +size 41239 diff --git a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad.yaml b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad.yaml index c698b8391..29bdb8f94 100644 --- a/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad.yaml +++ b/playwright/snapshots/si-launchpad.spec.ts-snapshots/si-application-header--si-launchpad.yaml @@ -2,18 +2,59 @@ - button "Launchpad" [expanded] - link "Siemens logo": - /url: "#/" -- paragraph: Launchpad -- paragraph: Access all your apps -- text: Favorite apps -- link "Fischbach": +- paragraph: Switch applications +- button "Close launchpad" +- text: Favorites +- link "Assets System name": - /url: . -- button "Show less" -- link "Assets": +- link "Fischbach System name": - /url: . -- link "Fischbach": +- link "Statistics System name": + - /url: "#/viewer/viewer/stats" +- link "Rocket System name": - /url: . -- link "Rocket": +- button "Show less" +- link "Assets System name": - /url: . -- link "Statistics": +- link "Fischbach System name": + - /url: . +- link "Statistics System name": - /url: "#/viewer/viewer/stats" -- button "Close launchpad" \ No newline at end of file +- link "Rocket System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 1 External application System name": + - /url: . + - text: "" +- link "App name 2 System name": + - /url: . +- link "App name 3 System name": + - /url: . +- link "This is a really long name External application System name": + - /url: . + - text: "" +- link "App name 4 System name": + - /url: . +- link "App name 5 System name": + - /url: . +- link "App name 6 This is a really long name": + - /url: . +- link "App name 7 System name": + - /url: . +- link "App name 8 System name": + - /url: . +- link "App name 9 System name": + - /url: . +- link /App name \d+ System name/: + - /url: . +- heading "Launchpad Configuration" [level=2] +- paragraph: Configure your launchpad settings and test different display modes. +- text: Enable Favorites Show favorite apps at the top +- switch "Enable Favorites Show favorite apps at the top" [checked] +- text: Enable Categories Group apps into organized categories +- switch "Enable Categories Group apps into organized categories" +- paragraph: + - strong: "Demo note:" + - text: Click the header icon to open the launchpad and test your settings \ No newline at end of file diff --git a/projects/element-ng/application-header/launchpad/si-launchpad-app.component.html b/projects/element-ng/application-header/launchpad/si-launchpad-app.component.html index 54ee6766b..9c63f5713 100644 --- a/projects/element-ng/application-header/launchpad/si-launchpad-app.component.html +++ b/projects/element-ng/application-header/launchpad/si-launchpad-app.component.html @@ -3,14 +3,22 @@ } @else if (iconClass()) { } -
- - @if (external()) { - - } -
-
- +
+
+ + + + @if (external()) { + + } +
+
+ +
@if (enableFavoriteToggle()) { (); readonly iconClass = input(); + /** + * Aria-label for the external link icon. + * + * @defaultValue + * ``` + * t(() => $localize`:@@SI_LAUNCHPAD.EXTERNAL_LINK:External application`) + * ``` + */ + readonly externalLinkText = input( + t(() => $localize`:@@SI_LAUNCHPAD.EXTERNAL_LINK:External application`) + ); protected readonly icons = addIcons({ elementExport, elementFavorites, elementFavoritesFilled }); diff --git a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.html b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.html index f2484cb22..3241684c1 100644 --- a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.html +++ b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.html @@ -1,27 +1,43 @@
@if (titleText()) { -

{{ titleText() | translate }}

+
+ +

{{ titleText() | translate }}

+ @if (subtitleText()) { +

{{ subtitleText() | translate }}

+ } +
+ +
} - @if (subtitleText()) { -

{{ subtitleText() | translate }}

- } -
+
@for (category of categories(); track category; let first = $first) { @if (!enableFavorites() || !hasFavorites() || first || showAllApps) { -
+
@if (category.name) { - +
{{ category.name | translate }} - +
} -
+
@for (app of category.apps; track app) { @switch (app.type) { @case ('router-link') { @@ -76,22 +92,14 @@ @if (enableFavorites() && first && hasFavorites()) { } }
-
diff --git a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.scss b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.scss index 300485b84..bccfe1c7e 100644 --- a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.scss +++ b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.scss @@ -1,12 +1,12 @@ @use 'sass:map'; - @use '@siemens/element-theme/src/styles/variables'; +@use '@siemens/element-theme/src/styles/all-variables'; .app-switcher { position: fixed; inset-block-start: calc( - variables.$si-application-header-height + variables.$si-titlebar-spacing + - variables.$si-system-banner-spacing + variables.$si-application-header-height + 1px /* header border compensation */ + + variables.$si-titlebar-spacing + variables.$si-system-banner-spacing ); inset-inline: 0; min-block-size: 200px; @@ -14,13 +14,40 @@ 100vh - variables.$si-application-header-height - variables.$si-titlebar-spacing - variables.$si-system-banner-spacing ); + padding: map.get(variables.$spacers, 6); display: flex; flex-direction: column; z-index: variables.$zindex-launchpad; background-color: variables.$element-base-1; - box-shadow: variables.$element-elevation-inset-1; + + @include all-variables.media-breakpoint-up(lg) { + padding-block: map.get(variables.$spacers, 6); + padding-inline: map.get(variables.$spacers, 8); + } +} + +.apps-header { + display: flex; + align-items: center; + justify-content: space-between; } .apps-scroll { overflow-y: auto; + // Prevent scrollbar from overlapping items on mobile + padding-inline-end: map.get(variables.$spacers, 6); + margin-inline-end: map.get(variables.$spacers, 6) * -1; +} + +.btn-show-all { + margin-block-start: map.get(variables.$spacers, 6); + margin-block-end: map.get(variables.$spacers, 4); + + &.show { + margin-block-end: map.get(variables.$spacers, 8); + } + + &.show:has(+ div .launchpad-category-title) { + margin-block-end: 0; + } } diff --git a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.ts b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.ts index 9175e6180..37df08d58 100644 --- a/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.ts +++ b/projects/element-ng/application-header/launchpad/si-launchpad-factory.component.ts @@ -15,7 +15,7 @@ import { import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router'; import { addIcons, elementCancel, elementDown2, SiIconComponent } from '@siemens/element-ng/icon'; import { SiLinkModule } from '@siemens/element-ng/link'; -import { SiTranslatePipe, t } from '@siemens/element-translate-ng/translate'; +import { SiTranslatePipe, t, TranslatableString } from '@siemens/element-translate-ng/translate'; import { SiApplicationHeaderComponent } from '../si-application-header.component'; import { SiLaunchpadAppComponent } from './si-launchpad-app.component'; @@ -57,20 +57,16 @@ export class SiLaunchpadFactoryComponent { * * @defaultValue * ``` - * t(() => $localize`:@@SI_LAUNCHPAD.TITLE:Launchpad`) + * t(() => $localize`:@@SI_LAUNCHPAD.TITLE:Switch applications`) * ``` */ - readonly titleText = input(t(() => $localize`:@@SI_LAUNCHPAD.TITLE:Launchpad`)); + readonly titleText = input(t(() => $localize`:@@SI_LAUNCHPAD.TITLE:Switch applications`)); /** * Subtitle of the launchpad. - * - * @defaultValue - * ``` - * t(() => $localize`:@@SI_LAUNCHPAD.SUBTITLE:Access all your apps`) - * ``` + * When not provided, no subtitle is displayed. */ - readonly subtitleText = input(t(() => $localize`:@@SI_LAUNCHPAD.SUBTITLE:Access all your apps`)); + readonly subtitleText = input(); /** All app items shown in the launchpad. */ readonly apps = input.required(); @@ -87,12 +83,10 @@ export class SiLaunchpadFactoryComponent { * * @defaultValue * ``` - * t(() => $localize`:@@SI_LAUNCHPAD.FAVORITE_APPS:Favorite apps`) + * t(() => $localize`:@@SI_LAUNCHPAD.FAVORITE_APPS:Favorites`) * ``` */ - readonly favoriteAppsText = input( - t(() => $localize`:@@SI_LAUNCHPAD.FAVORITE_APPS:Favorite apps`) - ); + readonly favoriteAppsText = input(t(() => $localize`:@@SI_LAUNCHPAD.FAVORITE_APPS:Favorites`)); /** * Title of the show more apps button. diff --git a/projects/element-ng/application-header/launchpad/si-launchpad.spec.ts b/projects/element-ng/application-header/launchpad/si-launchpad.spec.ts index 49d7492f7..538bb808b 100644 --- a/projects/element-ng/application-header/launchpad/si-launchpad.spec.ts +++ b/projects/element-ng/application-header/launchpad/si-launchpad.spec.ts @@ -109,7 +109,7 @@ describe('SiLaunchpad', () => { await harness.toggleMore(); const categories = await harness.getCategories(); expect(categories).toHaveSize(2); - expect(await categories[0].getName()).toBe('Favorite apps'); + expect(await categories[0].getName()).toBe('Favorites'); expect(await categories[1].getName()).toBe(null); expect(await harness.getApp('A-1').then(app => app.isFavorite())).toBeTrue(); expect(await harness.getFavoriteCategory().then(category => category.getApps())).toHaveSize( diff --git a/projects/element-ng/application-header/si-application-header.component.ts b/projects/element-ng/application-header/si-application-header.component.ts index 318ff2b44..818ae9468 100644 --- a/projects/element-ng/application-header/si-application-header.component.ts +++ b/projects/element-ng/application-header/si-application-header.component.ts @@ -148,9 +148,6 @@ export class SiApplicationHeaderComponent implements HeaderWithDropdowns, OnDest this.dropdownOpened(); this.closeMobileMenus.next(); this.launchpadOpen.set(true); - this.inlineDropdown - .pipe(skip(1), takeUntil(this.closeMobileMenus)) - .subscribe(() => this.closeMobileMenus.next()); } } diff --git a/projects/element-ng/application-header/testing/si-launchpad-category.harness.ts b/projects/element-ng/application-header/testing/si-launchpad-category.harness.ts index c29f75ccc..e23fe36b1 100644 --- a/projects/element-ng/application-header/testing/si-launchpad-category.harness.ts +++ b/projects/element-ng/application-header/testing/si-launchpad-category.harness.ts @@ -15,7 +15,7 @@ export class SiLaunchpadCategoryHarness extends ComponentHarness { ); } - private name = this.locatorForOptional('.si-h4'); + private name = this.locatorForOptional('.launchpad-category-title'); async getName(): Promise { return this.name().then(name => name?.text() ?? null); diff --git a/projects/element-ng/application-header/testing/si-launchpad.harness.ts b/projects/element-ng/application-header/testing/si-launchpad.harness.ts index 0eaebf7bb..7b5da7e83 100644 --- a/projects/element-ng/application-header/testing/si-launchpad.harness.ts +++ b/projects/element-ng/application-header/testing/si-launchpad.harness.ts @@ -17,7 +17,7 @@ export class SiLaunchpadHarness extends ComponentHarness { } async getFavoriteCategory(): Promise { - return this.getCategory('Favorite apps'); + return this.getCategory('Favorites'); } async getCategories(): Promise { diff --git a/projects/element-ng/translate/si-translatable-keys.interface.ts b/projects/element-ng/translate/si-translatable-keys.interface.ts index f5ce83212..65788a261 100644 --- a/projects/element-ng/translate/si-translatable-keys.interface.ts +++ b/projects/element-ng/translate/si-translatable-keys.interface.ts @@ -146,10 +146,10 @@ export interface SiTranslatableKeys { 'SI_LANGUAGE_SWITCHER.LABEL'?: string; 'SI_LAUNCHPAD.CLOSE'?: string; 'SI_LAUNCHPAD.DEFAULT_CATEGORY_TITLE'?: string; + 'SI_LAUNCHPAD.EXTERNAL_LINK'?: string; 'SI_LAUNCHPAD.FAVORITE_APPS'?: string; 'SI_LAUNCHPAD.SHOW_LESS'?: string; 'SI_LAUNCHPAD.SHOW_MORE'?: string; - 'SI_LAUNCHPAD.SUBTITLE'?: string; 'SI_LAUNCHPAD.SUB_TITLE'?: string; 'SI_LAUNCHPAD.TITLE'?: string; 'SI_LIST_DETAILS.BACK'?: string; diff --git a/projects/element-theme/src/styles/components/_application-header.scss b/projects/element-theme/src/styles/components/_application-header.scss index 0ddf7e5a1..23e5878ba 100644 --- a/projects/element-theme/src/styles/components/_application-header.scss +++ b/projects/element-theme/src/styles/components/_application-header.scss @@ -31,8 +31,9 @@ align-items: stretch; border-block-end: 1px solid semantic-tokens.$element-ui-4; - // hide border when mobile styles are applied and either the dropdown-menu or header-toggle is shown - &:has(.dropdown-menu.show, .header-toggle.show) { + // hide border when mobile styles are applied and either the dropdown-menu is shown or navigation is expanded + &:has(.dropdown-menu.show), + &.show-navigation { border-block-end: none; } diff --git a/src/app/examples/si-application-header/si-launchpad.html b/src/app/examples/si-application-header/si-launchpad.html index 12917de0b..d8d59ba64 100644 --- a/src/app/examples/si-application-header/si-launchpad.html +++ b/src/app/examples/si-application-header/si-launchpad.html @@ -1,9 +1,93 @@ - - - - - - - - - +
+ + + + + + + + + + +
+
+
+
+
+

Launchpad Configuration

+

+ Configure your launchpad settings and test different display modes. +

+ +
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+

+ + Demo note: Click the header icon to open the launchpad and test + your settings + +

+
+
+
+
+
+
+
diff --git a/src/app/examples/si-application-header/si-launchpad.ts b/src/app/examples/si-application-header/si-launchpad.ts index b0e23bd59..3f38f9faf 100644 --- a/src/app/examples/si-application-header/si-launchpad.ts +++ b/src/app/examples/si-application-header/si-launchpad.ts @@ -2,15 +2,18 @@ * Copyright (c) Siemens 2016 - 2025 * SPDX-License-Identifier: MIT */ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { RouterLink } from '@angular/router'; import { App, + AppCategory, SiApplicationHeaderComponent, SiHeaderBrandDirective, SiHeaderLogoDirective, SiLaunchpadFactoryComponent } from '@siemens/element-ng/application-header'; +import { SiFormItemComponent } from '@siemens/element-ng/form'; @Component({ selector: 'app-sample', @@ -19,39 +22,100 @@ import { RouterLink, SiHeaderBrandDirective, SiLaunchpadFactoryComponent, - SiHeaderLogoDirective + SiHeaderLogoDirective, + FormsModule, + SiFormItemComponent ], templateUrl: './si-launchpad.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class SampleComponent { - apps: App[] = [ + readonly enableFavorites = signal(true); + readonly enableCategories = signal(false); + + private readonly businessApps = signal([ { name: 'Assets', + systemName: 'System name', iconUrl: './assets/app-icons/assets.svg', + favorite: true, href: '.' }, { name: 'Fischbach', + systemName: 'System name', iconUrl: './assets/app-icons/fischbach.svg', favorite: true, + active: true, href: '.' }, + { + name: 'Statistics', + systemName: 'System name', + iconUrl: './assets/app-icons/statistics.svg', + favorite: true, + type: 'router-link', + routerLink: 'stats' + } + ]); + private readonly toolApps = signal([ { name: 'Rocket', + systemName: 'System name', iconUrl: './assets/app-icons/rocket.svg', + favorite: true, href: '.' }, { - name: 'Statistics', - iconUrl: './assets/app-icons/statistics.svg', - type: 'router-link', - routerLink: 'stats' + name: 'This is a really long name', + systemName: 'System name', + iconUrl: './assets/app-icons/assets.svg', + external: true, + href: '.' + } + ]); + private appCounter = 0; + private readonly otherApps = signal( + Array.from({ length: 11 }, (_, i) => ({ + name: i === 3 ? 'This is a really long name' : `App name ${++this.appCounter}`, + systemName: i === 6 ? 'This is a really long name' : 'System name', + iconUrl: './assets/app-icons/assets.svg', + external: [0, 3].includes(i), + href: '.' + })) + ); + + readonly apps = computed((): App[] | AppCategory[] => { + if (!this.enableCategories()) { + return [...this.businessApps(), ...this.toolApps(), ...this.otherApps()]; } - ]; + + return [ + { name: 'Business Applications', apps: this.businessApps() }, + { name: 'System Tools', apps: this.toolApps() }, + { name: 'Other Applications', apps: this.otherApps() } + ].filter(category => category.apps.length > 0); + }); updateFavorite({ app, favorite }: { app: App; favorite: boolean }): void { - app.favorite = favorite; - this.apps = [...this.apps]; // Trigger change detection + for (const category of [this.businessApps, this.toolApps, this.otherApps]) { + const match = category().find(a => a === app); + if (match) { + category.update(apps => { + return apps.map(a => (a === app ? { ...a, favorite } : a)); + }); + break; + } + } + } + + toggleFavorites(event: Event): void { + const target = event.target as HTMLInputElement; + this.enableFavorites.set(target.checked); + } + + toggleCategories(event: Event): void { + const target = event.target as HTMLInputElement; + this.enableCategories.set(target.checked); } }