@c8y/ngx-components 1024.1.8 → 1024.5.1

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 (87) hide show
  1. package/fesm2022/c8y-ngx-components-bookmarks.mjs +33 -23
  2. package/fesm2022/c8y-ngx-components-bookmarks.mjs.map +1 -1
  3. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +2 -2
  4. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +65 -25
  6. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +363 -38
  8. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-device-profile.mjs +27 -9
  10. package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -1
  12. package/fesm2022/c8y-ngx-components-echart.mjs +796 -123
  13. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  14. package/fesm2022/c8y-ngx-components-global-context.mjs +391 -54
  15. package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
  16. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs +9 -11
  17. package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
  18. package/fesm2022/c8y-ngx-components-remote-access-data.mjs +43 -0
  19. package/fesm2022/c8y-ngx-components-remote-access-data.mjs.map +1 -1
  20. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs +17 -3
  21. package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs.map +1 -1
  22. package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs +179 -41
  23. package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs.map +1 -1
  24. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +5 -4
  25. package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
  26. package/fesm2022/c8y-ngx-components-repository-software.mjs +10 -4
  27. package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
  28. package/fesm2022/c8y-ngx-components-time-context.mjs +146 -20
  29. package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
  30. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +5 -4
  31. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
  32. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +6 -5
  33. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  34. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +198 -24
  35. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  36. package/fesm2022/c8y-ngx-components.mjs +109 -36
  37. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  38. package/locales/de.po +141 -13
  39. package/locales/es.po +141 -13
  40. package/locales/fr.po +141 -13
  41. package/locales/ja_JP.po +140 -14
  42. package/locales/ko.po +141 -13
  43. package/locales/locales.pot +139 -11
  44. package/locales/nl.po +141 -13
  45. package/locales/pl.po +141 -13
  46. package/locales/pt_BR.po +141 -13
  47. package/locales/zh_CN.po +141 -13
  48. package/locales/zh_TW.po +141 -13
  49. package/package.json +1 -1
  50. package/types/c8y-ngx-components-bookmarks.d.ts +7 -7
  51. package/types/c8y-ngx-components-bookmarks.d.ts.map +1 -1
  52. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts +4 -1
  53. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -1
  54. package/types/c8y-ngx-components-datapoint-selector.d.ts +93 -5
  55. package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
  56. package/types/c8y-ngx-components-device-profile.d.ts +5 -2
  57. package/types/c8y-ngx-components-device-profile.d.ts.map +1 -1
  58. package/types/c8y-ngx-components-echart-models.d.ts +25 -3
  59. package/types/c8y-ngx-components-echart-models.d.ts.map +1 -1
  60. package/types/c8y-ngx-components-echart.d.ts +65 -5
  61. package/types/c8y-ngx-components-echart.d.ts.map +1 -1
  62. package/types/c8y-ngx-components-global-context.d.ts +187 -7
  63. package/types/c8y-ngx-components-global-context.d.ts.map +1 -1
  64. package/types/c8y-ngx-components-protocol-opcua.d.ts.map +1 -1
  65. package/types/c8y-ngx-components-remote-access-data.d.ts +19 -0
  66. package/types/c8y-ngx-components-remote-access-data.d.ts.map +1 -1
  67. package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts +10 -3
  68. package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts.map +1 -1
  69. package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts +20 -2
  70. package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts.map +1 -1
  71. package/types/c8y-ngx-components-repository-firmware.d.ts.map +1 -1
  72. package/types/c8y-ngx-components-repository-software.d.ts +2 -0
  73. package/types/c8y-ngx-components-repository-software.d.ts.map +1 -1
  74. package/types/c8y-ngx-components-time-context.d.ts +50 -8
  75. package/types/c8y-ngx-components-time-context.d.ts.map +1 -1
  76. package/types/c8y-ngx-components-trusted-certificates.d.ts.map +1 -1
  77. package/types/c8y-ngx-components-widgets-implementations-alarms.d.ts +1 -0
  78. package/types/c8y-ngx-components-widgets-implementations-alarms.d.ts.map +1 -1
  79. package/types/c8y-ngx-components-widgets-implementations-asset-table.d.ts.map +1 -1
  80. package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts +25 -0
  81. package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -1
  82. package/types/c8y-ngx-components-widgets-implementations-datapoints-list.d.ts +1 -0
  83. package/types/c8y-ngx-components-widgets-implementations-datapoints-list.d.ts.map +1 -1
  84. package/types/c8y-ngx-components-widgets-implementations-scada.d.ts +2 -0
  85. package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
  86. package/types/c8y-ngx-components.d.ts +55 -12
  87. package/types/c8y-ngx-components.d.ts.map +1 -1
@@ -1,20 +1,21 @@
1
1
  import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
2
2
  import * as i0 from '@angular/core';
3
- import { Injectable, HostListener, Input, Component, DOCUMENT, Inject, NgModule } from '@angular/core';
4
- import * as i5 from '@angular/forms';
3
+ import { Injectable, inject, ChangeDetectorRef, Input, ChangeDetectionStrategy, Component, DOCUMENT, Inject, NgModule } from '@angular/core';
4
+ import * as i1$1 from '@angular/forms';
5
5
  import { FormsModule } from '@angular/forms';
6
6
  import * as i1$2 from 'ngx-bootstrap/tooltip';
7
7
  import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
8
8
  import * as i1 from '@c8y/ngx-components';
9
- import { IconDirective, C8yTranslateDirective, ListGroupComponent, ListItemComponent, ListItemDragHandleComponent, ListItemIconComponent, ChangeIconComponent, PopoverConfirmComponent, EmptyStateComponent, C8yTranslatePipe, CoreModule, CommonModule, ListGroupModule, FormsModule as FormsModule$1, ModalModule, hookDrawer } from '@c8y/ngx-components';
10
- import { NgIf, NgFor, AsyncPipe } from '@angular/common';
9
+ import { AlertService, IconDirective, C8yTranslateDirective, ListGroupComponent, ListItemComponent, ListItemDragHandleComponent, ListItemIconComponent, ChangeIconComponent, InputGroupEditableComponent, PopoverConfirmComponent, EmptyStateComponent, C8yTranslatePipe, CoreModule, CommonModule, ListGroupModule, FormsModule as FormsModule$1, ModalModule, hookDrawer } from '@c8y/ngx-components';
10
+ import { AsyncPipe } from '@angular/common';
11
11
  import * as i2 from '@angular/router';
12
12
  import { gettext } from '@c8y/ngx-components/gettext';
13
13
  import { uniqBy, cloneDeep } from 'lodash-es';
14
- import * as i1$1 from 'ngx-bootstrap/modal';
14
+ import * as i3$1 from 'ngx-bootstrap/modal';
15
+ import { BsModalRef } from 'ngx-bootstrap/modal';
15
16
  import * as i3 from '@ngx-translate/core';
16
17
  import { firstValueFrom, map } from 'rxjs';
17
- import * as i4 from '@c8y/ngx-components/icon-selector';
18
+ import { IconSelectorService } from '@c8y/ngx-components/icon-selector';
18
19
 
19
20
  class BookmarkService {
20
21
  static { this.DEFAULT_ICON = 'bookmark'; }
@@ -107,11 +108,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
107
108
  }], ctorParameters: () => [{ type: i1.NavigatorService }, { type: i1.OptionsService }, { type: i2.Router }, { type: i3.TranslateService }, { type: i1.UserPreferencesService }] });
108
109
 
