@c8y/ngx-components 1024.2.4 → 1024.8.3

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 (71) hide show
  1. package/fesm2022/{c8y-ngx-components-asset-property-grid.component-DhfJagxU.mjs → c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs} +35 -19
  2. package/fesm2022/c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs.map +1 -0
  3. package/fesm2022/c8y-ngx-components-bookmarks.mjs +33 -23
  4. package/fesm2022/c8y-ngx-components-bookmarks.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +30 -16
  6. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +3 -2
  8. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +2 -2
  10. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-device-profile.mjs +27 -9
  12. package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-icon-selector.mjs +1538 -59
  14. package/fesm2022/c8y-ngx-components-icon-selector.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs +9 -11
  16. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components-remote-access-data.mjs +52 -2
  18. package/fesm2022/c8y-ngx-components-remote-access-data.mjs.map +1 -1
  19. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs +17 -3
  20. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs.map +1 -1
  21. package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs +184 -41
  22. package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs.map +1 -1
  23. package/fesm2022/c8y-ngx-components-repository-configuration.mjs +94 -49
  24. package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
  25. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +5 -4
  26. package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
  27. package/fesm2022/c8y-ngx-components-repository-software.mjs +10 -4
  28. package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
  29. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +5 -4
  30. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
  31. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +6 -5
  32. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  33. package/fesm2022/c8y-ngx-components.mjs +10 -5
  34. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  35. package/locales/de.po +327 -8
  36. package/locales/es.po +327 -8
  37. package/locales/fr.po +327 -8
  38. package/locales/ja_JP.po +325 -9
  39. package/locales/ko.po +327 -8
  40. package/locales/locales.pot +326 -7
  41. package/locales/nl.po +327 -8
  42. package/locales/pl.po +327 -8
  43. package/locales/pt_BR.po +327 -8
  44. package/locales/zh_CN.po +327 -8
  45. package/locales/zh_TW.po +327 -8
  46. package/package.json +1 -1
  47. package/types/c8y-ngx-components-bookmarks.d.ts +7 -7
  48. package/types/c8y-ngx-components-bookmarks.d.ts.map +1 -1
  49. package/types/c8y-ngx-components-context-dashboard.d.ts +7 -3
  50. package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
  51. package/types/c8y-ngx-components-device-profile.d.ts +5 -2
  52. package/types/c8y-ngx-components-device-profile.d.ts.map +1 -1
  53. package/types/c8y-ngx-components-icon-selector.d.ts +286 -32
  54. package/types/c8y-ngx-components-icon-selector.d.ts.map +1 -1
  55. package/types/c8y-ngx-components-protocol-opcua.d.ts.map +1 -1
  56. package/types/c8y-ngx-components-remote-access-data.d.ts +27 -1
  57. package/types/c8y-ngx-components-remote-access-data.d.ts.map +1 -1
  58. package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts +10 -3
  59. package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts.map +1 -1
  60. package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts +20 -2
  61. package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts.map +1 -1
  62. package/types/c8y-ngx-components-repository-configuration.d.ts +20 -10
  63. package/types/c8y-ngx-components-repository-configuration.d.ts.map +1 -1
  64. package/types/c8y-ngx-components-repository-firmware.d.ts.map +1 -1
  65. package/types/c8y-ngx-components-repository-software.d.ts +2 -0
  66. package/types/c8y-ngx-components-repository-software.d.ts.map +1 -1
  67. package/types/c8y-ngx-components-trusted-certificates.d.ts.map +1 -1
  68. package/types/c8y-ngx-components-widgets-implementations-asset-table.d.ts.map +1 -1
  69. package/types/c8y-ngx-components.d.ts +5 -1
  70. package/types/c8y-ngx-components.d.ts.map +1 -1
  71. package/fesm2022/c8y-ngx-components-asset-property-grid.component-DhfJagxU.mjs.map +0 -1
@@ -453,18 +453,23 @@ class ContextDashboardService {
453
453
  this.dashboardTabs$ = this.getTabs$(mo, types, route?.parent?.data, options);
454
454
  return this.dashboardTabs$;
455
455
  }
