@spike-rabbit/dashboards-ng 49.0.0 → 49.13.0

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,3 +1,4 @@
1
1
  {
2
- "module": "../fesm2022/spike-rabbit-dashboards-ng-module-federation.mjs"
2
+ "module": "../fesm2022/spike-rabbit-dashboards-ng-module-federation.mjs",
3
+ "typings": "../types/spike-rabbit-dashboards-ng-module-federation.d.ts"
3
4
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "module": "../../fesm2022/spike-rabbit-dashboards-ng-native-federation-mf-bridge.mjs",
3
+ "typings": "../../types/spike-rabbit-dashboards-ng-native-federation-mf-bridge.d.ts"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "module": "../fesm2022/spike-rabbit-dashboards-ng-native-federation.mjs",
3
+ "typings": "../types/spike-rabbit-dashboards-ng-native-federation.d.ts"
4
+ }
package/package.json CHANGED
@@ -1,51 +1,75 @@
1
1
  {
2
2
  "name": "@spike-rabbit/dashboards-ng",
3
3
  "description": "Element Dashboards library.",
4
- "version": "49.0.0",
4
+ "version": "49.13.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+ssh://git@github.com/siemens/element.git"
8
+ "url": "git+https://github.com/spike-rabbit/element.git"
9
9
  },
10
10
  "author": {
11
11
  "name": "Siemens AG",
12
12
  "email": "info@siemens.com"
13
13
  },
14
14
  "publishConfig": {
15
- "access": "public"
15
+ "access": "public",
16
+ "directory": "../../dist/@spike-rabbit/dashboards-ng"
16
17
  },
17
- "homepage": "https://github.com/siemens/element",
18
- "bugs": "https://github.com/siemens/element/issues/new",
18
+ "homepage": "https://github.com/spike-rabbit/element",
19
+ "bugs": "https://github.com/spike-rabbit/element/issues/new",
19
20
  "type": "module",
20
21
  "peerDependencies": {
21
- "@angular/common": "20",
22
- "@angular/core": "20",
23
- "@ngx-translate/core": "15 - 16",
24
- "@spike-rabbit/element-ng": "49.0.0",
25
- "@spike-rabbit/element-theme": "49.0.0",
26
- "gridstack": "^11.1.0"
22
+ "@angular-architects/module-federation": "^21.0.0",
23
+ "@angular-architects/native-federation": "^22.0.0",
24
+ "@angular/common": "22",
25
+ "@angular/core": "22",
26
+ "@module-federation/enhanced": "^2.0.0",
27
+ "@module-federation/runtime": "^2.0.0",
28
+ "gridstack": "^12.3.3",
29
+ "@spike-rabbit/element-ng": "49.13.0",
30
+ "@spike-rabbit/element-theme": "50.0.0"
31
+ },
32
+ "peerDependenciesMeta": {
33
+ "@angular-architects/module-federation": {
34
+ "optional": true
35
+ },
36
+ "@angular-architects/native-federation": {
37
+ "optional": true
38
+ },
39
+ "@module-federation/enhanced": {
40
+ "optional": true
41
+ }
27
42
  },
28
43
  "module": "fesm2022/spike-rabbit-dashboards-ng.mjs",
29
- "typings": "index.d.ts",
44
+ "typings": "types/spike-rabbit-dashboards-ng.d.ts",
30
45
  "exports": {
31
46
  "./package.json": {
32
47
  "default": "./package.json"
33
48
  },
34
49
  ".": {
35
- "types": "./index.d.ts",
50
+ "types": "./types/spike-rabbit-dashboards-ng.d.ts",
36
51
  "default": "./fesm2022/spike-rabbit-dashboards-ng.mjs"
37
52
  },
38
53
  "./module-federation": {
39
- "types": "./module-federation/index.d.ts",
54
+ "types": "./types/spike-rabbit-dashboards-ng-module-federation.d.ts",
40
55
  "default": "./fesm2022/spike-rabbit-dashboards-ng-module-federation.mjs"
41
56
  },
57
+ "./native-federation": {
58
+ "types": "./types/spike-rabbit-dashboards-ng-native-federation.d.ts",
59
+ "default": "./fesm2022/spike-rabbit-dashboards-ng-native-federation.mjs"
60
+ },
61
+ "./native-federation/mf-bridge": {
62
+ "types": "./types/spike-rabbit-dashboards-ng-native-federation-mf-bridge.d.ts",
63
+ "default": "./fesm2022/spike-rabbit-dashboards-ng-native-federation-mf-bridge.mjs"
64
+ },
42
65
  "./translate": {
43
- "types": "./translate/index.d.ts",
66
+ "types": "./types/spike-rabbit-dashboards-ng-translate.d.ts",
44
67
  "default": "./fesm2022/spike-rabbit-dashboards-ng-translate.mjs"
45
68
  }
46
69
  },