109
110
  class EditBookmarksComponent {
110
- constructor(bsModalRef, alertService, bookmarkService, iconSelector) {
111
- this.bsModalRef = bsModalRef;
112
- this.alertService = alertService;
113
- this.bookmarkService = bookmarkService;
114
- this.iconSelector = iconSelector;
111
+ constructor() {
112
+ // @Input is intentional: this component is opened via BsModalService with initialState,
113
+ // which sets the property directly on the instance and is incompatible with signal inputs.
114
+ this.bookmarks = [];
115
+ this.bookmarksToUpdate = [];
115
116
  this.confirmRemoveColumnButtons = [
116
117
  {
117
118
  label: gettext('Cancel'),
@@ -126,6 +127,11 @@ class EditBookmarksComponent {
126
127
  this.result = new Promise(resolve => {
127
128
  this._close = resolve;
128
129
  });
130
+ this.bsModalRef = inject(BsModalRef);
131
+ this.alertService = inject(AlertService);
132
+ this.bookmarkService = inject(BookmarkService);
133
+ this.iconSelector = inject(IconSelectorService);
134
+ this.cdr = inject(ChangeDetectorRef);
129
135
  }
130
136
  ngOnInit() {
131
137
  this.bookmarksToUpdate = cloneDeep(this.bookmarks);
@@ -166,6 +172,10 @@ class EditBookmarksComponent {
166
172
  }
167
173
  }
168
174
  }
175
+ onLabelSaved(bookmark, label) {
176
+ bookmark.label = label;
177
+ this.updateBookmark(bookmark, 'label');
178
+ }
169
179
  updateBookmarkProperty(updatedBookmark, type) {
170
180
  const update = {
171
181
  icon: (bookmark) => ({ ...bookmark, icon: updatedBookmark.icon }),
@@ -179,6 +189,7 @@ class EditBookmarksComponent {
179
189
  const newIcon = await this.iconSelector.selectIcon();
180
190
  updatedBookmark.icon = newIcon;
181
191
  await this.updateBookmark(updatedBookmark, 'icon');
192
+ this.cdr.markForCheck();
182
193
  }
183
194
  catch {
184
195
  // nothing to do
@@ -197,6 +208,7 @@ class EditBookmarksComponent {
197
208
  return;
198
209
  }
199
210
  this.bookmarks.splice(bookmarkIndex, 1);
211
+ this.cdr.markForCheck();
200
212
  this.alertService.success(gettext('Bookmark removed.'));
201
213
  }
202
214
  catch (err) {
@@ -208,18 +220,18 @@ class EditBookmarksComponent {
208
220
  }
209
221
  }
210
222
  }
211
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: EditBookmarksComponent, deps: [{ token: i1$1.BsModalRef }, { token: i1.AlertService }, { token: BookmarkService }, { token: i4.IconSelectorService }], target: i0.ɵɵFactoryTarget.Component }); }
212
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.17", type: EditBookmarksComponent, isStandalone: true, selector: "c8y-edit-bookmarks", inputs: { bookmarks: "bookmarks" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n *ngIf=\"bookmarks.length; else emptyList\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks?.length < 2\"\n >\n <c8y-li\n *ngFor=\"let bookmark of bookmarks\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n <c8y-li-icon\n style=\"{{ bookmarks?.length < 2 ? 'padding-left: 16px!important' : '' }}\"\n *ngIf=\"bookmark.icon\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n\n <div class=\"d-flex gap-8 a-i-center\">\n <form\n class=\"d-flex flex-grow\"\n name=\"bookmarksForm\"\n #bookmarksForm=\"ngForm\"\n >\n <div class=\"input-group input-group-editable\">\n <input\n class=\"form-control fit-w\"\n title=\"{{ bookmark.label }}\"\n id=\"label\"\n name=\"label\"\n type=\"text\"\n [(ngModel)]=\"bookmark.label\"\n #label=\"ngModel\"\n maxlength=\"50\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n (click)=\"updateBookmark(bookmark, 'label'); label.control.markAsPristine()\"\n [disabled]=\"label.invalid\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n</ng-template>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: ChangeIconComponent, selector: "c8y-change-icon", inputs: ["currentIcon"], outputs: ["onButtonClick"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PopoverConfirmComponent, selector: "c8y-popover-confirm", inputs: ["buttons", "message", "title", "isOpen", "containerClass", "placement", "outsideClick", "adaptivePosition", "container"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
223
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: EditBookmarksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
224
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: EditBookmarksComponent, isStandalone: true, selector: "c8y-edit-bookmarks", inputs: { bookmarks: "bookmarks" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n @if (bookmarks.length) {\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks.length < 2\"\n >\n @for (bookmark of bookmarks; track bookmark.id) {\n <c8y-li cdkDrag>\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n @if (bookmark.icon) {\n <c8y-li-icon\n class=\"a-s-stretch\"\n [style.padding-left]=\"bookmarks.length < 2 ? '16px !important' : null\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n }\n\n <div class=\"d-flex gap-8 a-i-center\">\n <div class=\"flex-grow\">\n <c8y-input-group-editable\n [ariaLabel]=\"'Bookmark label' | translate\"\n formGroupClass=\"m-b-0\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n [maxLength]=\"50\"\n [ngModel]=\"bookmark.label\"\n (ngModelChange)=\"onLabelSaved(bookmark, $event)\"\n ></c8y-input-group-editable>\n </div>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n }\n </c8y-list-group>\n } @else {\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: ChangeIconComponent, selector: "c8y-change-icon", inputs: ["currentIcon"], outputs: ["onButtonClick"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputGroupEditableComponent, selector: "c8y-input-group-editable", inputs: ["ariaLabel", "name", "size", "placeholder", "multiline", "maxHeight", "maxLength", "noSaveButton", "formGroupClass", "validators", "asyncValidators", "autocomplete"], outputs: ["save", "cancel"] }, { kind: "component", type: PopoverConfirmComponent, selector: "c8y-popover-confirm", inputs: ["buttons", "message", "title", "isOpen", "containerClass", "placement", "outsideClick", "adaptivePosition", "container"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
213
225
  }
214
226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: EditBookmarksComponent, decorators: [{
215
227
  type: Component,
216
- args: [{ selector: 'c8y-edit-bookmarks', imports: [
228
+ args: [{ selector: 'c8y-edit-bookmarks', changeDetection: ChangeDetectionStrategy.OnPush, host: {
229
+ '(document:keydown)': 'handleKeyboardEvent($event)'
230
+ }, imports: [
217
231
  IconDirective,
218
232
  C8yTranslateDirective,
219
- NgIf,
220
233
  ListGroupComponent,
221
234
  CdkDropList,
222
- NgFor,
223
235
  ListItemComponent,
224
236
  CdkDrag,
225
237
  ListItemDragHandleComponent,
@@ -227,15 +239,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
227
239
  ListItemIconComponent,
228
240
  ChangeIconComponent,
229
241
  FormsModule,
242
+ InputGroupEditableComponent,
230
243
  PopoverConfirmComponent,
231
244
  EmptyStateComponent,
232
245
  C8yTranslatePipe
233
- ], template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n *ngIf=\"bookmarks.length; else emptyList\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks?.length < 2\"\n >\n <c8y-li\n *ngFor=\"let bookmark of bookmarks\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n <c8y-li-icon\n style=\"{{ bookmarks?.length < 2 ? 'padding-left: 16px!important' : '' }}\"\n *ngIf=\"bookmark.icon\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n\n <div class=\"d-flex gap-8 a-i-center\">\n <form\n class=\"d-flex flex-grow\"\n name=\"bookmarksForm\"\n #bookmarksForm=\"ngForm\"\n >\n <div class=\"input-group input-group-editable\">\n <input\n class=\"form-control fit-w\"\n title=\"{{ bookmark.label }}\"\n id=\"label\"\n name=\"label\"\n type=\"text\"\n [(ngModel)]=\"bookmark.label\"\n #label=\"ngModel\"\n maxlength=\"50\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n (click)=\"updateBookmark(bookmark, 'label'); label.control.markAsPristine()\"\n [disabled]=\"label.invalid\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n</ng-template>\n" }]
234
- }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i1.AlertService }, { type: BookmarkService }, { type: i4.IconSelectorService }], propDecorators: { bookmarks: [{
246
+ ], template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n @if (bookmarks.length) {\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks.length < 2\"\n >\n @for (bookmark of bookmarks; track bookmark.id) {\n <c8y-li cdkDrag>\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n @if (bookmark.icon) {\n <c8y-li-icon\n class=\"a-s-stretch\"\n [style.padding-left]=\"bookmarks.length < 2 ? '16px !important' : null\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n }\n\n <div class=\"d-flex gap-8 a-i-center\">\n <div class=\"flex-grow\">\n <c8y-input-group-editable\n [ariaLabel]=\"'Bookmark label' | translate\"\n formGroupClass=\"m-b-0\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n [maxLength]=\"50\"\n [ngModel]=\"bookmark.label\"\n (ngModelChange)=\"onLabelSaved(bookmark, $event)\"\n ></c8y-input-group-editable>\n </div>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n }\n </c8y-list-group>\n } @else {\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n" }]
247
+ }], propDecorators: { bookmarks: [{
235
248
  type: Input
236
- }], handleKeyboardEvent: [{
237
- type: HostListener,
238
- args: ['document:keydown', ['$event']]
239
249
  }] } });
240
250
 
241
251
  class BookmarksComponent {
@@ -329,7 +339,7 @@ class BookmarksComponent {
329
339
  return url;
330
340
  }
331
341
  }
332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BookmarksComponent, deps: [{ token: DOCUMENT }, { token: i1.AlertService }, { token: BookmarkService }, { token: i1$1.BsModalService }, { token: i2.Router }, { token: i1.HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
342
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BookmarksComponent, deps: [{ token: DOCUMENT }, { token: i1.AlertService }, { token: BookmarkService }, { token: i3$1.BsModalService }, { token: i2.Router }, { token: i1.HeaderService }], target: i0.ɵɵFactoryTarget.Component }); }
333
343
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: BookmarksComponent, isStandalone: true, selector: "c8y-bookmarks", ngImport: i0, template: "<div class=\"separator-top p-t-8 m-t-auto c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Bookmarks' | translate }}</span>\n <button\n class=\"btn-dot m-l-auto\"\n [attr.aria-label]=\"'Edit bookmarks' | translate\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n tooltip=\"{{ 'Edit bookmarks' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n (click)=\"editBookmarks()\"\n >\n <i\n class=\"text-14 m-0\"\n c8yIcon=\"cog\"\n ></i>\n </button>\n</div>\n@if (bookmarks?.length) {\n <div class=\"c8y-right-drawer__item p-t-0 p-b-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n}\n@if (bookmarks?.length) {\n @for (bookmark of bookmarks; track bookmark.url) {\n <button\n class=\"c8y-right-drawer__link\"\n title=\"{{ bookmark.label }}\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"openUrl(bookmark.url)\"\n >\n @if (bookmark.icon) {\n <i [c8yIcon]=\"bookmark.icon\"></i>\n }\n <span class=\"text-truncate\">{{ bookmark.label }}</span>\n </button>\n }\n}\n\n<div class=\"p-t-8 p-b-8\">\n @if (!bookmarks?.length) {\n <span class=\"c8y-right-drawer__item text-muted text-bold text-14 p-b-0\">\n {{ emptyMessageHeader | translate }}\n </span>\n <span class=\"c8y-right-drawer__item text-12 p-t-0\">\n <span class=\"text-muted\">{{ emptyMessageBody | translate }}</span>\n </span>\n <div class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
334
344
  }