456
- getDashboard(name, defaultWidgets) {
456
+ getDashboard(name, defaultWidgets, context) {
457
457
  const children = this.mapWidgets(defaultWidgets);
458
+ const defaultDashboard = this.getDefaultDashboard({
459
+ name,
460
+ children,
461
+ translateWidgetTitle: true,
462
+ widgetClasses: { 'dashboard-theme-light': true, 'panel-title-regular': true }
463
+ });
458
464
  return this.getDashboard$(name, [ContextDashboardType.Named]).pipe(throwIfEmpty(), catchError(() => {
459
- if (!this.hasPermissionsToCopyDashboard()) {
460
- this.alert.warning(gettext('You are viewing a read-only dashboard because you don’t have the necessary permissions to modify it.'));
461
- }
462
- return of(this.getDefaultDashboard({
463
- name,
464
- children,
465
- translateWidgetTitle: true,
466
- widgetClasses: { 'dashboard-theme-light': true, 'panel-title-regular': true }
467
- }));
465
+ const canCreate$ = context?.id
466
+ ? from(this.permissions.canEdit(this.INVENTORY_ROLES, context))
467
+ : of(this.hasPermissionsToCopyDashboard());
468
+ return canCreate$.pipe(tap(hasPermission => {
469
+ if (!hasPermission) {
470
+ this.alert.warning(gettext('You are viewing a read-only dashboard because you don’t have the necessary permissions to modify it.'));
471
+ }
472
+ }), map(() => defaultDashboard));
468
473
  }));
469
474
  }
470
475
  updateNavigatorItem(mo) {
@@ -521,12 +526,19 @@ class ContextDashboardService {
521
526
  }
522
527
  /**
523
528
  * Checks if user is able to edit dashboard according to his roles and dashboard ownership.
529
+ * When the dashboard managed object has no ID (e.g. a default in-memory dashboard), the check
530
+ * falls back to the provided `fallbackContext` managed object (e.g. the device or group), which
531
+ * allows group-level inventory roles to be evaluated correctly via the request-based check.
524
532
  *
525
533
  * @param mo - Dashboard managed object.
534
+ * @param fallbackContext - Optional context (device or group) used for permission checks when `mo` has no ID.
526
535
  * @returns True if user is able to edit dashboard, false if he cannot.
527
536
  */
528
- async canEditDashboard(mo) {
529
- return await this.permissions.canEdit(this.INVENTORY_ROLES, mo);
537
+ async canEditDashboard(mo, fallbackContext) {
538
+ if (!isEmpty(mo.id) || !fallbackContext?.id) {
539
+ return await this.permissions.canEdit(this.INVENTORY_ROLES, mo);
540
+ }
541
+ return await this.permissions.canEdit(this.INVENTORY_ROLES, fallbackContext);
530
542
  }
531
543
  /**
532
544
  * Checks if user has permissions to copy dashboard according to his roles.
@@ -1627,7 +1639,7 @@ class DashboardDetailComponent {
1627
1639
  this.tabs = this.dashboardDetailService.getTabs();
1628
1640
  }
1629
1641
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DashboardDetailComponent, deps: [{ token: ContextDashboardService }, { token: i2$1.TranslateService }, { token: i2.ContextRouteService }, { token: i1.ActivatedRoute }, { token: i2.TabsService }, { token: i1.Router }, { token: i1$1.InventoryService }, { token: i1.ActivatedRoute }, { token: DashboardDetailService }, { token: i2.AppStateService }, { token: i2.GroupService }, { token: i2.ModalService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
1630
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DashboardDetailComponent, isStandalone: true, selector: "c8y-dashboard-detail", inputs: { isReport: "isReport", deviceType: "deviceType", context: "context", mo: "mo", dashboard: "dashboard", isNamedDashboard: "isNamedDashboard", hideAvailability: "hideAvailability" }, outputs: { dashboardSaved: "dashboardSaved", previewChanged: "previewChanged" }, providers: [DashboardDetailService], usesOnChanges: true, ngImport: i0, template: "<!--\n [isAnimated]=\"false\": ngx-bootstrap's CollapseDirective builds an Angular animation\n player on each open/close but never destroys it on teardown, so the root animation\n engine retains the player and its onDone closure pins this directive \u2014 and via the\n view tree the whole c8y-context-dashboard \u2014 on every \"Dashboard settings\" open (leak).\n-->\n<div\n class=\"collapse c8y-top-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"false\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span class=\"h4\">{{ 'Dashboard settings' | translate }}</span>\n </div>\n\n @if (!isCollapsed) {\n <div class=\"d-flex\">\n <c8y-tabs-outlet\n class=\"c8y-top-drawer--tabs\"\n [tabs]=\"tabs\"\n [outletName]=\"TABS_OUTLET_NAME\"\n [orientation]=\"'vertical'\"\n [openFirstTab]=\"true\"\n ></c8y-tabs-outlet>\n\n <div\n class=\"inner-scroll c8y-top-drawer__tabs-container flex-grow p-l-24 p-r-lg-32 p-r-xs-24 p-r-sm-24\"\n >\n <router-outlet name=\"dashboard-details\"></router-outlet>\n </div>\n </div>\n }\n\n <div class=\"c8y-top-drawer--footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--cancel-dashboard\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--save-dashboard\"\n (click)=\"save()\"\n [disabled]=\"\n ((dashboardDetailsForm?.invalid || dashboardDetailsForm?.pristine) && this.isEdit) ||\n dashboardDetailService.saveButtonDisabled\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
1642
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DashboardDetailComponent, isStandalone: true, selector: "c8y-dashboard-detail", inputs: { isReport: "isReport", deviceType: "deviceType", context: "context", mo: "mo", dashboard: "dashboard", isNamedDashboard: "isNamedDashboard", hideAvailability: "hideAvailability" }, outputs: { dashboardSaved: "dashboardSaved", previewChanged: "previewChanged" }, providers: [DashboardDetailService], usesOnChanges: true, ngImport: i0, template: "<!--\n [isAnimated]=\"false\": ngx-bootstrap's CollapseDirective builds an Angular animation\n player on each open/close but never destroys it on teardown, so the root animation\n engine retains the player and its onDone closure pins this directive \u2014 and via the\n view tree the whole c8y-context-dashboard \u2014 on every \"Dashboard settings\" open (leak).\n\n decision by Jan on 9/7/2026 renable it and start preparing to bump ngx-bootstrap to 21.2.1\n-->\n<div\n class=\"collapse c8y-top-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span class=\"h4\">{{ 'Dashboard settings' | translate }}</span>\n </div>\n\n @if (!isCollapsed) {\n <div class=\"d-flex\">\n <c8y-tabs-outlet\n class=\"c8y-top-drawer--tabs\"\n [tabs]=\"tabs\"\n [outletName]=\"TABS_OUTLET_NAME\"\n [orientation]=\"'vertical'\"\n [openFirstTab]=\"true\"\n ></c8y-tabs-outlet>\n\n <div\n class=\"inner-scroll c8y-top-drawer__tabs-container flex-grow p-l-24 p-r-lg-32 p-r-xs-24 p-r-sm-24\"\n >\n <router-outlet name=\"dashboard-details\"></router-outlet>\n </div>\n </div>\n }\n\n <div class=\"c8y-top-drawer--footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--cancel-dashboard\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--save-dashboard\"\n (click)=\"save()\"\n [disabled]=\"\n ((dashboardDetailsForm?.invalid || dashboardDetailsForm?.pristine) && this.isEdit) ||\n dashboardDetailService.saveButtonDisabled\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "component", type: TabsOutletComponent, selector: "c8y-tabs-outlet,c8y-ui-tabs", inputs: ["tabs", "orientation", "navigatorOpen", "outletName", "context", "openFirstTab", "hasHeader"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
1631
1643
  }
1632
1644
  __decorate([
1633
1645
  memoize(),
@@ -1637,7 +1649,7 @@ __decorate([
1637
1649
  ], DashboardDetailComponent.prototype, "convertStringToHash", null);
1638
1650
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DashboardDetailComponent, decorators: [{
1639
1651
  type: Component,
1640
- args: [{ selector: 'c8y-dashboard-detail', providers: [DashboardDetailService], imports: [CollapseDirective, TabsOutletComponent, RouterOutlet, C8yTranslatePipe], template: "<!--\n [isAnimated]=\"false\": ngx-bootstrap's CollapseDirective builds an Angular animation\n player on each open/close but never destroys it on teardown, so the root animation\n engine retains the player and its onDone closure pins this directive \u2014 and via the\n view tree the whole c8y-context-dashboard \u2014 on every \"Dashboard settings\" open (leak).\n-->\n<div\n class=\"collapse c8y-top-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"false\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span class=\"h4\">{{ 'Dashboard settings' | translate }}</span>\n </div>\n\n @if (!isCollapsed) {\n <div class=\"d-flex\">\n <c8y-tabs-outlet\n class=\"c8y-top-drawer--tabs\"\n [tabs]=\"tabs\"\n [outletName]=\"TABS_OUTLET_NAME\"\n [orientation]=\"'vertical'\"\n [openFirstTab]=\"true\"\n ></c8y-tabs-outlet>\n\n <div\n class=\"inner-scroll c8y-top-drawer__tabs-container flex-grow p-l-24 p-r-lg-32 p-r-xs-24 p-r-sm-24\"\n >\n <router-outlet name=\"dashboard-details\"></router-outlet>\n </div>\n </div>\n }\n\n <div class=\"c8y-top-drawer--footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--cancel-dashboard\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--save-dashboard\"\n (click)=\"save()\"\n [disabled]=\"\n ((dashboardDetailsForm?.invalid || dashboardDetailsForm?.pristine) && this.isEdit) ||\n dashboardDetailService.saveButtonDisabled\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</div>\n" }]
1652
+ args: [{ selector: 'c8y-dashboard-detail', providers: [DashboardDetailService], imports: [CollapseDirective, TabsOutletComponent, RouterOutlet, C8yTranslatePipe], template: "<!--\n [isAnimated]=\"false\": ngx-bootstrap's CollapseDirective builds an Angular animation\n player on each open/close but never destroys it on teardown, so the root animation\n engine retains the player and its onDone closure pins this directive \u2014 and via the\n view tree the whole c8y-context-dashboard \u2014 on every \"Dashboard settings\" open (leak).\n\n decision by Jan on 9/7/2026 renable it and start preparing to bump ngx-bootstrap to 21.2.1\n-->\n<div\n class=\"collapse c8y-top-drawer\"\n [collapse]=\"isCollapsed\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span class=\"h4\">{{ 'Dashboard settings' | translate }}</span>\n </div>\n\n @if (!isCollapsed) {\n <div class=\"d-flex\">\n <c8y-tabs-outlet\n class=\"c8y-top-drawer--tabs\"\n [tabs]=\"tabs\"\n [outletName]=\"TABS_OUTLET_NAME\"\n [orientation]=\"'vertical'\"\n [openFirstTab]=\"true\"\n ></c8y-tabs-outlet>\n\n <div\n class=\"inner-scroll c8y-top-drawer__tabs-container flex-grow p-l-24 p-r-lg-32 p-r-xs-24 p-r-sm-24\"\n >\n <router-outlet name=\"dashboard-details\"></router-outlet>\n </div>\n </div>\n }\n\n <div class=\"c8y-top-drawer--footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--cancel-dashboard\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n data-cy=\"dashboard-detail--save-dashboard\"\n (click)=\"save()\"\n [disabled]=\"\n ((dashboardDetailsForm?.invalid || dashboardDetailsForm?.pristine) && this.isEdit) ||\n dashboardDetailService.saveButtonDisabled\n \"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</div>\n" }]
1641
1653
  }], ctorParameters: () => [{ type: ContextDashboardService }, { type: i2$1.TranslateService }, { type: i2.ContextRouteService }, { type: i1.ActivatedRoute }, { type: i2.TabsService }, { type: i1.Router }, { type: i1$1.InventoryService }, { type: i1.ActivatedRoute }, { type: DashboardDetailService }, { type: i2.AppStateService }, { type: i2.GroupService }, { type: i2.ModalService }, { type: i2.GainsightService }], propDecorators: { isReport: [{
1642
1654
  type: Input
1643
1655
  }], deviceType: [{
@@ -3413,8 +3425,9 @@ class ContextDashboardComponent {
3413
3425
  }
3414
3426
  async onLoad(trackExperience) {
3415
3427
  this.isNamedDashboard = this.contextDashboardService.isNamed(this.mo);
3428
+ const activeContext = this.context?.contextData || this.context;
3416
3429
  this.hasPermissionToEditDashboard = this.dashboard
3417
- ? await this.contextDashboardService.canEditDashboard(this.mo)
3430
+ ? await this.contextDashboardService.canEditDashboard(this.mo, activeContext)
3418
3431
  : false;
3419
3432
  this.canCopy =
3420
3433
  this._canCopy &&
@@ -3516,8 +3529,9 @@ class ContextDashboardComponent {
3516
3529
  }
3517
3530
  }
3518
3531
  loadNamedDashboard() {
3532
+ const activeContext = this.context?.contextData || this.context;
3519
3533
  this.dataSub = this.contextDashboardService
3520
- .getDashboard(this.name, this.defaultWidgets)
3534
+ .getDashboard(this.name, this.defaultWidgets, activeContext)
3521
3535
  .subscribe(mo => {
3522
3536
  this.context = this.context || {};
3523
3537
  this.mo = mo;