47
70
  "sideEffects": false,
48
71
  "dependencies": {
49
72
  "tslib": "^2.3.0"
50
- }
73
+ },
74
+ "readme": "# Siemens Dashboards\n\n## Usage\n\nCheck out our [dashboard demo project](https://github.com/siemens/element/blob/main/projects/dashboards-demo/) for examples on how\nto integrate the Siemens Dashboards library in your project.\n\n### Install dependencies\n\nTo use the Siemens Dashboards in your project, add it to your dependencies\nby executing:\n\n```sh\nnpm install --save @spike-rabbit/dashboards-ng gridstack\n```\n\n### Add libraries to your project\n\nThe library supports standalone components and modules.\n\n### Standalone\n\nImport and include the `SiFlexibleDashboardComponent` in the component that shall provide the dashboard.\nOptionally, configure the grid and the widget storage in the global app configuration providers.\n\n```ts\nproviders: [\n provideRouter(routes, withHashLocation()),\n { provide: SI_WIDGET_STORE, useClass: AppWidgetStorage },\n { provide: SI_DASHBOARD_CONFIGURATION, useValue: config },\n provideTranslateService({\n loader: {\n provide: TranslateLoader,\n useFactory: createTranslateLoader,\n deps: [HttpBackend]\n },\n missingTranslationHandler: provideMissingTranslationHandlerForElement()\n }),\n provideNgxTranslateForElement(),\n provideHttpClient(withInterceptorsFromDi())\n];\n```\n\n### Modules\n\nImport the library to your Angular `AppModule`, mostly residing in your\n`src/app/app.modules.ts` file as follows:\n\n```ts\n// [...]\n// Import this library\nimport { SiDashboardsNgModule } from '@spike-rabbit/dashboards-ng';\n// Import needed peer dependency\nimport { SiTranslateModule } from '@spike-rabbit/element-translate-ng/translate';\n\n@NgModule({\n declarations: [AppComponent],\n imports: [\n BrowserModule,\n\n // Import this library\n SiDashboardsNgModule\n ],\n providers: [\n provideNgxTranslateForElement()\n ]\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n```\n\nAdd `gridstack` CSS files to your application by editing\nthe `angular.json` file.\n\n```json\n\"styles\": [\n \"src/styles.scss\",\n \"node_modules/gridstack/dist/gridstack.css\"\n],\n\"allowedCommonJsDependencies\": [\n \"gridstack\"\n],\n```\n\n### Add the dashboard to your application\n\nTo add the dashboard to your application, add the `si-flexible-dashboard` component\nto your template. Configure the widget catalog by setting the _widgetCatalog_ input\nproperty.\n\nThe component expects to be added to a flex container with a defined height, as it grows in height\nto the available space, following the [Fixed-height](https://element.siemens.io/fundamentals/layouts/content/#fixed-height)\nconcept.\n\nFor testing, set `style=\"display: flex; block-size: 800px;\"` to the parent element. Please\nnote that the `si-flexible-dashboard` comes with the correct page margins.\n\n```html\n<div style=\"display: flex; block-size: 800px;\">\n <si-flexible-dashboard heading=\"Sample Dashboard\" [widgetCatalog]=\"[]\">\n <div filters-slot><button class=\"btn btn-secondary\">My Menu</button></div>\n </si-flexible-dashboard>\n</div>\n```\n\nThe correct approach is to use the full page height as explained at\n[Fixed-height](https://element.siemens.io/fundamentals/layouts/content/#fixed-height).\n\n```html\n<div class=\"has-navbar-fixed-top si-layout-fixed-height h-100\">\n <si-application-header> ... </si-application-header>\n <div class=\"si-layout-fixed-height\">\n <si-flexible-dashboard heading=\"Sample Dashboard\" [widgetCatalog]=\"[]\">\n <div filters-slot><button class=\"btn btn-secondary\">My Menu</button></div>\n </si-flexible-dashboard>\n </div>\n</div>\n```\n\n### Translations\n\nThe dashboard comes with a couple of components with i18n support.\nThe library uses translation keys in the components and ships English\nand German (`en.json`, `de.json`) translations for demonstration. The\nfiles are located at the folder `node_modules/@spike-rabbit/dashboards-ng/assets/i18n/`\nand provides you all used keys. You should include the keys in your translation\nfiles and update the translations to your need.\n\nFor a quick test you can include the files from the library in your app.\nCopy the files to your target by updated the `assets` definition in the `angular.json`\nfile.\n\n```json\n{\n \"glob\": \"**/*\",\n \"input\": \"node_modules/@spike-rabbit/dashboards-ng/assets/i18n\",\n \"output\": \"./assets/i18n/dashboard/\"\n}\n```\n\nUse the `MultiTranslateHttpLoader` to load your and the library translation\nfiles.\n\n```ts\n...\nexport function createTranslateLoader(_httpBackend: HttpBackend) {\n return new MultiTranslateHttpLoader(_httpBackend, ['/assets/i18n/', '/assets/i18n/dashboard/']);\n}\n\n...\n\nprovideTranslateService({\n loader: {\n provide: TranslateLoader,\n useFactory: (createTranslateLoader),\n deps: [HttpBackend]\n }\n})\n```\n\n### Widget development\n\nYou can develop your own widgets that are managed by the dashboard. One or multiple widgets\nhave to be provided by an Angular module or standalone and described by a `Widget` object, that includes\nthe meta information and the Angular widget instance component and editor names that are\nused to instantiate the widget at runtime.\n\nThe widget instance component must implement the `WidgetInstance` interface and the\neditor must implement the `WidgetInstanceEditor` interface. You must provide either\na module loader function with module name or a component loader function for standalone components\nthat is used to load the widget when needed.\n\nThe library ships with a [hello-widget](https://github.com/siemens/element/blob/main/projects/dashboards-demo/src/app/widgets/hello-widget/) example for illustration.\n\nE.g. a widget implements a user interface that is added at runtime into the body of a dashboard card.\nOptionally, the widget template may include a `<ng-template/>` to provides a footer implementation like\n`<ng-template #footer><a [siLink]=\"link\">Go to issues</a></ng-template>` in the [value-widget](https://github.com/siemens/element/blob/main/projects/dashboards-demo/src/app/widgets/charts/value-widget.component.ts).\nThe Angular component should export the template as the public attribute `footer`.\n\n```ts\n@ViewChild('footer', { static: true }) footer?: TemplateRef<unknown>;\n```\n\n### Remote Widget Loading (Microfrontends)\n\nThe flexible dashboard supports loading widgets as remote microfrontends, allowing widgets to be deployed and updated independently from the host application. Three integration options are available:\n\n#### Pure Module Federation (Webpack-based)\n\nUses `@angular-architects/module-federation` to share code between host and remote applications. Both host and remotes must use Webpack as the bundler.\n\nRegister the loader in your application bootstrap:\n\n```ts\nimport { registerModuleFederatedWidgetLoader } from '@spike-rabbit/dashboards-ng/module-federation';\n\nregisterModuleFederatedWidgetLoader();\n```\n\n```\n+-------------------------+ +----------------------------------+\n| Host App | | @angular-architects/ |\n| Module Federation |------>| module-federation |\n| (webpack) | | |\n+------------+------------+ +---------------^------------------+\n | |\n registerModuleFederatedWidgetLoader |\n | |\n+------------v------------+ +---------------+------------------+\n| @spike-rabbit/dashboards-ng/ | | Remote Widget |\n| module-federation | | Module Federation |\n+-------------------------+ | (webpack) |\n +----------------------------------+\n```\n\n#### Pure Native Federation (ESM-based)\n\nUses `@angular-architects/native-federation` with ES Module-based federation, independent of the bundler. Works with any build tool (esbuild, Vite, Webpack). Recommended for modern Angular applications.\n\nRegister the loader in your application bootstrap:\n\n```ts\nimport { registerNativeFederatedWidgetLoader } from '@spike-rabbit/dashboards-ng/native-federation';\n\nregisterNativeFederatedWidgetLoader();\n```\n\n```\n+-------------------------+ +----------------------------------+\n| Host App | | @angular-architects/ |\n| Native Federation |------>| native-federation |\n| (esbuild/Vite/webpack) | | |\n+------------+------------+ +---------------^------------------+\n | |\n registerNativeFederatedWidgetLoader |\n | |\n+------------v------------+ +---------------+------------------+\n| @spike-rabbit/dashboards-ng/ | | Remote Widget |\n| native-federation | | Native Federation |\n+-------------------------+ | (esbuild) |\n +----------------------------------+\n```\n\n#### Hybrid/Bridge (Native Federation + Module Federation)\n\nEnables a Native Federation shell to load Module Federation remotes using `@module-federation/runtime`. Useful for gradual migration or when integrating existing Webpack-based remotes into a modern ESM-based host.\n\nRegister the loader with your Module Federation instance:\n\n```ts\nimport { registerModuleFederatedWidgetLoader } from '@spike-rabbit/dashboards-ng/native-federation/mf-bridge';\n\nregisterModuleFederatedWidgetLoader(mfInstance);\n```\n\n```\n+-------------------------+ +----------------------------------+\n| Host App | | @angular-architects/ |\n| Native Federation |------>| native-federation |\n| (esbuild) | | |\n+------------+------------+ +----------------------------------+\n |\n | registerModuleFederatedWidgetLoader(mfInstance)\n |\n+------------v-----------------------+\n| @spike-rabbit/dashboards-ng/ |\n| native-federation/mf-bridge |\n+------------+-----------------------+\n |\n | loads\n |\n+------------v------------+ +----------------------------------+\n| @module-federation/ | | Remote Widget |\n| runtime |------>| Module Federation |\n+-------------------------+ | (webpack) |\n +----------------------------------+\n```\n\nFor more details, refer to [Combining Native Federation and Module Federation](https://www.angulararchitects.io/blog/combining-native-federation-and-module-federation/).\n\n#### Running the Demo Application\n\nThe [dashboard demo project](https://github.com/siemens/element/blob/main/projects/dashboards-demo/) includes examples of all microfrontend modes. Use these npm scripts to run locally:\n\n```sh\n# Module Federation mode (Webpack-based host and remotes)\npnpm run dashboards-demo:run-all:local\n\n# Native Federation mode with Hybrid/Bridge support (ESM-based host with both Native and Module Federation remotes)\npnpm run dashboards-demo:run-all:esm:local\n```\n\n### Widget instance ID generation\n\nEach widget instance on a dashboard requires a unique ID for identification and persistence. The library\nprovides a flexible system for generating these IDs through the `SiWidgetIdProvider` abstract class.\n\n#### Default ID generation\n\nBy default, the library uses `SiWidgetDefaultIdProvider`, which generates unique IDs using\na RFC4122 version 4 UUID (e.g.,`'550e8400-e29b-41d4-a716-446655440000'`). This default implementation\nuses `crypto.randomUUID()` to ensure cryptographically secure uniqueness with 122 bits of entropy.\n\n#### Custom ID generation\n\nTo implement custom ID generation logic (e.g., UUID-based, sequential or\ncontext-aware IDs), create a class that extends `SiWidgetIdProvider` and implement the\n`generateWidgetId` method:\n\n```ts\nimport { Injectable } from '@angular/core';\nimport { SiWidgetIdProvider } from '@spike-rabbit/dashboards-ng';\n\n@Injectable()\nexport class CustomWidgetIdProvider extends SiWidgetIdProvider {\n override generateWidgetId(widget: WidgetConfig, dashboardId?: string): string {\n // Example: Create a composite ID from dashboard and widget type\n const prefix = dashboardId ?? 'default';\n const timestamp = Date.now();\n return `${prefix}-${widget.widgetId}-${timestamp}`;\n }\n}\n```\n\n#### Providing a custom ID provider\n\nTo use your custom ID provider, register it in your application's providers:\n\n```ts\n// For standalone applications\nproviders: [{ provide: SI_WIDGET_ID_PROVIDER, useClass: CustomWidgetIdProvider }];\n\n// For module-based applications\n@NgModule({\n providers: [{ provide: SI_WIDGET_ID_PROVIDER, useClass: CustomWidgetIdProvider }]\n})\nexport class AppModule {}\n```\n\n### Dashboard persistence\n\nThe library persists a dashboard configuration by the default `SiDefaultWidgetStorage` implementation\nof the API [SiWidgetStorage](https://github.com/siemens/element/blob/main/projects/dashboards-ng/src/model/si-widget-storage.ts). The\n`SiDefaultWidgetStorage` uses the `Storage` implementation `sessionStorage`. You can set a different\n`Storage` like the `localStorage` by providing the `DEFAULT_WIDGET_STORAGE_TOKEN` in the related module.\n\n```ts\nproviders: [..., { provide: DEFAULT_WIDGET_STORAGE_TOKEN, useValue: localStorage }],\n```\n\nFor persistence in a backend service, you should implement your own\n[SiWidgetStorage](https://github.com/siemens/element/blob/main/projects/dashboards-ng/src/model/si-widget-storage.ts) and provide it in\nyour module providers or application config.\n\n```ts\nproviders: [{ provide: SI_WIDGET_STORE, useClass: CustomWidgetStorage }];\n```\n\n### Configuration\n\nThe dashboard is configurable through the Angular inputs of the exposed components and by\nthe usage of the configuration object `Config`, which includes a `GridConfig` and including\nthe [GridStackOptions](https://github.com/siemens/element/blob/main/projects/dashboards-ng/src/model/gridstack.model.ts).\n\nTo configure all dashboard instances, you can leverage dependency injection by providing\nthe `SI_DASHBOARD_CONFIGURATION` token in your providers.\nAlternatively, you have the option to configure individual dashboard instances by setting\nthe input property `SiFlexibleDashboardComponent.config = {...}`.\n\nHere is the [demo](https://github.com/siemens/element/blob/main/projects/dashboards-demo/src/app/pages/fixed-widgets-dashboard/fixed-widgets-dashboard.component.ts)\n\n## License\n\nCode and documentation Copyright (c) Siemens 2016 - 2026\n\nMIT, see [LICENSE.md](LICENSE.md).\n"
51
75
  }