335
345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BookmarksComponent, decorators: [{
@@ -338,7 +348,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
338
348
  }], ctorParameters: () => [{ type: DOCUMENT, decorators: [{
339
349
  type: Inject,
340
350
  args: [DOCUMENT]
341
- }] }, { type: i1.AlertService }, { type: BookmarkService }, { type: i1$1.BsModalService }, { type: i2.Router }, { type: i1.HeaderService }] });
351
+ }] }, { type: i1.AlertService }, { type: BookmarkService }, { type: i3$1.BsModalService }, { type: i2.Router }, { type: i1.HeaderService }] });
342
352
 
343
353
  class BookmarksModule {
344
354
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BookmarksModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-bookmarks.mjs","sources":["../../bookmarks/bookmarks.service.ts","../../bookmarks/edit-bookmarks/edit-bookmarks.component.ts","../../bookmarks/edit-bookmarks/edit-bookmarks.component.html","../../bookmarks/bookmarks.component.ts","../../bookmarks/bookmarks.component.html","../../bookmarks/bookmarks.module.ts","../../bookmarks/c8y-ngx-components-bookmarks.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { Router } from '@angular/router';\nimport {\n NavigatorNode,\n NavigatorService,\n OptionsService,\n UserPreferencesService\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { TranslateService } from '@ngx-translate/core';\nimport { uniqBy } from 'lodash-es';\nimport { firstValueFrom, map } from 'rxjs';\nimport { Bookmark } from './bookmark.model';\n\n@Injectable({ providedIn: 'root' })\nexport class BookmarkService {\n private static readonly DEFAULT_ICON = 'bookmark';\n\n readonly USER_PREFERENCES_BOOKMARKS_KEY = 'bookmarks';\n\n updatedBookmarks: Bookmark[];\n\n constructor(\n private navigatorService: NavigatorService,\n private options: OptionsService,\n private router: Router,\n private translateService: TranslateService,\n private userPreferencesService: UserPreferencesService\n ) {}\n\n async updateBookmarksInStorage(newBookmarks: Bookmark[]): Promise<void> {\n const existingBookmarks = await this.getBookmarks();\n const mergedBookmarks = [...newBookmarks, ...existingBookmarks];\n const cleanedBookmarks = uniqBy(mergedBookmarks, 'id').filter(\n (bookmark: Bookmark) => !bookmark.markToRemove\n );\n\n this.setUserPreferencesBookmarks(cleanedBookmarks);\n }\n\n async getActiveNodeIcon(): Promise<string> {\n const activeNode = await this.findActiveNode();\n return activeNode?.icon || BookmarkService.DEFAULT_ICON;\n }\n\n extractIconName(input: string): string | null {\n const iconRegex = /\\b(dlt-)?c8y-icon-(\\w+(?:-\\w+)*)\\b/g;\n const matches = [...input.matchAll(iconRegex)];\n const match = matches?.pop();\n\n if (!match) {\n return null;\n }\n const [, prefix, name] = match;\n\n return prefix ? name : `c8y-${name}`;\n }\n\n async getBookmarks(): Promise<Bookmark[]> {\n return await firstValueFrom(\n this.userPreferencesService\n .get(this.USER_PREFERENCES_BOOKMARKS_KEY)\n .pipe(map((bookmarks: Bookmark[]) => bookmarks ?? []))\n );\n }\n\n generateRandomID() {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n\n return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');\n }\n\n convertBookmarkLinkToObject(title: string, url: string, icon: string): Bookmark {\n const globalTitle = this.options.globalTitle ?? 'Cumulocity';\n return {\n id: this.generateRandomID(),\n label: title.includes(globalTitle)\n ? title.replace(`${globalTitle} - `, '')\n : this.translateService.instant(gettext('Bookmark')),\n url,\n icon\n };\n }\n\n private async findActiveNode(): Promise<NavigatorNode | undefined> {\n const nodes = await firstValueFrom(this.navigatorService.items$);\n return this.findActiveInTree(nodes);\n }\n\n private findActiveInTree(nodes: NavigatorNode[]): NavigatorNode | undefined {\n let result: NavigatorNode | undefined;\n\n for (const node of nodes) {\n if (node.path && this.isNodeActive(node)) {\n result = node;\n }\n if (node.children?.length) {\n const childMatch = this.findActiveInTree(node.children);\n if (childMatch) {\n result = childMatch;\n }\n }\n }\n\n return result;\n }\n\n private isNodeActive(node: NavigatorNode): boolean {\n return this.router.isActive(node.path, {\n paths: node.routerLinkExact ? 'exact' : 'subset',\n queryParams: 'ignored',\n fragment: 'ignored',\n matrixParams: 'ignored'\n });\n }\n\n private setUserPreferencesBookmarks(bookmarks: Bookmark[]): void {\n this.userPreferencesService.set(this.USER_PREFERENCES_BOOKMARKS_KEY, bookmarks);\n this.updatedBookmarks = bookmarks;\n }\n}\n","import {\n CdkDragDrop,\n moveItemInArray,\n CdkDropList,\n CdkDrag,\n CdkDragHandle\n} from '@angular/cdk/drag-drop';\nimport { Component, HostListener, Input, OnInit } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n AlertService,\n PopoverConfirmButtons,\n PopoverConfirmComponent,\n IconDirective,\n C8yTranslateDirective,\n ListGroupComponent,\n ListItemComponent,\n ListItemDragHandleComponent,\n ListItemIconComponent,\n ChangeIconComponent,\n EmptyStateComponent,\n C8yTranslatePipe\n} from '@c8y/ngx-components';\nimport { IconSelectorService } from '@c8y/ngx-components/icon-selector';\nimport { cloneDeep } from 'lodash-es';\nimport { BsModalRef } from 'ngx-bootstrap/modal';\nimport { Bookmark } from '../bookmark.model';\nimport { BookmarkService } from '../bookmarks.service';\nimport { NgIf, NgFor } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\n@Component({\n selector: 'c8y-edit-bookmarks',\n templateUrl: './edit-bookmarks.component.html',\n imports: [\n IconDirective,\n C8yTranslateDirective,\n NgIf,\n ListGroupComponent,\n CdkDropList,\n NgFor,\n ListItemComponent,\n CdkDrag,\n ListItemDragHandleComponent,\n CdkDragHandle,\n ListItemIconComponent,\n ChangeIconComponent,\n FormsModule,\n PopoverConfirmComponent,\n EmptyStateComponent,\n C8yTranslatePipe\n ]\n})\nexport class EditBookmarksComponent implements OnInit {\n @Input() bookmarks: Bookmark[];\n private bookmarksToUpdate: Bookmark[];\n\n confirmRemoveColumnButtons: PopoverConfirmButtons[] = [\n {\n label: gettext('Cancel'),\n action: () => Promise.resolve(false)\n },\n {\n label: gettext('Delete'),\n status: 'danger',\n action: () => Promise.resolve(true)\n }\n ];\n\n result: Promise<Bookmark[]> = new Promise(resolve => {\n this._close = resolve;\n });\n\n private _close: (value: Bookmark[]) => void;\n\n constructor(\n private bsModalRef: BsModalRef,\n private alertService: AlertService,\n private bookmarkService: BookmarkService,\n private iconSelector: IconSelectorService\n ) {}\n\n ngOnInit(): void {\n this.bookmarksToUpdate = cloneDeep(this.bookmarks);\n }\n\n @HostListener('document:keydown', ['$event'])\n handleKeyboardEvent(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n this.close();\n }\n }\n\n close(): void {\n if (this.bookmarkService.updatedBookmarks) {\n this._close(this.bookmarkService.updatedBookmarks);\n }\n this.bsModalRef.hide();\n }\n\n async drop(event: CdkDragDrop<Bookmark[]>): Promise<void> {\n try {\n moveItemInArray(this.bookmarks, event.previousIndex, event.currentIndex);\n moveItemInArray(this.bookmarksToUpdate, event.previousIndex, event.currentIndex);\n\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);\n this.alertService.success(gettext('Bookmarks order updated.'));\n } catch {\n this.alertService.success(gettext('Bookmarks order failed to update.'));\n }\n }\n\n async updateBookmark(\n updatedBookmark: Bookmark,\n type: keyof Pick<Bookmark, 'icon' | 'label' | 'markToRemove'>\n ): Promise<void> {\n try {\n this.bookmarksToUpdate = this.updateBookmarkProperty(updatedBookmark, type);\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);\n if (type !== 'markToRemove') {\n this.alertService.success(gettext('Bookmark updated.'));\n }\n } catch {\n if (type !== 'markToRemove') {\n this.alertService.warning(gettext('Bookmark update failed'));\n }\n }\n }\n\n updateBookmarkProperty(\n updatedBookmark: Bookmark,\n type: keyof Pick<Bookmark, 'icon' | 'label' | 'markToRemove'>\n ): Bookmark[] {\n const update = {\n icon: (bookmark: Bookmark) => ({ ...bookmark, icon: updatedBookmark.icon }),\n label: (bookmark: Bookmark) => ({ ...bookmark, label: updatedBookmark.label }),\n markToRemove: (bookmark: Bookmark) => ({ ...bookmark, markToRemove: true })\n }[type];\n\n return this.bookmarksToUpdate.map(bookmark =>\n bookmark.id === updatedBookmark.id ? update(bookmark) : bookmark\n );\n }\n\n async changeBookmarkIcon(updatedBookmark: Bookmark): Promise<void> {\n try {\n const newIcon = await this.iconSelector.selectIcon();\n updatedBookmark.icon = newIcon;\n await this.updateBookmark(updatedBookmark, 'icon');\n } catch {\n // nothing to do\n }\n }\n\n async removeBookmark(\n poConfirm: PopoverConfirmComponent,\n bookmarkToDelete: Bookmark\n ): Promise<void> {\n poConfirm.message = gettext('This action is irreversible.');\n\n try {\n const remove = await poConfirm.show(this.confirmRemoveColumnButtons);\n if (!remove) {\n return;\n }\n\n await this.updateBookmark(bookmarkToDelete, 'markToRemove');\n\n const bookmarkIndex = this.bookmarks.findIndex(\n bookmark => bookmark.id === bookmarkToDelete.id\n );\n\n if (bookmarkIndex === -1) {\n return;\n }\n\n this.bookmarks.splice(bookmarkIndex, 1);\n this.alertService.success(gettext('Bookmark removed.'));\n } catch (err) {\n /**\n * Prevents an alert message from being displayed if the user clicks outside of a popover.\n */\n if (err) {\n this.alertService.warning(gettext('Bookmarks deletion failed.'));\n }\n }\n }\n}\n","<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n *ngIf=\"bookmarks.length; else emptyList\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks?.length < 2\"\n >\n <c8y-li\n *ngFor=\"let bookmark of bookmarks\"\n cdkDrag\n >\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n <c8y-li-icon\n style=\"{{ bookmarks?.length < 2 ? 'padding-left: 16px!important' : '' }}\"\n *ngIf=\"bookmark.icon\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n\n <div class=\"d-flex gap-8 a-i-center\">\n <form\n class=\"d-flex flex-grow\"\n name=\"bookmarksForm\"\n #bookmarksForm=\"ngForm\"\n >\n <div class=\"input-group input-group-editable\">\n <input\n class=\"form-control fit-w\"\n title=\"{{ bookmark.label }}\"\n id=\"label\"\n name=\"label\"\n type=\"text\"\n [(ngModel)]=\"bookmark.label\"\n #label=\"ngModel\"\n maxlength=\"50\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n />\n <span></span>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n (click)=\"updateBookmark(bookmark, 'label'); label.control.markAsPristine()\"\n [disabled]=\"label.invalid\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n </c8y-list-group>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n</ng-template>\n","import { AsyncPipe } from '@angular/common';\nimport { Component, Inject, DOCUMENT as Document } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AlertService, HeaderService, IconDirective, C8yTranslatePipe } from '@c8y/ngx-components';\nimport { cloneDeep } from 'lodash-es';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { Observable } from 'rxjs';\nimport { Bookmark } from './bookmark.model';\nimport { BookmarkService } from './bookmarks.service';\nimport { EditBookmarksComponent } from './edit-bookmarks/edit-bookmarks.component';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\n\n@Component({\n selector: 'c8y-bookmarks',\n templateUrl: './bookmarks.component.html',\n imports: [IconDirective, TooltipDirective, C8yTranslatePipe, AsyncPipe]\n})\nexport class BookmarksComponent {\n drawerOpen$: Observable<boolean>;\n bookmarks: Bookmark[] = [];\n emptyMessageHeader = gettext('No bookmarks yet');\n emptyMessageBody = gettext(\n 'Navigate to the desired page and click the \"Add current page\" button. Editing, deleting and reordering are possible by clicking on the cog wheel.'\n );\n addButtonText = gettext('Add current page');\n\n constructor(\n @Inject(Document) private document: Document,\n private alertService: AlertService,\n private bookmarkService: BookmarkService,\n private bsModalService: BsModalService,\n private router: Router,\n private headerService: HeaderService\n ) {\n this.drawerOpen$ = this.headerService.rightDrawerOpen$;\n }\n\n async ngOnInit(): Promise<void> {\n this.bookmarks = await this.bookmarkService.getBookmarks();\n }\n\n async addBookmark(): Promise<void> {\n const currentUrl = this.getRelativeUrl();\n if (this.bookmarks.some(bookmark => this.toRelativeUrl(bookmark.url) === currentUrl)) {\n this.alertService.warning(gettext('Bookmark with the same URL is already added.'));\n return;\n }\n const icon = await this.bookmarkService.getActiveNodeIcon();\n const linkObject = this.bookmarkService.convertBookmarkLinkToObject(\n this.document.title,\n currentUrl,\n icon\n );\n this.bookmarks.push(linkObject);\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarks);\n this.alertService.success(gettext('Bookmark added.'));\n }\n\n async editBookmarks(): Promise<void> {\n try {\n const initialState: Pick<EditBookmarksComponent, 'bookmarks'> = {\n bookmarks: cloneDeep(this.bookmarks)\n };\n const modalRef = this.bsModalService.show(EditBookmarksComponent, {\n class: 'modal-md',\n ariaDescribedby: 'modal-body',\n ariaLabelledBy: 'modal-title',\n initialState: initialState,\n ignoreBackdropClick: true\n }).content as EditBookmarksComponent;\n this.bookmarks = await modalRef.result;\n } catch {\n return;\n }\n }\n\n openUrl(url: string): void {\n if (this.isRelativeUrl(url)) {\n if (this.isSameApp(url)) {\n const hash = url.includes('#') ? url.substring(url.indexOf('#') + 1) : '/';\n this.router.navigateByUrl(hash);\n } else {\n window.open(`${this.document.location.origin}${url}`, '_self');\n }\n return;\n }\n\n // Legacy support for absolute URLs stored before the relative URL migration\n const parsedUrl = new URL(url);\n const relativePath = `${parsedUrl.pathname}${parsedUrl.hash}`;\n\n if (this.isSameApp(relativePath)) {\n const hash = parsedUrl.hash ? parsedUrl.hash.substring(1) : '/';\n this.router.navigateByUrl(hash);\n } else {\n window.open(`${this.document.location.origin}${relativePath}`, '_self');\n }\n }\n\n private getRelativeUrl(): string {\n const { pathname, hash } = this.document.location;\n return `${pathname}${hash}`;\n }\n\n private isRelativeUrl(url: string): boolean {\n return url.startsWith('/');\n }\n\n private isSameApp(url: string): boolean {\n return url.startsWith(this.document.location.pathname);\n }\n\n private toRelativeUrl(url: string): string {\n if (this.isRelativeUrl(url)) {\n return url;\n }\n try {\n const parsed = new URL(url);\n return `${parsed.pathname}${parsed.hash}`;\n } catch {\n return url;\n }\n }\n}\n","<div class=\"separator-top p-t-8 m-t-auto c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Bookmarks' | translate }}</span>\n <button\n class=\"btn-dot m-l-auto\"\n [attr.aria-label]=\"'Edit bookmarks' | translate\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n tooltip=\"{{ 'Edit bookmarks' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n (click)=\"editBookmarks()\"\n >\n <i\n class=\"text-14 m-0\"\n c8yIcon=\"cog\"\n ></i>\n </button>\n</div>\n@if (bookmarks?.length) {\n <div class=\"c8y-right-drawer__item p-t-0 p-b-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n}\n@if (bookmarks?.length) {\n @for (bookmark of bookmarks; track bookmark.url) {\n <button\n class=\"c8y-right-drawer__link\"\n title=\"{{ bookmark.label }}\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"openUrl(bookmark.url)\"\n >\n @if (bookmark.icon) {\n <i [c8yIcon]=\"bookmark.icon\"></i>\n }\n <span class=\"text-truncate\">{{ bookmark.label }}</span>\n </button>\n }\n}\n\n<div class=\"p-t-8 p-b-8\">\n @if (!bookmarks?.length) {\n <span class=\"c8y-right-drawer__item text-muted text-bold text-14 p-b-0\">\n {{ emptyMessageHeader | translate }}\n </span>\n <span class=\"c8y-right-drawer__item text-12 p-t-0\">\n <span class=\"text-muted\">{{ emptyMessageBody | translate }}</span>\n </span>\n <div class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n }\n</div>\n","import { DragDropModule } from '@angular/cdk/drag-drop';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport {\n ChangeIconComponent,\n CommonModule,\n CoreModule,\n FormsModule as c8yFormsModule,\n hookDrawer,\n ListGroupModule,\n ModalModule\n} from '@c8y/ngx-components';\nimport { BookmarksComponent } from './bookmarks.component';\nimport { EditBookmarksComponent } from './edit-bookmarks/edit-bookmarks.component';\n\n@NgModule({\n imports: [\n CoreModule,\n CommonModule,\n ListGroupModule,\n DragDropModule,\n FormsModule,\n c8yFormsModule,\n ModalModule,\n TooltipModule.forRoot(),\n ChangeIconComponent,\n BookmarksComponent,\n EditBookmarksComponent\n ],\n exports: [BookmarksComponent],\n providers: [\n hookDrawer({\n component: BookmarksComponent,\n position: 'right',\n priority: 50,\n id: 'bookmarks'\n })\n ]\n})\nexport class BookmarksModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3.BookmarkService","Document","i2.BookmarkService","i3","i4","c8yFormsModule"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-bookmarks.mjs","sources":["../../bookmarks/bookmarks.service.ts","../../bookmarks/edit-bookmarks/edit-bookmarks.component.ts","../../bookmarks/edit-bookmarks/edit-bookmarks.component.html","../../bookmarks/bookmarks.component.ts","../../bookmarks/bookmarks.component.html","../../bookmarks/bookmarks.module.ts","../../bookmarks/c8y-ngx-components-bookmarks.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { Router } from '@angular/router';\nimport {\n NavigatorNode,\n NavigatorService,\n OptionsService,\n UserPreferencesService\n} from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { TranslateService } from '@ngx-translate/core';\nimport { uniqBy } from 'lodash-es';\nimport { firstValueFrom, map } from 'rxjs';\nimport { Bookmark } from './bookmark.model';\n\n@Injectable({ providedIn: 'root' })\nexport class BookmarkService {\n private static readonly DEFAULT_ICON = 'bookmark';\n\n readonly USER_PREFERENCES_BOOKMARKS_KEY = 'bookmarks';\n\n updatedBookmarks: Bookmark[];\n\n constructor(\n private navigatorService: NavigatorService,\n private options: OptionsService,\n private router: Router,\n private translateService: TranslateService,\n private userPreferencesService: UserPreferencesService\n ) {}\n\n async updateBookmarksInStorage(newBookmarks: Bookmark[]): Promise<void> {\n const existingBookmarks = await this.getBookmarks();\n const mergedBookmarks = [...newBookmarks, ...existingBookmarks];\n const cleanedBookmarks = uniqBy(mergedBookmarks, 'id').filter(\n (bookmark: Bookmark) => !bookmark.markToRemove\n );\n\n this.setUserPreferencesBookmarks(cleanedBookmarks);\n }\n\n async getActiveNodeIcon(): Promise<string> {\n const activeNode = await this.findActiveNode();\n return activeNode?.icon || BookmarkService.DEFAULT_ICON;\n }\n\n extractIconName(input: string): string | null {\n const iconRegex = /\\b(dlt-)?c8y-icon-(\\w+(?:-\\w+)*)\\b/g;\n const matches = [...input.matchAll(iconRegex)];\n const match = matches?.pop();\n\n if (!match) {\n return null;\n }\n const [, prefix, name] = match;\n\n return prefix ? name : `c8y-${name}`;\n }\n\n async getBookmarks(): Promise<Bookmark[]> {\n return await firstValueFrom(\n this.userPreferencesService\n .get(this.USER_PREFERENCES_BOOKMARKS_KEY)\n .pipe(map((bookmarks: Bookmark[]) => bookmarks ?? []))\n );\n }\n\n generateRandomID() {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n\n return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');\n }\n\n convertBookmarkLinkToObject(title: string, url: string, icon: string): Bookmark {\n const globalTitle = this.options.globalTitle ?? 'Cumulocity';\n return {\n id: this.generateRandomID(),\n label: title.includes(globalTitle)\n ? title.replace(`${globalTitle} - `, '')\n : this.translateService.instant(gettext('Bookmark')),\n url,\n icon\n };\n }\n\n private async findActiveNode(): Promise<NavigatorNode | undefined> {\n const nodes = await firstValueFrom(this.navigatorService.items$);\n return this.findActiveInTree(nodes);\n }\n\n private findActiveInTree(nodes: NavigatorNode[]): NavigatorNode | undefined {\n let result: NavigatorNode | undefined;\n\n for (const node of nodes) {\n if (node.path && this.isNodeActive(node)) {\n result = node;\n }\n if (node.children?.length) {\n const childMatch = this.findActiveInTree(node.children);\n if (childMatch) {\n result = childMatch;\n }\n }\n }\n\n return result;\n }\n\n private isNodeActive(node: NavigatorNode): boolean {\n return this.router.isActive(node.path, {\n paths: node.routerLinkExact ? 'exact' : 'subset',\n queryParams: 'ignored',\n fragment: 'ignored',\n matrixParams: 'ignored'\n });\n }\n\n private setUserPreferencesBookmarks(bookmarks: Bookmark[]): void {\n this.userPreferencesService.set(this.USER_PREFERENCES_BOOKMARKS_KEY, bookmarks);\n this.updatedBookmarks = bookmarks;\n }\n}\n","import {\n CdkDragDrop,\n moveItemInArray,\n CdkDropList,\n CdkDrag,\n CdkDragHandle\n} from '@angular/cdk/drag-drop';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n Input,\n OnInit,\n inject\n} from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n AlertService,\n InputGroupEditableComponent,\n PopoverConfirmButtons,\n PopoverConfirmComponent,\n IconDirective,\n C8yTranslateDirective,\n ListGroupComponent,\n ListItemComponent,\n ListItemDragHandleComponent,\n ListItemIconComponent,\n ChangeIconComponent,\n EmptyStateComponent,\n C8yTranslatePipe\n} from '@c8y/ngx-components';\nimport { IconSelectorService } from '@c8y/ngx-components/icon-selector';\nimport { cloneDeep } from 'lodash-es';\nimport { BsModalRef } from 'ngx-bootstrap/modal';\nimport { Bookmark } from '../bookmark.model';\nimport { BookmarkService } from '../bookmarks.service';\nimport { FormsModule } from '@angular/forms';\n\n@Component({\n selector: 'c8y-edit-bookmarks',\n templateUrl: './edit-bookmarks.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '(document:keydown)': 'handleKeyboardEvent($event)'\n },\n imports: [\n IconDirective,\n C8yTranslateDirective,\n ListGroupComponent,\n CdkDropList,\n ListItemComponent,\n CdkDrag,\n ListItemDragHandleComponent,\n CdkDragHandle,\n ListItemIconComponent,\n ChangeIconComponent,\n FormsModule,\n InputGroupEditableComponent,\n PopoverConfirmComponent,\n EmptyStateComponent,\n C8yTranslatePipe\n ]\n})\nexport class EditBookmarksComponent implements OnInit {\n // @Input is intentional: this component is opened via BsModalService with initialState,\n // which sets the property directly on the instance and is incompatible with signal inputs.\n @Input()\n bookmarks: Bookmark[] = [];\n private bookmarksToUpdate: Bookmark[] = [];\n\n confirmRemoveColumnButtons: PopoverConfirmButtons[] = [\n {\n label: gettext('Cancel'),\n action: () => Promise.resolve(false)\n },\n {\n label: gettext('Delete'),\n status: 'danger',\n action: () => Promise.resolve(true)\n }\n ];\n\n result: Promise<Bookmark[]> = new Promise(resolve => {\n this._close = resolve;\n });\n\n private _close: (value: Bookmark[]) => void;\n\n private readonly bsModalRef = inject(BsModalRef);\n private readonly alertService = inject(AlertService);\n private readonly bookmarkService = inject(BookmarkService);\n private readonly iconSelector = inject(IconSelectorService);\n private readonly cdr = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n this.bookmarksToUpdate = cloneDeep(this.bookmarks);\n }\n\n handleKeyboardEvent(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n this.close();\n }\n }\n\n close(): void {\n if (this.bookmarkService.updatedBookmarks) {\n this._close(this.bookmarkService.updatedBookmarks);\n }\n this.bsModalRef.hide();\n }\n\n async drop(event: CdkDragDrop<Bookmark[]>): Promise<void> {\n try {\n moveItemInArray(this.bookmarks, event.previousIndex, event.currentIndex);\n moveItemInArray(this.bookmarksToUpdate, event.previousIndex, event.currentIndex);\n\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);\n this.alertService.success(gettext('Bookmarks order updated.'));\n } catch {\n this.alertService.success(gettext('Bookmarks order failed to update.'));\n }\n }\n\n async updateBookmark(\n updatedBookmark: Bookmark,\n type: keyof Pick<Bookmark, 'icon' | 'label' | 'markToRemove'>\n ): Promise<void> {\n try {\n this.bookmarksToUpdate = this.updateBookmarkProperty(updatedBookmark, type);\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarksToUpdate);\n if (type !== 'markToRemove') {\n this.alertService.success(gettext('Bookmark updated.'));\n }\n } catch {\n if (type !== 'markToRemove') {\n this.alertService.warning(gettext('Bookmark update failed'));\n }\n }\n }\n\n onLabelSaved(bookmark: Bookmark, label: string): void {\n bookmark.label = label;\n this.updateBookmark(bookmark, 'label');\n }\n\n updateBookmarkProperty(\n updatedBookmark: Bookmark,\n type: keyof Pick<Bookmark, 'icon' | 'label' | 'markToRemove'>\n ): Bookmark[] {\n const update = {\n icon: (bookmark: Bookmark) => ({ ...bookmark, icon: updatedBookmark.icon }),\n label: (bookmark: Bookmark) => ({ ...bookmark, label: updatedBookmark.label }),\n markToRemove: (bookmark: Bookmark) => ({ ...bookmark, markToRemove: true })\n }[type];\n\n return this.bookmarksToUpdate.map(bookmark =>\n bookmark.id === updatedBookmark.id ? update(bookmark) : bookmark\n );\n }\n\n async changeBookmarkIcon(updatedBookmark: Bookmark): Promise<void> {\n try {\n const newIcon = await this.iconSelector.selectIcon();\n updatedBookmark.icon = newIcon;\n await this.updateBookmark(updatedBookmark, 'icon');\n this.cdr.markForCheck();\n } catch {\n // nothing to do\n }\n }\n\n async removeBookmark(\n poConfirm: PopoverConfirmComponent,\n bookmarkToDelete: Bookmark\n ): Promise<void> {\n poConfirm.message = gettext('This action is irreversible.');\n\n try {\n const remove = await poConfirm.show(this.confirmRemoveColumnButtons);\n if (!remove) {\n return;\n }\n\n await this.updateBookmark(bookmarkToDelete, 'markToRemove');\n\n const bookmarkIndex = this.bookmarks.findIndex(\n bookmark => bookmark.id === bookmarkToDelete.id\n );\n\n if (bookmarkIndex === -1) {\n return;\n }\n\n this.bookmarks.splice(bookmarkIndex, 1);\n this.cdr.markForCheck();\n this.alertService.success(gettext('Bookmark removed.'));\n } catch (err) {\n /**\n * Prevents an alert message from being displayed if the user clicks outside of a popover.\n */\n if (err) {\n this.alertService.warning(gettext('Bookmarks deletion failed.'));\n }\n }\n }\n}\n","<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'bookmark'\"></i>\n <div\n class=\"h4\"\n id=\"modal-title\"\n translate\n >\n Bookmarks\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16 text-center separator-bottom sticky-top bg-component\">\n <p class=\"text-medium text-16\">\n {{ 'Reorder, edit or delete bookmarks.' | translate }}\n </p>\n </div>\n @if (bookmarks.length) {\n <c8y-list-group\n class=\"cdk-droplist no-border-last\"\n cdkDropList\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListDisabled]=\"bookmarks.length < 2\"\n >\n @for (bookmark of bookmarks; track bookmark.id) {\n <c8y-li cdkDrag>\n <c8y-li-drag-handle\n title=\"{{ 'Drag to reorder' | translate }}\"\n cdkDragHandle\n >\n <i c8yIcon=\"drag-reorder\"></i>\n </c8y-li-drag-handle>\n @if (bookmark.icon) {\n <c8y-li-icon\n class=\"a-s-stretch\"\n [style.padding-left]=\"bookmarks.length < 2 ? '16px !important' : null\"\n >\n <c8y-change-icon\n [currentIcon]=\"bookmark.icon\"\n (onButtonClick)=\"changeBookmarkIcon(bookmark)\"\n ></c8y-change-icon>\n </c8y-li-icon>\n }\n\n <div class=\"d-flex gap-8 a-i-center\">\n <div class=\"flex-grow\">\n <c8y-input-group-editable\n [ariaLabel]=\"'Bookmark label' | translate\"\n formGroupClass=\"m-b-0\"\n [placeholder]=\"'e.g. My bookmark' | translate\"\n [maxLength]=\"50\"\n [ngModel]=\"bookmark.label\"\n (ngModelChange)=\"onLabelSaved(bookmark, $event)\"\n ></c8y-input-group-editable>\n </div>\n <c8y-popover-confirm\n class=\"d-block\"\n [title]=\"'Delete bookmark' | translate\"\n [placement]=\"'left'\"\n [outsideClick]=\"true\"\n [adaptivePosition]=\"true\"\n [container]=\"''\"\n #poConfirm\n >\n <button\n class=\"btn btn-dot btn-dot--danger m-l-auto\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"removeBookmark(poConfirm, bookmark)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </c8y-popover-confirm>\n </div>\n </c8y-li>\n }\n </c8y-list-group>\n } @else {\n <c8y-ui-empty-state\n [icon]=\"'bookmark'\"\n [title]=\"'No bookmarks yet' | translate\"\n [subtitle]=\"\n 'Navigate to the desired page, open the right drawer and click the &quot;Add current page&quot; button.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n","import { AsyncPipe } from '@angular/common';\nimport { Component, Inject, DOCUMENT as Document } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AlertService, HeaderService, IconDirective, C8yTranslatePipe } from '@c8y/ngx-components';\nimport { cloneDeep } from 'lodash-es';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { Observable } from 'rxjs';\nimport { Bookmark } from './bookmark.model';\nimport { BookmarkService } from './bookmarks.service';\nimport { EditBookmarksComponent } from './edit-bookmarks/edit-bookmarks.component';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\n\n@Component({\n selector: 'c8y-bookmarks',\n templateUrl: './bookmarks.component.html',\n imports: [IconDirective, TooltipDirective, C8yTranslatePipe, AsyncPipe]\n})\nexport class BookmarksComponent {\n drawerOpen$: Observable<boolean>;\n bookmarks: Bookmark[] = [];\n emptyMessageHeader = gettext('No bookmarks yet');\n emptyMessageBody = gettext(\n 'Navigate to the desired page and click the \"Add current page\" button. Editing, deleting and reordering are possible by clicking on the cog wheel.'\n );\n addButtonText = gettext('Add current page');\n\n constructor(\n @Inject(Document) private document: Document,\n private alertService: AlertService,\n private bookmarkService: BookmarkService,\n private bsModalService: BsModalService,\n private router: Router,\n private headerService: HeaderService\n ) {\n this.drawerOpen$ = this.headerService.rightDrawerOpen$;\n }\n\n async ngOnInit(): Promise<void> {\n this.bookmarks = await this.bookmarkService.getBookmarks();\n }\n\n async addBookmark(): Promise<void> {\n const currentUrl = this.getRelativeUrl();\n if (this.bookmarks.some(bookmark => this.toRelativeUrl(bookmark.url) === currentUrl)) {\n this.alertService.warning(gettext('Bookmark with the same URL is already added.'));\n return;\n }\n const icon = await this.bookmarkService.getActiveNodeIcon();\n const linkObject = this.bookmarkService.convertBookmarkLinkToObject(\n this.document.title,\n currentUrl,\n icon\n );\n this.bookmarks.push(linkObject);\n await this.bookmarkService.updateBookmarksInStorage(this.bookmarks);\n this.alertService.success(gettext('Bookmark added.'));\n }\n\n async editBookmarks(): Promise<void> {\n try {\n const initialState: Pick<EditBookmarksComponent, 'bookmarks'> = {\n bookmarks: cloneDeep(this.bookmarks)\n };\n const modalRef = this.bsModalService.show(EditBookmarksComponent, {\n class: 'modal-md',\n ariaDescribedby: 'modal-body',\n ariaLabelledBy: 'modal-title',\n initialState: initialState,\n ignoreBackdropClick: true\n }).content as EditBookmarksComponent;\n this.bookmarks = await modalRef.result;\n } catch {\n return;\n }\n }\n\n openUrl(url: string): void {\n if (this.isRelativeUrl(url)) {\n if (this.isSameApp(url)) {\n const hash = url.includes('#') ? url.substring(url.indexOf('#') + 1) : '/';\n this.router.navigateByUrl(hash);\n } else {\n window.open(`${this.document.location.origin}${url}`, '_self');\n }\n return;\n }\n\n // Legacy support for absolute URLs stored before the relative URL migration\n const parsedUrl = new URL(url);\n const relativePath = `${parsedUrl.pathname}${parsedUrl.hash}`;\n\n if (this.isSameApp(relativePath)) {\n const hash = parsedUrl.hash ? parsedUrl.hash.substring(1) : '/';\n this.router.navigateByUrl(hash);\n } else {\n window.open(`${this.document.location.origin}${relativePath}`, '_self');\n }\n }\n\n private getRelativeUrl(): string {\n const { pathname, hash } = this.document.location;\n return `${pathname}${hash}`;\n }\n\n private isRelativeUrl(url: string): boolean {\n return url.startsWith('/');\n }\n\n private isSameApp(url: string): boolean {\n return url.startsWith(this.document.location.pathname);\n }\n\n private toRelativeUrl(url: string): string {\n if (this.isRelativeUrl(url)) {\n return url;\n }\n try {\n const parsed = new URL(url);\n return `${parsed.pathname}${parsed.hash}`;\n } catch {\n return url;\n }\n }\n}\n","<div class=\"separator-top p-t-8 m-t-auto c8y-right-drawer__item sticky-top\">\n <i c8yIcon=\"bookmark\"></i>\n <span class=\"text-bold\">{{ 'Bookmarks' | translate }}</span>\n <button\n class=\"btn-dot m-l-auto\"\n [attr.aria-label]=\"'Edit bookmarks' | translate\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n tooltip=\"{{ 'Edit bookmarks' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n (click)=\"editBookmarks()\"\n >\n <i\n class=\"text-14 m-0\"\n c8yIcon=\"cog\"\n ></i>\n </button>\n</div>\n@if (bookmarks?.length) {\n <div class=\"c8y-right-drawer__item p-t-0 p-b-8\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n}\n@if (bookmarks?.length) {\n @for (bookmark of bookmarks; track bookmark.url) {\n <button\n class=\"c8y-right-drawer__link\"\n title=\"{{ bookmark.label }}\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"openUrl(bookmark.url)\"\n >\n @if (bookmark.icon) {\n <i [c8yIcon]=\"bookmark.icon\"></i>\n }\n <span class=\"text-truncate\">{{ bookmark.label }}</span>\n </button>\n }\n}\n\n<div class=\"p-t-8 p-b-8\">\n @if (!bookmarks?.length) {\n <span class=\"c8y-right-drawer__item text-muted text-bold text-14 p-b-0\">\n {{ emptyMessageHeader | translate }}\n </span>\n <span class=\"c8y-right-drawer__item text-12 p-t-0\">\n <span class=\"text-muted\">{{ emptyMessageBody | translate }}</span>\n </span>\n <div class=\"c8y-right-drawer__item\">\n <button\n class=\"btn btn-default btn-sm\"\n [tabindex]=\"(drawerOpen$ | async) ? '0' : '-1'\"\n type=\"button\"\n (click)=\"addBookmark()\"\n >\n <i\n class=\"m-t-0 m-b-0 text-14\"\n c8yIcon=\"plus-circle-o\"\n ></i>\n <span>{{ addButtonText | translate }}</span>\n </button>\n </div>\n }\n</div>\n","import { DragDropModule } from '@angular/cdk/drag-drop';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport {\n ChangeIconComponent,\n CommonModule,\n CoreModule,\n FormsModule as c8yFormsModule,\n hookDrawer,\n ListGroupModule,\n ModalModule\n} from '@c8y/ngx-components';\nimport { BookmarksComponent } from './bookmarks.component';\nimport { EditBookmarksComponent } from './edit-bookmarks/edit-bookmarks.component';\n\n@NgModule({\n imports: [\n CoreModule,\n CommonModule,\n ListGroupModule,\n DragDropModule,\n FormsModule,\n c8yFormsModule,\n ModalModule,\n TooltipModule.forRoot(),\n ChangeIconComponent,\n BookmarksComponent,\n EditBookmarksComponent\n ],\n exports: [BookmarksComponent],\n providers: [\n hookDrawer({\n component: BookmarksComponent,\n position: 'right',\n priority: 50,\n id: 'bookmarks'\n })\n ]\n})\nexport class BookmarksModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","Document","i2.BookmarkService","i3","i4","c8yFormsModule"],"mappings":";;;;;;;;;;;;;;;;;;;MAea,eAAe,CAAA;aACF,IAAA,CAAA,YAAY,GAAG,UAAH,CAAc;IAMlD,WAAA,CACU,gBAAkC,EAClC,OAAuB,EACvB,MAAc,EACd,gBAAkC,EAClC,sBAA8C,EAAA;QAJ9C,IAAA,CAAA,gBAAgB,GAAhB,gBAAgB;QAChB,IAAA,CAAA,OAAO,GAAP,OAAO;QACP,IAAA,CAAA,MAAM,GAAN,MAAM;QACN,IAAA,CAAA,gBAAgB,GAAhB,gBAAgB;QAChB,IAAA,CAAA,sBAAsB,GAAtB,sBAAsB;QATvB,IAAA,CAAA,8BAA8B,GAAG,WAAW;IAUlD;IAEH,MAAM,wBAAwB,CAAC,YAAwB,EAAA;AACrD,QAAA,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE;QACnD,MAAM,eAAe,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,iBAAiB,CAAC;QAC/D,MAAM,gBAAgB,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,MAAM,CAC3D,CAAC,QAAkB,KAAK,CAAC,QAAQ,CAAC,YAAY,CAC/C;AAED,QAAA,IAAI,CAAC,2BAA2B,CAAC,gBAAgB,CAAC;IACpD;AAEA,IAAA,MAAM,iBAAiB,GAAA;AACrB,QAAA,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE;AAC9C,QAAA,OAAO,UAAU,EAAE,IAAI,IAAI,eAAe,CAAC,YAAY;IACzD;AAEA,IAAA,eAAe,CAAC,KAAa,EAAA;QAC3B,MAAM,SAAS,GAAG,qCAAqC;QACvD,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC9C,QAAA,MAAM,KAAK,GAAG,OAAO,EAAE,GAAG,EAAE;QAE5B,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,IAAI;QACb;QACA,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK;QAE9B,OAAO,MAAM,GAAG,IAAI,GAAG,CAAA,IAAA,EAAO,IAAI,CAAA,CAAE;IACtC;AAEA,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,MAAM,cAAc,CACzB,IAAI,CAAC;AACF,aAAA,GAAG,CAAC,IAAI,CAAC,8BAA8B;AACvC,aAAA,IAAI,CAAC,GAAG,CAAC,CAAC,SAAqB,KAAK,SAAS,IAAI,EAAE,CAAC,CAAC,CACzD;IACH;IAEA,gBAAgB,GAAA;AACd,QAAA,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC;AAChC,QAAA,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC;AAE7B,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/E;AAEA,IAAA,2BAA2B,CAAC,KAAa,EAAE,GAAW,EAAE,IAAY,EAAA;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY;QAC5D,OAAO;AACL,YAAA,EAAE,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAC3B,YAAA,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;kBAC7B,KAAK,CAAC,OAAO,CAAC,GAAG,WAAW,CAAA,GAAA,CAAK,EAAE,EAAE;kBACrC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACtD,GAAG;YACH;SACD;IACH;AAEQ,IAAA,MAAM,cAAc,GAAA;QAC1B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;AAChE,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;IACrC;AAEQ,IAAA,gBAAgB,CAAC,KAAsB,EAAA;AAC7C,QAAA,IAAI,MAAiC;AAErC,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;gBACxC,MAAM,GAAG,IAAI;YACf;AACA,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;gBACzB,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACvD,IAAI,UAAU,EAAE;oBACd,MAAM,GAAG,UAAU;gBACrB;YACF;QACF;AAEA,QAAA,OAAO,MAAM;IACf;AAEQ,IAAA,YAAY,CAAC,IAAmB,EAAA;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;YACrC,KAAK,EAAE,IAAI,CAAC,eAAe,GAAG,OAAO,GAAG,QAAQ;AAChD,YAAA,WAAW,EAAE,SAAS;AACtB,YAAA,QAAQ,EAAE,SAAS;AACnB,YAAA,YAAY,EAAE;AACf,SAAA,CAAC;IACJ;AAEQ,IAAA,2BAA2B,CAAC,SAAqB,EAAA;QACvD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,EAAE,SAAS,CAAC;AAC/E,QAAA,IAAI,CAAC,gBAAgB,GAAG,SAAS;IACnC;+GAzGW,eAAe,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,cAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,cADF,MAAM,EAAA,CAAA,CAAA;;4FACnB,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCiDrB,sBAAsB,CAAA;AAzBnC,IAAA,WAAA,GAAA;;;QA6BE,IAAA,CAAA,SAAS,GAAe,EAAE;QAClB,IAAA,CAAA,iBAAiB,GAAe,EAAE;AAE1C,QAAA,IAAA,CAAA,0BAA0B,GAA4B;AACpD,YAAA;AACE,gBAAA,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC;gBACxB,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK;AACpC,aAAA;AACD,YAAA;AACE,gBAAA,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC;AACxB,gBAAA,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI;AACnC;SACF;AAED,QAAA,IAAA,CAAA,MAAM,GAAwB,IAAI,OAAO,CAAC,OAAO,IAAG;AAClD,YAAA,IAAI,CAAC,MAAM,GAAG,OAAO;AACvB,QAAA,CAAC,CAAC;AAIe,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AACnC,QAAA,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;AACzC,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAiHjD,IAAA;IA/GC,QAAQ,GAAA;QACN,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;IACpD;AAEA,IAAA,mBAAmB,CAAC,KAAoB,EAAA;AACtC,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,KAAK,EAAE;QACd;IACF;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC;QACpD;AACA,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;IACxB;IAEA,MAAM,IAAI,CAAC,KAA8B,EAAA;AACvC,QAAA,IAAI;AACF,YAAA,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC;AACxE,YAAA,eAAe,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC;YAEhF,MAAM,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,IAAI,CAAC,iBAAiB,CAAC;YAC3E,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAChE;AAAE,QAAA,MAAM;YACN,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACzE;IACF;AAEA,IAAA,MAAM,cAAc,CAClB,eAAyB,EACzB,IAA6D,EAAA;AAE7D,QAAA,IAAI;YACF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,EAAE,IAAI,CAAC;YAC3E,MAAM,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC3E,YAAA,IAAI,IAAI,KAAK,cAAc,EAAE;gBAC3B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;YACzD;QACF;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,IAAI,KAAK,cAAc,EAAE;gBAC3B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;YAC9D;QACF;IACF;IAEA,YAAY,CAAC,QAAkB,EAAE,KAAa,EAAA;AAC5C,QAAA,QAAQ,CAAC,KAAK,GAAG,KAAK;AACtB,QAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC;IACxC;IAEA,sBAAsB,CACpB,eAAyB,EACzB,IAA6D,EAAA;AAE7D,QAAA,MAAM,MAAM,GAAG;AACb,YAAA,IAAI,EAAE,CAAC,QAAkB,MAAM,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC;AAC3E,YAAA,KAAK,EAAE,CAAC,QAAkB,MAAM,EAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,CAAC;AAC9E,YAAA,YAAY,EAAE,CAAC,QAAkB,MAAM,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE;SAC3E,CAAC,IAAI,CAAC;AAEP,QAAA,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,IACxC,QAAQ,CAAC,EAAE,KAAK,eAAe,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CACjE;IACH;IAEA,MAAM,kBAAkB,CAAC,eAAyB,EAAA;AAChD,QAAA,IAAI;YACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE;AACpD,YAAA,eAAe,CAAC,IAAI,GAAG,OAAO;YAC9B,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC;AAClD,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;QACzB;AAAE,QAAA,MAAM;;QAER;IACF;AAEA,IAAA,MAAM,cAAc,CAClB,SAAkC,EAClC,gBAA0B,EAAA;AAE1B,QAAA,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,8BAA8B,CAAC;AAE3D,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC;YACpE,IAAI,CAAC,MAAM,EAAE;gBACX;YACF;YAEA,MAAM,IAAI,CAAC,cAAc,CAAC,gBAAgB,EAAE,cAAc,CAAC;YAE3D,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAC5C,QAAQ,IAAI,QAAQ,CAAC,EAAE,KAAK,gBAAgB,CAAC,EAAE,CAChD;AAED,YAAA,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;gBACxB;YACF;YAEA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;AACvC,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;YACvB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACzD;QAAE,OAAO,GAAG,EAAE;AACZ;;AAEG;YACH,IAAI,GAAG,EAAE;gBACP,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;YAClE;QACF;IACF;+GA7IW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,kBAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC/DnC,g4GAuGA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDzDI,aAAa,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,qBAAqB,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,WAAW,EAAA,QAAA,EAAA,8BAAA,EAAA,MAAA,EAAA,CAAA,wBAAA,EAAA,iBAAA,EAAA,wBAAA,EAAA,IAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,4BAAA,EAAA,2BAAA,EAAA,0BAAA,EAAA,+BAAA,EAAA,2BAAA,EAAA,6BAAA,EAAA,sBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,oBAAA,EAAA,oBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,iBAAiB,uLACjB,OAAO,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,yBAAA,EAAA,iBAAA,EAAA,0BAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,cAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,2BAA2B,EAAA,QAAA,EAAA,+CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC3B,aAAa,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,qBAAqB,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,mBAAmB,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACnB,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,2BAA2B,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,MAAA,EAAA,aAAA,EAAA,WAAA,EAAA,WAAA,EAAA,WAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC3B,uBAAuB,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,SAAA,EAAA,OAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,WAAA,EAAA,cAAA,EAAA,kBAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACvB,mBAAmB,+GACnB,gBAAgB,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGP,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAzBlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,EAAA,eAAA,EAEb,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,oBAAoB,EAAE;qBACvB,EAAA,OAAA,EACQ;wBACP,aAAa;wBACb,qBAAqB;wBACrB,kBAAkB;wBAClB,WAAW;wBACX,iBAAiB;wBACjB,OAAO;wBACP,2BAA2B;wBAC3B,aAAa;wBACb,qBAAqB;wBACrB,mBAAmB;wBACnB,WAAW;wBACX,2BAA2B;wBAC3B,uBAAuB;wBACvB,mBAAmB;wBACnB;AACD,qBAAA,EAAA,QAAA,EAAA,g4GAAA,EAAA;;sBAKA;;;MEhDU,kBAAkB,CAAA;IAS7B,WAAA,CAC4B,QAAkB,EACpC,YAA0B,EAC1B,eAAgC,EAChC,cAA8B,EAC9B,MAAc,EACd,aAA4B,EAAA;QALV,IAAA,CAAA,QAAQ,GAAR,QAAQ;QAC1B,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,eAAe,GAAf,eAAe;QACf,IAAA,CAAA,cAAc,GAAd,cAAc;QACd,IAAA,CAAA,MAAM,GAAN,MAAM;QACN,IAAA,CAAA,aAAa,GAAb,aAAa;QAbvB,IAAA,CAAA,SAAS,GAAe,EAAE;AAC1B,QAAA,IAAA,CAAA,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;AAChD,QAAA,IAAA,CAAA,gBAAgB,GAAG,OAAO,CACxB,mJAAmJ,CACpJ;AACD,QAAA,IAAA,CAAA,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAUzC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB;IACxD;AAEA,IAAA,MAAM,QAAQ,GAAA;QACZ,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE;IAC5D;AAEA,IAAA,MAAM,WAAW,GAAA;AACf,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE;QACxC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,EAAE;YACpF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;YAClF;QACF;QACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE;AAC3D,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,2BAA2B,CACjE,IAAI,CAAC,QAAQ,CAAC,KAAK,EACnB,UAAU,EACV,IAAI,CACL;AACD,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;QAC/B,MAAM,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC;QACnE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACvD;AAEA,IAAA,MAAM,aAAa,GAAA;AACjB,QAAA,IAAI;AACF,YAAA,MAAM,YAAY,GAA8C;AAC9D,gBAAA,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS;aACpC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,sBAAsB,EAAE;AAChE,gBAAA,KAAK,EAAE,UAAU;AACjB,gBAAA,eAAe,EAAE,YAAY;AAC7B,gBAAA,cAAc,EAAE,aAAa;AAC7B,gBAAA,YAAY,EAAE,YAAY;AAC1B,gBAAA,mBAAmB,EAAE;aACtB,CAAC,CAAC,OAAiC;AACpC,YAAA,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM;QACxC;AAAE,QAAA,MAAM;YACN;QACF;IACF;AAEA,IAAA,OAAO,CAAC,GAAW,EAAA;AACjB,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;AAC3B,YAAA,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;AACvB,gBAAA,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG;AAC1E,gBAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YACjC;iBAAO;AACL,gBAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAA,EAAG,GAAG,EAAE,EAAE,OAAO,CAAC;YAChE;YACA;QACF;;AAGA,QAAA,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC;QAC9B,MAAM,YAAY,GAAG,CAAA,EAAG,SAAS,CAAC,QAAQ,CAAA,EAAG,SAAS,CAAC,IAAI,CAAA,CAAE;AAE7D,QAAA,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE;YAChC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG;AAC/D,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QACjC;aAAO;AACL,YAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAA,EAAG,YAAY,EAAE,EAAE,OAAO,CAAC;QACzE;IACF;IAEQ,cAAc,GAAA;QACpB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ;AACjD,QAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAI,EAAE;IAC7B;AAEQ,IAAA,aAAa,CAAC,GAAW,EAAA;AAC/B,QAAA,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;IAC5B;AAEQ,IAAA,SAAS,CAAC,GAAW,EAAA;AAC3B,QAAA,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACxD;AAEQ,IAAA,aAAa,CAAC,GAAW,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;AAC3B,YAAA,OAAO,GAAG;QACZ;AACA,QAAA,IAAI;AACF,YAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC;YAC3B,OAAO,CAAA,EAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAA,CAAE;QAC3C;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,GAAG;QACZ;IACF;AAzGW,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,kBAUnBC,QAAQ,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,eAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,cAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,EAAA,CAAA,MAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAVP,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClB/B,8wEA8EA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED9DY,aAAa,2EAAE,gBAAgB,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,YAAA,EAAA,OAAA,EAAA,aAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,eAAA,EAAA,qBAAA,EAAA,kBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,EAAA,SAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,SAAS,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAE3D,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAL9B,SAAS;+BACE,eAAe,EAAA,OAAA,EAEhB,CAAC,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAA,QAAA,EAAA,8wEAAA,EAAA;;0BAYpE,MAAM;2BAACH,QAAQ;;;MEYP,eAAe,CAAA;+GAAf,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,YAtBxB,UAAU;YACV,YAAY;YACZ,eAAe;YACf,cAAc;YACd,WAAW;YACXI,aAAc;AACd,YAAA,WAAW,sBAEX,mBAAmB;YACnB,kBAAkB;AAClB,YAAA,sBAAsB,aAEd,kBAAkB,CAAA,EAAA,CAAA,CAAA;AAUjB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,EAAA,SAAA,EATf;AACT,YAAA,UAAU,CAAC;AACT,gBAAA,SAAS,EAAE,kBAAkB;AAC7B,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,QAAQ,EAAE,EAAE;AACZ,gBAAA,EAAE,EAAE;aACL;AACF,SAAA,EAAA,OAAA,EAAA,CApBC,UAAU;YACV,YAAY;YACZ,eAAe;YACf,cAAc;YACd,WAAW;YACXA,aAAc;YACd,WAAW;YACX,aAAa,CAAC,OAAO,EAAE;YACvB,mBAAmB;YAEnB,sBAAsB,CAAA,EAAA,CAAA,CAAA;;4FAYb,eAAe,EAAA,UAAA,EAAA,CAAA;kBAxB3B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,OAAO,EAAE;wBACP,UAAU;wBACV,YAAY;wBACZ,eAAe;wBACf,cAAc;wBACd,WAAW;wBACXA,aAAc;wBACd,WAAW;wBACX,aAAa,CAAC,OAAO,EAAE;wBACvB,mBAAmB;wBACnB,kBAAkB;wBAClB;AACD,qBAAA;oBACD,OAAO,EAAE,CAAC,kBAAkB,CAAC;AAC7B,oBAAA,SAAS,EAAE;AACT,wBAAA,UAAU,CAAC;AACT,4BAAA,SAAS,EAAE,kBAAkB;AAC7B,4BAAA,QAAQ,EAAE,OAAO;AACjB,4BAAA,QAAQ,EAAE,EAAE;AACZ,4BAAA,EAAE,EAAE;yBACL;AACF;AACF,iBAAA;;;ACvCD;;AAEG;;;;"}
@@ -1627,7 +1627,7 @@ class DashboardDetailComponent {
1627
1627
  this.tabs = this.dashboardDetailService.getTabs();
1628
1628
  }
1629
1629
  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" }] }); }
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 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
1631
  }
1632
1632
  __decorate([
1633
1633
  memoize(),
@@ -1637,7 +1637,7 @@ __decorate([
1637
1637
  ], DashboardDetailComponent.prototype, "convertStringToHash", null);
1638
1638
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DashboardDetailComponent, decorators: [{
1639
1639
  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" }]
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 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
1641
  }], 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
1642
  type: Input
1643
1643
  }], deviceType: [{