@@ -1,3 +1,4 @@
1
1
  {
2
- "module": "../fesm2022/spike-rabbit-dashboards-ng-translate.mjs"
2
+ "module": "../fesm2022/spike-rabbit-dashboards-ng-translate.mjs",
3
+ "typings": "../types/spike-rabbit-dashboards-ng-translate.d.ts"
3
4
  }
@@ -0,0 +1,9 @@
1
+ import { ModuleFederation } from '@module-federation/runtime';
2
+
3
+ /**
4
+ * Use this when having native federation shell and remote module is using module federation.
5
+ * @param mfInstance - The ModuleFederation instance returned by `createInstance` from '\@module-federation/runtime'
6
+ */
7
+ declare const registerModuleFederatedWidgetLoader: (mfInstance: ModuleFederation) => void;
8
+
9
+ export { registerModuleFederatedWidgetLoader };
@@ -0,0 +1,3 @@
1
+ declare const registerNativeFederatedWidgetLoader: () => void;
2
+
3
+ export { registerNativeFederatedWidgetLoader };
@@ -1,6 +1,7 @@
1
1
  import { Provider } from '@angular/core';
2
2
 
3
3
  interface SiTranslatableKeys {
4
+ 'DASHBOARD.A11Y.WIDGETS_LIST'?: string;
4
5
  'DASHBOARD.ADD_WIDGET'?: string;
5
6
  'DASHBOARD.CANCEL'?: string;
6
7
  'DASHBOARD.EDIT'?: string;
@@ -9,6 +10,11 @@ interface SiTranslatableKeys {
9
10
  'DASHBOARD.REMOVE_WIDGET_CONFIRMATION_DIALOG.MESSAGE'?: string;
10
11
  'DASHBOARD.REMOVE_WIDGET_CONFIRMATION_DIALOG.REMOVE'?: string;
11
12
  'DASHBOARD.SAVE'?: string;
13
+ 'DASHBOARD.WIDGET.A11Y.ACTIVATED'?: string;
14
+ 'DASHBOARD.WIDGET.A11Y.DEACTIVATED'?: string;
15
+ 'DASHBOARD.WIDGET.A11Y.DESCRIPTION'?: string;
16
+ 'DASHBOARD.WIDGET.A11Y.MOVED'?: string;
17
+ 'DASHBOARD.WIDGET.A11Y.RESIZED'?: string;
12
18
  'DASHBOARD.WIDGET.EDIT'?: string;
13
19
  'DASHBOARD.WIDGET.EXPAND'?: string;
14
20
  'DASHBOARD.WIDGET.REMOVE'?: string;
@@ -34,10 +40,11 @@ interface SiTranslatableKeys {
34
40
  'DASHBOARD.WIDGET_LIBRARY.PREVIOUS'?: string;
35
41
  'DASHBOARD.WIDGET_LIBRARY.SEARCH_PLACEHOLDER'?: string;
36
42
  'DASHBOARD.WIDGET_LIBRARY.TITLE'?: string;
43
+ 'DASHBOARD.WIDGET_LIBRARY.WIDGET_CATALOG_LIST'?: string;
37
44
  }
38
45
 
39
46
  /**
40
- * Copyright (c) Siemens 2016 - 2025
47
+ * Copyright (c) Siemens 2016 - 2026
41
48
  * SPDX-License-Identifier: MIT
42
49
  */
43
50