@c8y/ngx-components 1023.53.0 → 1023.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/alarms/index.d.ts +2 -1
  2. package/alarms/index.d.ts.map +1 -1
  3. package/application-access/list/index.d.ts +36 -0
  4. package/application-access/list/index.d.ts.map +1 -0
  5. package/application-access/user/application-access-user-details-wrapper/index.d.ts +33 -0
  6. package/application-access/user/application-access-user-details-wrapper/index.d.ts.map +1 -0
  7. package/application-access/user/index.d.ts +6 -0
  8. package/application-access/user/index.d.ts.map +1 -0
  9. package/asset-properties/index.d.ts +1 -1
  10. package/context-dashboard/index.d.ts +1 -1
  11. package/context-dashboard/index.d.ts.map +1 -1
  12. package/datapoints-export-selector/index.d.ts +2 -2
  13. package/device-enrolment/index.d.ts +6 -0
  14. package/device-enrolment/index.d.ts.map +1 -0
  15. package/device-enrolment/modal/index.d.ts +88 -0
  16. package/device-enrolment/modal/index.d.ts.map +1 -0
  17. package/device-grid/index.d.ts +1 -1
  18. package/device-list/index.d.ts +1 -1
  19. package/device-shell/index.d.ts +1 -1
  20. package/echart/index.d.ts +1 -1
  21. package/echart/models/index.d.ts +2 -2
  22. package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs +1 -1
  23. package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs +1 -1
  24. package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
  25. package/fesm2022/c8y-ngx-components-application-access-list.mjs +180 -0
  26. package/fesm2022/c8y-ngx-components-application-access-list.mjs.map +1 -0
  27. package/fesm2022/c8y-ngx-components-application-access-user-application-access-user-details-wrapper.mjs +113 -0
  28. package/fesm2022/c8y-ngx-components-application-access-user-application-access-user-details-wrapper.mjs.map +1 -0
  29. package/fesm2022/c8y-ngx-components-application-access-user.mjs +20 -0
  30. package/fesm2022/c8y-ngx-components-application-access-user.mjs.map +1 -0
  31. package/fesm2022/c8y-ngx-components-branding-shared.mjs +1 -1
  32. package/fesm2022/c8y-ngx-components-child-devices.mjs +1 -1
  33. package/fesm2022/c8y-ngx-components-context-dashboard-asset-add.mjs +1 -1
  34. package/fesm2022/c8y-ngx-components-context-dashboard-device-add.mjs +1 -1
  35. package/fesm2022/c8y-ngx-components-context-dashboard-devicemanagement.mjs +1 -1
  36. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +4 -24
  37. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  38. package/fesm2022/{c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-D0C7SH6L.mjs → c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DvKsV_Fs.mjs} +14 -12
  39. package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DvKsV_Fs.mjs.map +1 -0
  40. package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab.mjs +2 -2
  41. package/fesm2022/c8y-ngx-components-datapoint-explorer-devicemanagement.mjs +1 -1
  42. package/fesm2022/c8y-ngx-components-datapoint-explorer.mjs +1 -1
  43. package/fesm2022/c8y-ngx-components-datapoint-library.mjs +1 -1
  44. package/fesm2022/c8y-ngx-components-device-enrolment-modal.mjs +570 -0
  45. package/fesm2022/c8y-ngx-components-device-enrolment-modal.mjs.map +1 -0
  46. package/fesm2022/c8y-ngx-components-device-enrolment.mjs +147 -0
  47. package/fesm2022/c8y-ngx-components-device-enrolment.mjs.map +1 -0
  48. package/fesm2022/c8y-ngx-components-ecosystem.mjs +2 -2
  49. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  50. package/fesm2022/c8y-ngx-components-exports.mjs +1 -1
  51. package/fesm2022/c8y-ngx-components-feature-toggles.mjs +1 -1
  52. package/fesm2022/c8y-ngx-components-register-device.mjs +1 -1
  53. package/fesm2022/c8y-ngx-components-remote-access-ssh.mjs +1 -1
  54. package/fesm2022/c8y-ngx-components-remote-access-telnet.mjs +1 -1
  55. package/fesm2022/c8y-ngx-components-remote-access-vnc.mjs +1 -1
  56. package/fesm2022/c8y-ngx-components-report-dashboard.mjs +1 -1
  57. package/fesm2022/c8y-ngx-components-repository-firmware.mjs +1 -1
  58. package/fesm2022/c8y-ngx-components-repository-shared.mjs +3 -5
  59. package/fesm2022/c8y-ngx-components-repository-shared.mjs.map +1 -1
  60. package/fesm2022/c8y-ngx-components-sub-assets.mjs +132 -55
  61. package/fesm2022/c8y-ngx-components-sub-assets.mjs.map +1 -1
  62. package/fesm2022/c8y-ngx-components-tenants.mjs +71 -32
  63. package/fesm2022/c8y-ngx-components-tenants.mjs.map +1 -1
  64. package/fesm2022/c8y-ngx-components-upgrade.mjs +7 -1
  65. package/fesm2022/c8y-ngx-components-upgrade.mjs.map +1 -1
  66. package/fesm2022/c8y-ngx-components-widgets-definitions-device-management-welcome.mjs +8 -7
  67. package/fesm2022/c8y-ngx-components-widgets-definitions-device-management-welcome.mjs.map +1 -1
  68. package/fesm2022/c8y-ngx-components-widgets-implementations-cockpit-welcome.mjs +4 -4
  69. package/fesm2022/c8y-ngx-components-widgets-implementations-cockpit-welcome.mjs.map +1 -1
  70. package/fesm2022/c8y-ngx-components-widgets-implementations-device-management-welcome.mjs +37 -86
  71. package/fesm2022/c8y-ngx-components-widgets-implementations-device-management-welcome.mjs.map +1 -1
  72. package/fesm2022/c8y-ngx-components-widgets-implementations-quick-links.mjs +1 -1
  73. package/fesm2022/c8y-ngx-components.mjs +454 -225
  74. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  75. package/index.d.ts +109 -39
  76. package/index.d.ts.map +1 -1
  77. package/locales/de.po +184 -13
  78. package/locales/es.po +183 -13
  79. package/locales/fr.po +183 -13
  80. package/locales/ja_JP.po +162 -13
  81. package/locales/ko.po +184 -13
  82. package/locales/locales.pot +166 -11
  83. package/locales/nl.po +183 -13
  84. package/locales/pl.po +183 -13
  85. package/locales/pt_BR.po +183 -13
  86. package/locales/zh_CN.po +184 -13
  87. package/locales/zh_TW.po +183 -13
  88. package/map/index.d.ts +1 -0
  89. package/map/index.d.ts.map +1 -1
  90. package/operations/bulk-operations-service/index.d.ts +1 -1
  91. package/package.json +1 -1
  92. package/protocol-opcua/mappings/index.d.ts +1 -1
  93. package/register-device/index.d.ts +1 -1
  94. package/remote-access/data/index.d.ts +1 -0
  95. package/remote-access/data/index.d.ts.map +1 -1
  96. package/repository/shared/index.d.ts.map +1 -1
  97. package/sub-assets/index.d.ts +9 -3
  98. package/sub-assets/index.d.ts.map +1 -1
  99. package/tenants/index.d.ts +1 -0
  100. package/tenants/index.d.ts.map +1 -1
  101. package/upgrade/index.d.ts.map +1 -1
  102. package/widgets/definitions/device-management-welcome/index.d.ts +9 -6
  103. package/widgets/definitions/device-management-welcome/index.d.ts.map +1 -1
  104. package/widgets/implementations/asset-table/index.d.ts +1 -1
  105. package/widgets/implementations/datapoints-table/index.d.ts +2 -2
  106. package/widgets/implementations/device-management-welcome/index.d.ts +9 -22
  107. package/widgets/implementations/device-management-welcome/index.d.ts.map +1 -1
  108. package/widgets/implementations/kpi/index.d.ts +1 -1
  109. package/widgets/implementations/quick-links/index.d.ts +13 -2
  110. package/widgets/implementations/quick-links/index.d.ts.map +1 -1
  111. package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-D0C7SH6L.mjs.map +0 -1
@@ -4258,7 +4258,7 @@ class AssetTypesRealtimeService {
4258
4258
  */
4259
4259
  getIcon$(type) {
4260
4260
  const assetType = this.getAssetTypeByName$(type);
4261
- return assetType.pipe(map(assetType => assetType?.c8y_IsAssetType?.icon?.name || this.DEFAULT_ASSET_ICON));
4261
+ return assetType.pipe(map(assetType => assetType?.icon?.name || assetType?.c8y_IsAssetType?.icon?.name || this.DEFAULT_ASSET_ICON));
4262
4262
  }
4263
4263
  /**
4264
4264
  * Refreshes the asset types cache
@@ -4276,8 +4276,12 @@ class AssetTypesRealtimeService {
4276
4276
  */
4277
4277
  async getAssetTypes() {
4278
4278
  const assetTypesCache = {};
4279
- const { data } = await this.inventory.list({
4280
- fragmentType: 'c8y_IsAssetType',
4279
+ const query = {
4280
+ __filter: {
4281
+ __or: [{ type: 'c8y_AssetDefinition' }, { __has: 'c8y_IsAssetType' }]
4282
+ }
4283
+ };
4284
+ const { data } = await this.inventory.listQuery(query, {
4281
4285
  withChildren: false,
4282
4286
  pageSize: 2000
4283
4287
  });
@@ -4376,8 +4380,8 @@ class GroupService {
4376
4380
  this.dataBrokerSourceFragmentInactive = `_${GroupFragment.dataBrokerSourceFragment}`;
4377
4381
  }
4378
4382
  /**
4379
- * Finds an icon based on the contents of a managed object.
4380
- * It takes into account factors such as type, and specific fragments.
4383
+ * Finds an icon based on the asset type; if none is found, it looks for an asset-specific icon,
4384
+ * and if that is also unavailable, it uses the default icon.
4381
4385
  * @param mo Managed object to be checked.
4382
4386
  * @param open Determines whether the method should return an alternative icon showing the open state.
4383
4387
  * @param fallbackIcon If no icon is found, this icon is returned.
@@ -4385,8 +4389,13 @@ class GroupService {
4385
4389
  */
4386
4390
  async getIcon(mo, open = false, fallbackIcon) {
4387
4391
  const genericMoType = this.determineMoType(mo);
4392
+ const defaultIcon = 'c8y-enterprise';
4388
4393
  if (genericMoType === 'asset') {
4389
- return await this.getAssetCustomIcon(mo.type);
4394
+ const icon = await this.getAssetCustomIcon(mo.type);
4395
+ if (icon === defaultIcon && mo.icon && mo.icon.name !== '') {
4396
+ return mo.icon.name;
4397
+ }
4398
+ return icon;
4390
4399
  }
4391
4400
  if (fallbackIcon && genericMoType === 'other') {
4392
4401
  return fallbackIcon;
@@ -15305,6 +15314,8 @@ class ConfirmModalComponent {
15305
15314
  constructor(modal) {
15306
15315
  this.modal = modal;
15307
15316
  this.status = Status.INFO;
15317
+ this.requireCodeVerification = false;
15318
+ this.confirmString = '';
15308
15319
  this._labels = {
15309
15320
  ok: 'OK',
15310
15321
  cancel: 'Cancel'
@@ -15315,6 +15326,9 @@ class ConfirmModalComponent {
15315
15326
  this.modal.hide();
15316
15327
  };
15317
15328
  this.close = () => {
15329
+ if (this.requireCodeVerification && !this.canConfirmWithCode()) {
15330
+ return;
15331
+ }
15318
15332
  resolve(isEmpty(this.confirmOptions)
15319
15333
  ? true
15320
15334
  : {
@@ -15325,6 +15339,11 @@ class ConfirmModalComponent {
15325
15339
  };
15326
15340
  });
15327
15341
  }
15342
+ ngOnInit() {
15343
+ if (this.requireCodeVerification) {
15344
+ this.code = this.generateRandomCode();
15345
+ }
15346
+ }
15328
15347
  get classIcon() {
15329
15348
  return `dlt-c8y-icon-${statusIcons[this.status]}`;
15330
15349
  }
@@ -15338,12 +15357,26 @@ class ConfirmModalComponent {
15338
15357
  const doc = new DOMParser().parseFromString(str, 'text/html');
15339
15358
  return Array.from(doc.body.childNodes).some(node => node.nodeType === Node.ELEMENT_NODE);
15340
15359
  }
15360
+ canConfirmWithCode() {
15361
+ return this.confirmString === this.code;
15362
+ }
15363
+ get isOkButtonDisabled() {
15364
+ if (this.requireCodeVerification) {
15365
+ return !this.canConfirmWithCode();
15366
+ }
15367
+ return false;
15368
+ }
15369
+ generateRandomCode() {
15370
+ // no l, I, 0, O chars to prevent confusion:
15371
+ const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefhijkmnoprstuvwxyz123456789';
15372
+ return Array.from({ length: 5 }, () => chars.charAt(Math.floor(Math.random() * chars.length))).join('');
15373
+ }
15341
15374
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ConfirmModalComponent, deps: [{ token: i1$7.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); }
15342
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ConfirmModalComponent, isStandalone: true, selector: "c8y-confirm-modal", inputs: { title: "title", body: "body", confirmOptions: "confirmOptions", status: "status", labels: "labels" }, ngImport: i0, template: "<div\n class=\"c8y-prompt alert\"\n [ngClass]=\"[classAlert]\"\n data-cy=\"prompt-alert\"\n>\n @if (title) {\n <h3 class=\"m-b-16 d-flex a-i-center\">\n <i\n class=\"dlt-c8y-icon\"\n [ngClass]=\"[classIcon]\"\n ></i>\n <span id=\"modal-title\">{{ title | translate }}</span>\n </h3>\n }\n <div id=\"modal-body\">\n @if (!isHtml(body)) {\n <p class=\"text-break-word m-b-16\">\n {{ body | translate }}\n </p>\n }\n @if (isHtml(body)) {\n <div\n class=\"text-break-word m-b-16\"\n [innerHTML]=\"body | translate\"\n ></div>\n }\n @for (co of confirmOptions | showIfFilter | async | keyvalue; track co) {\n <div class=\"c8y-checkbox plain m-b-8\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"co.value.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"co.value.checked\"\n (change)=\"co.value.checked = !co.value.checked\"\n [disabled]=\"confirmOptions[co.value.disabledByKey]?.checked\"\n />\n <span></span>\n <span>{{ co.value.text | translate }}</span>\n </label>\n </div>\n }\n <ng-content></ng-content>\n </div>\n <div class=\"alert-footer\">\n @if (labels.cancel !== null) {\n <button\n class=\"btn btn-default\"\n title=\"{{ labels.cancel | translate }}\"\n type=\"button\"\n (click)=\"dismiss()\"\n data-cy=\"c8y-confirm-modal--cancel\"\n >\n {{ labels.cancel | translate }}\n </button>\n }\n <button\n class=\"btn btn-primary m-t-xs-8\"\n title=\"{{ labels.ok | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n data-cy=\"c8y-confirm-modal--ok\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: ShowIfFilterPipe, name: "showIfFilter" }] }); }
15375
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ConfirmModalComponent, isStandalone: true, selector: "c8y-confirm-modal", inputs: { title: "title", body: "body", confirmOptions: "confirmOptions", status: "status", requireCodeVerification: "requireCodeVerification", labels: "labels" }, ngImport: i0, template: "<div\n class=\"c8y-prompt alert\"\n [ngClass]=\"[classAlert]\"\n data-cy=\"prompt-alert\"\n>\n @if (title) {\n <h3 class=\"m-b-16 d-flex a-i-center\">\n <i\n class=\"dlt-c8y-icon\"\n [ngClass]=\"[classIcon]\"\n ></i>\n <span id=\"modal-title\">{{ title | translate }}</span>\n </h3>\n }\n <div id=\"modal-body\">\n @if (!isHtml(body)) {\n <p class=\"text-break-word m-b-16\">\n {{ body | translate }}\n </p>\n }\n @if (isHtml(body)) {\n <div\n class=\"text-break-word m-b-16\"\n [innerHTML]=\"body | translate\"\n ></div>\n }\n @for (co of confirmOptions | showIfFilter | async | keyvalue; track co) {\n <div class=\"c8y-checkbox plain m-b-8\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"co.value.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"co.value.checked\"\n (change)=\"co.value.checked = !co.value.checked\"\n [disabled]=\"confirmOptions[co.value.disabledByKey]?.checked\"\n />\n <span></span>\n <span>{{ co.value.text | translate }}</span>\n </label>\n </div>\n }\n @if (requireCodeVerification) {\n <p class=\"text-break-word m-b-16\">\n <code>{{ code }}</code>\n </p>\n <form (submit)=\"$event.preventDefault()\">\n <div class=\"form-group\">\n <label for=\"confirmString\">\n {{ 'Confirm:' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"confirmString\"\n placeholder=\"{{ 'Type here' | translate }}\"\n name=\"confirmString\"\n type=\"text\"\n autocomplete=\"off\"\n [(ngModel)]=\"confirmString\"\n />\n </div>\n </form>\n }\n <ng-content></ng-content>\n </div>\n <div class=\"alert-footer\">\n @if (labels.cancel !== null) {\n <button\n class=\"btn btn-default\"\n title=\"{{ labels.cancel | translate }}\"\n type=\"button\"\n (click)=\"dismiss()\"\n data-cy=\"c8y-confirm-modal--cancel\"\n >\n {{ labels.cancel | translate }}\n </button>\n }\n <button\n class=\"btn btn-primary m-t-xs-8\"\n title=\"{{ labels.ok | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n data-cy=\"c8y-confirm-modal--ok\"\n [disabled]=\"isOkButtonDisabled\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$8.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: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: ShowIfFilterPipe, name: "showIfFilter" }] }); }
15343
15376
  }
15344
15377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ConfirmModalComponent, decorators: [{
15345
15378
  type: Component,
15346
- args: [{ selector: 'c8y-confirm-modal', standalone: true, imports: [NgClass, C8yTranslatePipe, AsyncPipe, KeyValuePipe, ShowIfFilterPipe], template: "<div\n class=\"c8y-prompt alert\"\n [ngClass]=\"[classAlert]\"\n data-cy=\"prompt-alert\"\n>\n @if (title) {\n <h3 class=\"m-b-16 d-flex a-i-center\">\n <i\n class=\"dlt-c8y-icon\"\n [ngClass]=\"[classIcon]\"\n ></i>\n <span id=\"modal-title\">{{ title | translate }}</span>\n </h3>\n }\n <div id=\"modal-body\">\n @if (!isHtml(body)) {\n <p class=\"text-break-word m-b-16\">\n {{ body | translate }}\n </p>\n }\n @if (isHtml(body)) {\n <div\n class=\"text-break-word m-b-16\"\n [innerHTML]=\"body | translate\"\n ></div>\n }\n @for (co of confirmOptions | showIfFilter | async | keyvalue; track co) {\n <div class=\"c8y-checkbox plain m-b-8\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"co.value.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"co.value.checked\"\n (change)=\"co.value.checked = !co.value.checked\"\n [disabled]=\"confirmOptions[co.value.disabledByKey]?.checked\"\n />\n <span></span>\n <span>{{ co.value.text | translate }}</span>\n </label>\n </div>\n }\n <ng-content></ng-content>\n </div>\n <div class=\"alert-footer\">\n @if (labels.cancel !== null) {\n <button\n class=\"btn btn-default\"\n title=\"{{ labels.cancel | translate }}\"\n type=\"button\"\n (click)=\"dismiss()\"\n data-cy=\"c8y-confirm-modal--cancel\"\n >\n {{ labels.cancel | translate }}\n </button>\n }\n <button\n class=\"btn btn-primary m-t-xs-8\"\n title=\"{{ labels.ok | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n data-cy=\"c8y-confirm-modal--ok\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n" }]
15379
+ args: [{ selector: 'c8y-confirm-modal', standalone: true, imports: [NgClass, C8yTranslatePipe, AsyncPipe, KeyValuePipe, ShowIfFilterPipe, FormsModule$1], template: "<div\n class=\"c8y-prompt alert\"\n [ngClass]=\"[classAlert]\"\n data-cy=\"prompt-alert\"\n>\n @if (title) {\n <h3 class=\"m-b-16 d-flex a-i-center\">\n <i\n class=\"dlt-c8y-icon\"\n [ngClass]=\"[classIcon]\"\n ></i>\n <span id=\"modal-title\">{{ title | translate }}</span>\n </h3>\n }\n <div id=\"modal-body\">\n @if (!isHtml(body)) {\n <p class=\"text-break-word m-b-16\">\n {{ body | translate }}\n </p>\n }\n @if (isHtml(body)) {\n <div\n class=\"text-break-word m-b-16\"\n [innerHTML]=\"body | translate\"\n ></div>\n }\n @for (co of confirmOptions | showIfFilter | async | keyvalue; track co) {\n <div class=\"c8y-checkbox plain m-b-8\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"co.value.text | translate\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"co.value.checked\"\n (change)=\"co.value.checked = !co.value.checked\"\n [disabled]=\"confirmOptions[co.value.disabledByKey]?.checked\"\n />\n <span></span>\n <span>{{ co.value.text | translate }}</span>\n </label>\n </div>\n }\n @if (requireCodeVerification) {\n <p class=\"text-break-word m-b-16\">\n <code>{{ code }}</code>\n </p>\n <form (submit)=\"$event.preventDefault()\">\n <div class=\"form-group\">\n <label for=\"confirmString\">\n {{ 'Confirm:' | translate }}\n </label>\n <input\n class=\"form-control\"\n id=\"confirmString\"\n placeholder=\"{{ 'Type here' | translate }}\"\n name=\"confirmString\"\n type=\"text\"\n autocomplete=\"off\"\n [(ngModel)]=\"confirmString\"\n />\n </div>\n </form>\n }\n <ng-content></ng-content>\n </div>\n <div class=\"alert-footer\">\n @if (labels.cancel !== null) {\n <button\n class=\"btn btn-default\"\n title=\"{{ labels.cancel | translate }}\"\n type=\"button\"\n (click)=\"dismiss()\"\n data-cy=\"c8y-confirm-modal--cancel\"\n >\n {{ labels.cancel | translate }}\n </button>\n }\n <button\n class=\"btn btn-primary m-t-xs-8\"\n title=\"{{ labels.ok | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n data-cy=\"c8y-confirm-modal--ok\"\n [disabled]=\"isOkButtonDisabled\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n" }]
15347
15380
  }], ctorParameters: () => [{ type: i1$7.BsModalRef }], propDecorators: { title: [{
15348
15381
  type: Input
15349
15382
  }], body: [{
@@ -15352,6 +15385,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
15352
15385
  type: Input
15353
15386
  }], status: [{
15354
15387
  type: Input
15388
+ }], requireCodeVerification: [{
15389
+ type: Input
15355
15390
  }], labels: [{
15356
15391
  type: Input
15357
15392
  }] } });
@@ -15389,7 +15424,7 @@ class CookieBannerPreferencesModalComponent {
15389
15424
  return this.cookieBannerService.getCookieDescription(cookieType);
15390
15425
  }
15391
15426
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CookieBannerPreferencesModalComponent, deps: [{ token: CookieBannerService }], target: i0.ɵɵFactoryTarget.Component }); }
15392
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CookieBannerPreferencesModalComponent, isStandalone: true, selector: "c8y-cookie-banner-preferences-modal", viewQueries: [{ propertyName: "modalRef", first: true, predicate: ["modalRef"], descendants: true }], ngImport: i0, template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n\n <div *ngFor=\"let item of configCookiePreferencesList\" class=\"row p-t-8 p-b-8 separator-top\">\n <div class=\"col-xs-2\">\n <div class=\"text-center\">\n <label class=\"c8y-switch\">\n <input\n name=\"{{ item.name }}\"\n type=\"checkbox\"\n [(ngModel)]=\"item.value\"\n [disabled]=\"item.isReadonly\"\n />\n <span></span>\n </label>\n </div>\n </div>\n <div class=\"col-xs-10\">\n <h4 class=\"text-medium\">\n {{ item.name | translate | humanize }}\n </h4>\n <p>\n {{ getCookieDescription(item.name) | translate }}\n </p>\n </div>\n </div>\n</c8y-confirm-modal>\n", dependencies: [{ kind: "component", type: ConfirmModalComponent, selector: "c8y-confirm-modal", inputs: ["title", "body", "confirmOptions", "status", "labels"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: HumanizePipe, name: "humanize" }] }); }
15427
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: CookieBannerPreferencesModalComponent, isStandalone: true, selector: "c8y-cookie-banner-preferences-modal", viewQueries: [{ propertyName: "modalRef", first: true, predicate: ["modalRef"], descendants: true }], ngImport: i0, template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n\n <div *ngFor=\"let item of configCookiePreferencesList\" class=\"row p-t-8 p-b-8 separator-top\">\n <div class=\"col-xs-2\">\n <div class=\"text-center\">\n <label class=\"c8y-switch\">\n <input\n name=\"{{ item.name }}\"\n type=\"checkbox\"\n [(ngModel)]=\"item.value\"\n [disabled]=\"item.isReadonly\"\n />\n <span></span>\n </label>\n </div>\n </div>\n <div class=\"col-xs-10\">\n <h4 class=\"text-medium\">\n {{ item.name | translate | humanize }}\n </h4>\n <p>\n {{ getCookieDescription(item.name) | translate }}\n </p>\n </div>\n </div>\n</c8y-confirm-modal>\n", dependencies: [{ kind: "component", type: ConfirmModalComponent, selector: "c8y-confirm-modal", inputs: ["title", "body", "confirmOptions", "status", "requireCodeVerification", "labels"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: HumanizePipe, name: "humanize" }] }); }
15393
15428
  }
15394
15429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CookieBannerPreferencesModalComponent, decorators: [{
15395
15430
  type: Component,
@@ -16219,6 +16254,7 @@ class ModalModule {
16219
16254
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModalModule, imports: [ModalModule$1.forRoot(),
16220
16255
  CommonModule,
16221
16256
  PopoverModule.forRoot(),
16257
+ ConfirmModalComponent,
16222
16258
  PopoverConfirmComponent] }); }
16223
16259
  }
16224
16260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModalModule, decorators: [{
@@ -16399,6 +16435,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
16399
16435
  args: ['message']
16400
16436
  }] } });
16401
16437
 
16438
+ class RequiredInputPlaceholderDirective {
16439
+ constructor(el, renderer, translationService, ngControl) {
16440
+ this.el = el;
16441
+ this.renderer = renderer;
16442
+ this.translationService = translationService;
16443
+ this.ngControl = ngControl;
16444
+ this.shouldSkipRequiredHint = false;
16445
+ this.shouldSkipRequiredHint = !!this.el.nativeElement.closest('[placeholder-no-required-hint]');
16446
+ }
16447
+ ngAfterViewChecked() {
16448
+ if (this.el?.nativeElement?.required !== undefined || this.ngControl?.control) {
16449
+ const isRequired = this.el?.nativeElement?.required ||
16450
+ this.ngControl?.control?.hasValidator(Validators.required);
16451
+ const willSetRequiredHint = isRequired && !this.shouldSkipRequiredHint;
16452
+ const placeholder = this.el.nativeElement.placeholder;
16453
+ if (this.placeholder !== placeholder || this.req !== willSetRequiredHint) {
16454
+ this.updatePlaceholder(this.getTextForPlaceholder(placeholder, willSetRequiredHint));
16455
+ }
16456
+ }
16457
+ }
16458
+ getTextForPlaceholder(placeholder = '', required = false) {
16459
+ this.req = required;
16460
+ const requiredText = `(${this.translationService.instant(gettext$1('required'))})`;
16461
+ const requiredTextIndex = placeholder.lastIndexOf(requiredText);
16462
+ if (requiredTextIndex > 0) {
16463
+ placeholder = placeholder.slice(0, requiredTextIndex - 1);
16464
+ }
16465
+ if (requiredTextIndex === 0) {
16466
+ placeholder = '';
16467
+ }
16468
+ if (!required) {
16469
+ return placeholder;
16470
+ }
16471
+ return placeholder.trim() ? `${placeholder} ${requiredText}` : requiredText;
16472
+ }
16473
+ updatePlaceholder(placeholder) {
16474
+ this.renderer.setAttribute(this.el.nativeElement, 'placeholder', placeholder);
16475
+ this.placeholder = placeholder;
16476
+ }
16477
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RequiredInputPlaceholderDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.TranslateService }, { token: i1$8.NgControl, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
16478
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: RequiredInputPlaceholderDirective, isStandalone: true, selector: "input[required], input[formControlName]", ngImport: i0 }); }
16479
+ }
16480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RequiredInputPlaceholderDirective, decorators: [{
16481
+ type: Directive,
16482
+ args: [{
16483
+ selector: 'input[required], input[formControlName]',
16484
+ standalone: true
16485
+ }]
16486
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.TranslateService }, { type: i1$8.NgControl, decorators: [{
16487
+ type: Optional
16488
+ }] }] });
16489
+
16402
16490
  /**
16403
16491
  * Actions are functions that can be executed on the
16404
16492
  * current list item. They are displayed next to the
@@ -16745,6 +16833,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
16745
16833
  args: [ListItemCollapseComponent, { static: false }]
16746
16834
  }] } });
16747
16835
 
16836
+ /**
16837
+ * Allows to display a timeline. Should be used with
16838
+ * content projection.
16839
+ *
16840
+ * ```html
16841
+ * <c8y-list-group>
16842
+ * <c8y-li-timeline>
16843
+ * 24.April 2020
16844
+ * <c8y-li>
16845
+ * Hello
16846
+ * </c8y-li>
16847
+ * </c8y-li-timeline>
16848
+ * </c8y-list-group>
16849
+ * ```
16850
+ */
16851
+ class ListItemTimelineComponent {
16852
+ get expanded() {
16853
+ return !this.listItemComponent?.collapsed;
16854
+ }
16855
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListItemTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16856
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ListItemTimelineComponent, isStandalone: true, selector: "c8y-list-item-timeline, c8y-li-timeline", host: { properties: { "class.expanded": "this.expanded" }, classAttribute: "c8y-list--timeline__item" }, queries: [{ propertyName: "listItemComponent", first: true, predicate: ListItemComponent, descendants: true }], ngImport: i0, template: "<small class=\"c8y-list--timeline__item__date\">\n <ng-content></ng-content>\n</small>\n<ng-content select=\"c8y-li, c8y-list-item\"></ng-content>\n" }); }
16857
+ }
16858
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListItemTimelineComponent, decorators: [{
16859
+ type: Component,
16860
+ args: [{ selector: 'c8y-list-item-timeline, c8y-li-timeline', host: {
16861
+ class: 'c8y-list--timeline__item'
16862
+ }, standalone: true, template: "<small class=\"c8y-list--timeline__item__date\">\n <ng-content></ng-content>\n</small>\n<ng-content select=\"c8y-li, c8y-list-item\"></ng-content>\n" }]
16863
+ }], propDecorators: { listItemComponent: [{
16864
+ type: ContentChild,
16865
+ args: [ListItemComponent, { static: false }]
16866
+ }], expanded: [{
16867
+ type: HostBinding,
16868
+ args: ['class.expanded']
16869
+ }] } });
16870
+
16871
+ /**
16872
+ * List groups are flexible and powerful components for displaying
16873
+ * both simple lists of elements and complex ones with custom content.
16874
+ *
16875
+ * ```html
16876
+ * <c8y-list-group>
16877
+ * <c8y-li>
16878
+ * Plain <strong>Text</strong>
16879
+ * </c8y-li>
16880
+ * <c8y-li>
16881
+ * <c8y-li-icon [icon]="'rocket'"></c8y-li-icon>
16882
+ * Icon
16883
+ * </c8y-li>
16884
+ * <c8y-li>
16885
+ * <c8y-li-radio></c8y-li-radio>
16886
+ * Radio
16887
+ * </c8y-li>
16888
+ * <c8y-li>
16889
+ * <c8y-li-checkbox></c8y-li-checkbox>
16890
+ * Checkbox
16891
+ * </c8y-li>
16892
+ * <c8y-li>
16893
+ * Content
16894
+ * <c8y-li-footer>
16895
+ * Footer
16896
+ * </c8y-li-footer>
16897
+ * </c8y-li>
16898
+ * <c8y-li>
16899
+ * Content
16900
+ * <c8y-li-action icon="rocket">
16901
+ * Launch
16902
+ * </c8y-li-action>
16903
+ * </c8y-li>
16904
+ * <c8y-li>
16905
+ * Content
16906
+ * <c8y-li-collapse>
16907
+ * Collapsed content
16908
+ * </c8y-li-collapse>
16909
+ * </c8y-li>
16910
+ * </c8y-list-group>
16911
+ * ```
16912
+ */
16913
+ class ListGroupComponent {
16914
+ constructor() {
16915
+ /**
16916
+ * @ignore
16917
+ */
16918
+ this.timeline = false;
16919
+ }
16920
+ /**
16921
+ * @ignore
16922
+ */
16923
+ ngAfterContentChecked() {
16924
+ this.timeline = !!this.timelineComponent;
16925
+ }
16926
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16927
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ListGroupComponent, isStandalone: true, selector: "c8y-list-group", host: { properties: { "class.c8y-list--timeline": "this.timeline" }, classAttribute: "c8y-list__group" }, queries: [{ propertyName: "timelineComponent", first: true, predicate: ListItemTimelineComponent, descendants: true }], ngImport: i0, template: "<ng-content></ng-content>\n" }); }
16928
+ }
16929
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListGroupComponent, decorators: [{
16930
+ type: Component,
16931
+ args: [{ selector: 'c8y-list-group', host: {
16932
+ class: 'c8y-list__group'
16933
+ }, standalone: true, template: "<ng-content></ng-content>\n" }]
16934
+ }], propDecorators: { timeline: [{
16935
+ type: HostBinding,
16936
+ args: ['class.c8y-list--timeline']
16937
+ }], timelineComponent: [{
16938
+ type: ContentChild,
16939
+ args: [ListItemTimelineComponent, { static: false }]
16940
+ }] } });
16941
+
16748
16942
  /**
16749
16943
  * This service provides keyboard navigation for dropdowns.
16750
16944
  *
@@ -16927,164 +17121,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
16927
17121
  type: Injectable
16928
17122
  }] });
16929
17123
 
16930
- class RequiredInputPlaceholderDirective {
16931
- constructor(el, renderer, translationService, ngControl) {
16932
- this.el = el;
16933
- this.renderer = renderer;
16934
- this.translationService = translationService;
16935
- this.ngControl = ngControl;
16936
- this.shouldSkipRequiredHint = false;
16937
- this.shouldSkipRequiredHint = !!this.el.nativeElement.closest('[placeholder-no-required-hint]');
16938
- }
16939
- ngAfterViewChecked() {
16940
- if (this.el?.nativeElement?.required !== undefined || this.ngControl?.control) {
16941
- const isRequired = this.el?.nativeElement?.required ||
16942
- this.ngControl?.control?.hasValidator(Validators.required);
16943
- const willSetRequiredHint = isRequired && !this.shouldSkipRequiredHint;
16944
- const placeholder = this.el.nativeElement.placeholder;
16945
- if (this.placeholder !== placeholder || this.req !== willSetRequiredHint) {
16946
- this.updatePlaceholder(this.getTextForPlaceholder(placeholder, willSetRequiredHint));
16947
- }
16948
- }
16949
- }
16950
- getTextForPlaceholder(placeholder = '', required = false) {
16951
- this.req = required;
16952
- const requiredText = `(${this.translationService.instant(gettext$1('required'))})`;
16953
- const requiredTextIndex = placeholder.lastIndexOf(requiredText);
16954
- if (requiredTextIndex > 0) {
16955
- placeholder = placeholder.slice(0, requiredTextIndex - 1);
16956
- }
16957
- if (requiredTextIndex === 0) {
16958
- placeholder = '';
16959
- }
16960
- if (!required) {
16961
- return placeholder;
16962
- }
16963
- return placeholder.trim() ? `${placeholder} ${requiredText}` : requiredText;
16964
- }
16965
- updatePlaceholder(placeholder) {
16966
- this.renderer.setAttribute(this.el.nativeElement, 'placeholder', placeholder);
16967
- this.placeholder = placeholder;
16968
- }
16969
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RequiredInputPlaceholderDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.TranslateService }, { token: i1$8.NgControl, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
16970
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: RequiredInputPlaceholderDirective, isStandalone: true, selector: "input[required], input[formControlName]", ngImport: i0 }); }
16971
- }
16972
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RequiredInputPlaceholderDirective, decorators: [{
16973
- type: Directive,
16974
- args: [{
16975
- selector: 'input[required], input[formControlName]',
16976
- standalone: true
16977
- }]
16978
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.TranslateService }, { type: i1$8.NgControl, decorators: [{
16979
- type: Optional
16980
- }] }] });
16981
-
16982
- /**
16983
- * Allows to display a timeline. Should be used with
16984
- * content projection.
16985
- *
16986
- * ```html
16987
- * <c8y-list-group>
16988
- * <c8y-li-timeline>
16989
- * 24.April 2020
16990
- * <c8y-li>
16991
- * Hello
16992
- * </c8y-li>
16993
- * </c8y-li-timeline>
16994
- * </c8y-list-group>
16995
- * ```
16996
- */
16997
- class ListItemTimelineComponent {
16998
- get expanded() {
16999
- return !this.listItemComponent?.collapsed;
17000
- }
17001
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListItemTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
17002
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ListItemTimelineComponent, isStandalone: true, selector: "c8y-list-item-timeline, c8y-li-timeline", host: { properties: { "class.expanded": "this.expanded" }, classAttribute: "c8y-list--timeline__item" }, queries: [{ propertyName: "listItemComponent", first: true, predicate: ListItemComponent, descendants: true }], ngImport: i0, template: "<small class=\"c8y-list--timeline__item__date\">\n <ng-content></ng-content>\n</small>\n<ng-content select=\"c8y-li, c8y-list-item\"></ng-content>\n" }); }
17003
- }
17004
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListItemTimelineComponent, decorators: [{
17005
- type: Component,
17006
- args: [{ selector: 'c8y-list-item-timeline, c8y-li-timeline', host: {
17007
- class: 'c8y-list--timeline__item'
17008
- }, standalone: true, template: "<small class=\"c8y-list--timeline__item__date\">\n <ng-content></ng-content>\n</small>\n<ng-content select=\"c8y-li, c8y-list-item\"></ng-content>\n" }]
17009
- }], propDecorators: { listItemComponent: [{
17010
- type: ContentChild,
17011
- args: [ListItemComponent, { static: false }]
17012
- }], expanded: [{
17013
- type: HostBinding,
17014
- args: ['class.expanded']
17015
- }] } });
17016
-
17017
- /**
17018
- * List groups are flexible and powerful components for displaying
17019
- * both simple lists of elements and complex ones with custom content.
17020
- *
17021
- * ```html
17022
- * <c8y-list-group>
17023
- * <c8y-li>
17024
- * Plain <strong>Text</strong>
17025
- * </c8y-li>
17026
- * <c8y-li>
17027
- * <c8y-li-icon [icon]="'rocket'"></c8y-li-icon>
17028
- * Icon
17029
- * </c8y-li>
17030
- * <c8y-li>
17031
- * <c8y-li-radio></c8y-li-radio>
17032
- * Radio
17033
- * </c8y-li>
17034
- * <c8y-li>
17035
- * <c8y-li-checkbox></c8y-li-checkbox>
17036
- * Checkbox
17037
- * </c8y-li>
17038
- * <c8y-li>
17039
- * Content
17040
- * <c8y-li-footer>
17041
- * Footer
17042
- * </c8y-li-footer>
17043
- * </c8y-li>
17044
- * <c8y-li>
17045
- * Content
17046
- * <c8y-li-action icon="rocket">
17047
- * Launch
17048
- * </c8y-li-action>
17049
- * </c8y-li>
17050
- * <c8y-li>
17051
- * Content
17052
- * <c8y-li-collapse>
17053
- * Collapsed content
17054
- * </c8y-li-collapse>
17055
- * </c8y-li>
17056
- * </c8y-list-group>
17057
- * ```
17058
- */
17059
- class ListGroupComponent {
17060
- constructor() {
17061
- /**
17062
- * @ignore
17063
- */
17064
- this.timeline = false;
17065
- }
17066
- /**
17067
- * @ignore
17068
- */
17069
- ngAfterContentChecked() {
17070
- this.timeline = !!this.timelineComponent;
17071
- }
17072
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
17073
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ListGroupComponent, isStandalone: true, selector: "c8y-list-group", host: { properties: { "class.c8y-list--timeline": "this.timeline" }, classAttribute: "c8y-list__group" }, queries: [{ propertyName: "timelineComponent", first: true, predicate: ListItemTimelineComponent, descendants: true }], ngImport: i0, template: "<ng-content></ng-content>\n" }); }
17074
- }
17075
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ListGroupComponent, decorators: [{
17076
- type: Component,
17077
- args: [{ selector: 'c8y-list-group', host: {
17078
- class: 'c8y-list__group'
17079
- }, standalone: true, template: "<ng-content></ng-content>\n" }]
17080
- }], propDecorators: { timeline: [{
17081
- type: HostBinding,
17082
- args: ['class.c8y-list--timeline']
17083
- }], timelineComponent: [{
17084
- type: ContentChild,
17085
- args: [ListItemTimelineComponent, { static: false }]
17086
- }] } });
17087
-
17088
17124
  class TypeaheadComponent {
17089
17125
  constructor(selectKeyboardService) {
17090
17126
  this.selectKeyboardService = selectKeyboardService;
@@ -17151,6 +17187,10 @@ class TypeaheadComponent {
17151
17187
  fromEvent(this.searchControl.nativeElement, 'keydown')
17152
17188
  .pipe(debounceTime(200), distinctUntilChanged(), takeUntil(this.destroyed$))
17153
17189
  .subscribe((event) => {
17190
+ // ignore OS/browser shortcuts (Cmd/Ctrl/Alt combos, e.g. Cmd+A, Shift+Cmd+4)
17191
+ if (event.metaKey || event.ctrlKey || event.altKey) {
17192
+ return;
17193
+ }
17154
17194
  if (this.selectKeyboardService.isSelectionEvent(event)) {
17155
17195
  return;
17156
17196
  }
@@ -17192,7 +17232,7 @@ class TypeaheadComponent {
17192
17232
  return null;
17193
17233
  }
17194
17234
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TypeaheadComponent, deps: [{ token: SelectKeyboardService }], target: i0.ɵɵFactoryTarget.Component }); }
17195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: TypeaheadComponent, isStandalone: true, selector: "c8y-typeahead", inputs: { required: "required", maxlength: "maxlength", disabled: "disabled", allowFreeEntries: "allowFreeEntries", placeholder: "placeholder", displayProperty: "displayProperty", icon: "icon", name: "name", autoClose: "autoClose", hideNew: "hideNew", container: "container", selected: "selected", title: "title", highlightFirstItem: "highlightFirstItem" }, outputs: { onSearch: "onSearch", onIconClick: "onIconClick" }, providers: [
17235
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TypeaheadComponent, isStandalone: true, selector: "c8y-typeahead", inputs: { required: "required", maxlength: "maxlength", disabled: "disabled", allowFreeEntries: "allowFreeEntries", placeholder: "placeholder", displayProperty: "displayProperty", icon: "icon", name: "name", autoClose: "autoClose", hideNew: "hideNew", container: "container", selected: "selected", title: "title", highlightFirstItem: "highlightFirstItem" }, outputs: { onSearch: "onSearch", onIconClick: "onIconClick" }, providers: [
17196
17236
  {
17197
17237
  provide: NG_VALUE_ACCESSOR,
17198
17238
  multi: true,
@@ -17204,7 +17244,7 @@ class TypeaheadComponent {
17204
17244
  multi: true
17205
17245
  },
17206
17246
  SelectKeyboardService
17207
- ], queries: [{ propertyName: "list", predicate: ListItemComponent }], viewQueries: [{ propertyName: "searchControl", first: true, predicate: ["searchControl"], descendants: true }, { propertyName: "searchControlModel", first: true, predicate: ["searchControlModel"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<div\n class=\"c8y-search-dropdown dropdown fit-w\"\n placement=\"bottom left\"\n dropdown\n [container]=\"container\"\n #dropdown=\"bs-dropdown\"\n [autoClose]=\"true\"\n (onShown)=\"onShown()\"\n [isDisabled]=\"disabled\"\n dropdownToggle\n>\n <div\n class=\"input-group input-group-dropdown \"\n role=\"button\"\n >\n <input\n class=\"form-control text-truncate\"\n type=\"text\"\n #searchControl\n #searchControlModel=\"ngModel\"\n [ngClass]=\"{\n 'p-r-80':\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false),\n 'p-r-40': hideNew || getDisplayProperty()?.length === 0\n }\"\n [required]=\"required\"\n [ngModel]=\"selected ? getDisplayProperty() : ''\"\n [placeholder]=\"placeholder | translate\"\n (blur)=\"doBlur()\"\n [name]=\"name\"\n [maxlength]=\"maxlength\"\n [disabled]=\"disabled\"\n />\n <span\n class=\"label label-info p-absolute\"\n style=\"top: 10px; right: 40px; z-index: 10\"\n *ngIf=\"\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false)\n \"\n >\n {{ 'New' | translate }}\n </span>\n\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n [title]=\"title\"\n type=\"button\"\n [disabled]=\"disabled\"\n (click)=\"onIconClick.emit({ icon, $event })\"\n data-cy=\"typeahead-button\"\n >\n <i\n class=\"text-primary\"\n [c8yIcon]=\"icon\"\n ></i>\n </button>\n </span>\n </div>\n <c8y-list-group\n class=\"dropdown-menu dropdown-menu--modal\"\n [style.width]=\"container === 'body' ? searchControl.clientWidth + 'px' : undefined\"\n role=\"menu\"\n data-cy=\"typeahead--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"div, c8y-li, c8y-list-item, button, a\"></ng-content>\n </c8y-list-group>\n</div>\n", dependencies: [{ kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1$3.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1$3.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1$3.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.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: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
17247
+ ], queries: [{ propertyName: "list", predicate: ListItemComponent }], viewQueries: [{ propertyName: "searchControl", first: true, predicate: ["searchControl"], descendants: true }, { propertyName: "searchControlModel", first: true, predicate: ["searchControlModel"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], ngImport: i0, template: "<div\n class=\"c8y-search-dropdown dropdown fit-w\"\n placement=\"bottom left\"\n dropdown\n [container]=\"container\"\n #dropdown=\"bs-dropdown\"\n [autoClose]=\"true\"\n (onShown)=\"onShown()\"\n [isDisabled]=\"disabled\"\n dropdownToggle\n>\n <div\n class=\"input-group input-group-dropdown\"\n role=\"button\"\n >\n <input\n class=\"form-control text-truncate\"\n type=\"text\"\n #searchControl\n #searchControlModel=\"ngModel\"\n [ngClass]=\"{\n 'p-r-80':\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false),\n 'p-r-40': hideNew || getDisplayProperty()?.length === 0\n }\"\n [required]=\"required\"\n [ngModel]=\"selected ? getDisplayProperty() : ''\"\n [placeholder]=\"placeholder | translate\"\n (blur)=\"doBlur()\"\n [name]=\"name\"\n [maxlength]=\"maxlength\"\n [disabled]=\"disabled\"\n />\n @if (\n !hideNew &&\n selected &&\n selected.id === null &&\n getDisplayProperty()?.length > 0 &&\n allowFreeEntries\n ) {\n <span\n class=\"label label-info p-absolute\"\n style=\"top: 10px; right: 40px; z-index: 10\"\n >\n {{ 'New' | translate }}\n </span>\n }\n\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n [title]=\"title\"\n type=\"button\"\n [disabled]=\"disabled\"\n (click)=\"onIconClick.emit({ icon, $event })\"\n data-cy=\"typeahead-button\"\n >\n <i\n class=\"text-primary\"\n [c8yIcon]=\"icon\"\n ></i>\n </button>\n </span>\n </div>\n <c8y-list-group\n class=\"dropdown-menu dropdown-menu--modal\"\n [style.width]=\"container === 'body' ? searchControl.clientWidth + 'px' : undefined\"\n role=\"menu\"\n data-cy=\"typeahead--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"div, c8y-li, c8y-list-item, button, a\"></ng-content>\n </c8y-list-group>\n</div>\n", dependencies: [{ kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1$3.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1$3.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1$3.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.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: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
17208
17248
  }
17209
17249
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TypeaheadComponent, decorators: [{
17210
17250
  type: Component,
@@ -17225,11 +17265,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
17225
17265
  RequiredInputPlaceholderDirective,
17226
17266
  FormsModule$1,
17227
17267
  NgClass,
17228
- NgIf,
17229
17268
  IconDirective,
17230
17269
  ListGroupComponent,
17231
17270
  C8yTranslatePipe
17232
- ], template: "<div\n class=\"c8y-search-dropdown dropdown fit-w\"\n placement=\"bottom left\"\n dropdown\n [container]=\"container\"\n #dropdown=\"bs-dropdown\"\n [autoClose]=\"true\"\n (onShown)=\"onShown()\"\n [isDisabled]=\"disabled\"\n dropdownToggle\n>\n <div\n class=\"input-group input-group-dropdown \"\n role=\"button\"\n >\n <input\n class=\"form-control text-truncate\"\n type=\"text\"\n #searchControl\n #searchControlModel=\"ngModel\"\n [ngClass]=\"{\n 'p-r-80':\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false),\n 'p-r-40': hideNew || getDisplayProperty()?.length === 0\n }\"\n [required]=\"required\"\n [ngModel]=\"selected ? getDisplayProperty() : ''\"\n [placeholder]=\"placeholder | translate\"\n (blur)=\"doBlur()\"\n [name]=\"name\"\n [maxlength]=\"maxlength\"\n [disabled]=\"disabled\"\n />\n <span\n class=\"label label-info p-absolute\"\n style=\"top: 10px; right: 40px; z-index: 10\"\n *ngIf=\"\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false)\n \"\n >\n {{ 'New' | translate }}\n </span>\n\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n [title]=\"title\"\n type=\"button\"\n [disabled]=\"disabled\"\n (click)=\"onIconClick.emit({ icon, $event })\"\n data-cy=\"typeahead-button\"\n >\n <i\n class=\"text-primary\"\n [c8yIcon]=\"icon\"\n ></i>\n </button>\n </span>\n </div>\n <c8y-list-group\n class=\"dropdown-menu dropdown-menu--modal\"\n [style.width]=\"container === 'body' ? searchControl.clientWidth + 'px' : undefined\"\n role=\"menu\"\n data-cy=\"typeahead--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"div, c8y-li, c8y-list-item, button, a\"></ng-content>\n </c8y-list-group>\n</div>\n" }]
17271
+ ], template: "<div\n class=\"c8y-search-dropdown dropdown fit-w\"\n placement=\"bottom left\"\n dropdown\n [container]=\"container\"\n #dropdown=\"bs-dropdown\"\n [autoClose]=\"true\"\n (onShown)=\"onShown()\"\n [isDisabled]=\"disabled\"\n dropdownToggle\n>\n <div\n class=\"input-group input-group-dropdown\"\n role=\"button\"\n >\n <input\n class=\"form-control text-truncate\"\n type=\"text\"\n #searchControl\n #searchControlModel=\"ngModel\"\n [ngClass]=\"{\n 'p-r-80':\n !hideNew &&\n (selected\n ? selected.id === null && getDisplayProperty()?.length > 0 && allowFreeEntries\n : false),\n 'p-r-40': hideNew || getDisplayProperty()?.length === 0\n }\"\n [required]=\"required\"\n [ngModel]=\"selected ? getDisplayProperty() : ''\"\n [placeholder]=\"placeholder | translate\"\n (blur)=\"doBlur()\"\n [name]=\"name\"\n [maxlength]=\"maxlength\"\n [disabled]=\"disabled\"\n />\n @if (\n !hideNew &&\n selected &&\n selected.id === null &&\n getDisplayProperty()?.length > 0 &&\n allowFreeEntries\n ) {\n <span\n class=\"label label-info p-absolute\"\n style=\"top: 10px; right: 40px; z-index: 10\"\n >\n {{ 'New' | translate }}\n </span>\n }\n\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n [title]=\"title\"\n type=\"button\"\n [disabled]=\"disabled\"\n (click)=\"onIconClick.emit({ icon, $event })\"\n data-cy=\"typeahead-button\"\n >\n <i\n class=\"text-primary\"\n [c8yIcon]=\"icon\"\n ></i>\n </button>\n </span>\n </div>\n <c8y-list-group\n class=\"dropdown-menu dropdown-menu--modal\"\n [style.width]=\"container === 'body' ? searchControl.clientWidth + 'px' : undefined\"\n role=\"menu\"\n data-cy=\"typeahead--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"div, c8y-li, c8y-list-item, button, a\"></ng-content>\n </c8y-list-group>\n</div>\n" }]
17233
17272
  }], ctorParameters: () => [{ type: SelectKeyboardService }], propDecorators: { searchControl: [{
17234
17273
  type: ViewChild,
17235
17274
  args: ['searchControl', { static: false }]
@@ -18444,7 +18483,8 @@ class ValidationPattern {
18444
18483
  maxlength: gettext$1('Should have at most {{ requiredLength }} characters.'),
18445
18484
  pattern: gettext$1('Does not match pattern {{ requiredPattern }}.'),
18446
18485
  opcuaBrowsePath: gettext$1('Invalid OPC UA URI.'),
18447
- password: gettext$1('Password must have at least 8 characters and no more than 32 and can only contain letters, numbers and following symbols: `~!@#$%^&*()_|+-=?;:\'",.<>{}[]\\/'),
18486
+ password: gettext$1('Password must have at least {{ minLength }} characters and no more than {{ maxLength }} and can only contain letters, numbers and following symbols: {{ allowedCharactersList }}'),
18487
+ passwordSimple: gettext$1('Password must have at least {{ minLength }} characters and no more than {{ maxLength }}.'),
18448
18488
  passwordConfirm: gettext$1('Passwords do not match.'),
18449
18489
  passwordStrength: gettext$1('Password is not strong enough, use a stronger password.'),
18450
18490
  passwordStrengthChecklist: gettext$1('Password is not strong enough, use a stronger password. Check the requirements listed on the right.'),
@@ -18488,6 +18528,8 @@ class ValidationPattern {
18488
18528
  pattern: /^(opc.tcp|http|https):\/\/[^ "]+$/
18489
18529
  },
18490
18530
  password: {
18531
+ // Note: min length {8} is a fallback default. Actual password validation uses
18532
+ // PasswordValidationService with dynamically configured min length.
18491
18533
  pattern: /^[a-zA-Z0-9`~!@#$%^&*()_|+\-=?;:'",.<>{}[\]\\/]{8,32}$/
18492
18534
  },
18493
18535
  tenantId: {
@@ -18700,6 +18742,7 @@ class MessagesComponent {
18700
18742
  this.defaults = ValidationPattern.messages;
18701
18743
  this.helpMessage = '';
18702
18744
  this.messages = [];
18745
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18703
18746
  this.messageMap = {};
18704
18747
  }
18705
18748
  ngAfterContentInit() {
@@ -18724,7 +18767,10 @@ class MessagesComponent {
18724
18767
  }
18725
18768
  }
18726
18769
  toMessage(key, value) {
18727
- let message = this.messageMap[key];
18770
+ // First check customMessages directly for the most up-to-date text
18771
+ // (handles async binding updates that occur after ngAfterContentInit)
18772
+ const customMessage = this.customMessages?.find(({ name }) => name === key);
18773
+ let message = customMessage?.text || this.messageMap[key];
18728
18774
  if ((!message || message === ValidationPattern.messages.pattern) &&
18729
18775
  key === 'pattern' &&
18730
18776
  typeof value?.requiredPattern === 'string') {
@@ -18732,7 +18778,8 @@ class MessagesComponent {
18732
18778
  const foundPattern = Object.keys(ValidationPattern.rules).find(tmp => ValidationPattern.rules[tmp].pattern?.source === pattern);
18733
18779
  if (foundPattern) {
18734
18780
  key = foundPattern;
18735
- message = this.messageMap[key];
18781
+ const foundCustomMessage = this.customMessages?.find(({ name }) => name === key);
18782
+ message = foundCustomMessage?.text || this.messageMap[key];
18736
18783
  }
18737
18784
  }
18738
18785
  if (!message) {
@@ -18741,11 +18788,11 @@ class MessagesComponent {
18741
18788
  return this.translateService.instant(message, value);
18742
18789
  }
18743
18790
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MessagesComponent, deps: [{ token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
18744
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: MessagesComponent, isStandalone: true, selector: "c8y-messages", inputs: { show: "show", defaults: "defaults", helpMessage: "helpMessage" }, queries: [{ propertyName: "customMessages", predicate: MessageDirective }], usesOnChanges: true, ngImport: i0, template: "<small class=\"form-control-feedback-message\">\n <div\n class=\"d-block\"\n *ngFor=\"let msg of messages\"\n >\n {{ msg | translate }}\n </div>\n <div\n class=\"help-block\"\n *ngIf=\"!messages.length && helpMessage\"\n >\n {{ helpMessage | translate }}\n </div>\n <ng-content></ng-content>\n</small>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
18791
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MessagesComponent, isStandalone: true, selector: "c8y-messages", inputs: { show: "show", defaults: "defaults", helpMessage: "helpMessage" }, queries: [{ propertyName: "customMessages", predicate: MessageDirective }], usesOnChanges: true, ngImport: i0, template: "<small class=\"form-control-feedback-message\">\n @for (msg of messages; track msg) {\n <div class=\"d-block\">\n {{ msg | translate }}\n </div>\n }\n @if (!messages.length && helpMessage) {\n <div class=\"help-block\">\n {{ helpMessage | translate }}\n </div>\n }\n <ng-content></ng-content>\n</small>\n", dependencies: [{ kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
18745
18792
  }
18746
18793
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MessagesComponent, decorators: [{
18747
18794
  type: Component,
18748
- args: [{ selector: 'c8y-messages', standalone: true, imports: [NgIf, NgFor, C8yTranslatePipe], template: "<small class=\"form-control-feedback-message\">\n <div\n class=\"d-block\"\n *ngFor=\"let msg of messages\"\n >\n {{ msg | translate }}\n </div>\n <div\n class=\"help-block\"\n *ngIf=\"!messages.length && helpMessage\"\n >\n {{ helpMessage | translate }}\n </div>\n <ng-content></ng-content>\n</small>\n" }]
18795
+ args: [{ selector: 'c8y-messages', standalone: true, imports: [C8yTranslatePipe], template: "<small class=\"form-control-feedback-message\">\n @for (msg of messages; track msg) {\n <div class=\"d-block\">\n {{ msg | translate }}\n </div>\n }\n @if (!messages.length && helpMessage) {\n <div class=\"help-block\">\n {{ helpMessage | translate }}\n </div>\n }\n <ng-content></ng-content>\n</small>\n" }]
18749
18796
  }], ctorParameters: () => [{ type: i1$1.TranslateService }], propDecorators: { show: [{
18750
18797
  type: Input
18751
18798
  }], defaults: [{
@@ -20370,14 +20417,22 @@ class ModalService {
20370
20417
  * @param labels The labels to use. Default: { ok: 'Confirm', cancel: 'Cancel'}
20371
20418
  * @param confirmOptions Selection options to display as checkbox list.
20372
20419
  * @param productExperienceEvent Additional data to attach to custom product experience events.
20420
+ * @param requireCodeVerification Whether to require user to retype a random code for confirmation.
20373
20421
  */
20374
- async confirm(title, body, status = Status.INFO, labels = {}, confirmOptions = {}, productExperienceEvent = { eventName: 'confirmModal' }) {
20422
+ async confirm(title, body, status = Status.INFO, labels = {}, confirmOptions = {}, productExperienceEvent = { eventName: 'confirmModal' }, requireCodeVerification = false) {
20375
20423
  const modalLabels = {
20376
20424
  ok: labels.ok || gettext$1('Confirm'),
20377
20425
  cancel: labels.cancel || gettext$1('Cancel')
20378
20426
  };
20379
20427
  const modalRef = this.modalService.show(ConfirmModalComponent, {
20380
- initialState: { title, body, labels: modalLabels, status, confirmOptions },
20428
+ initialState: {
20429
+ title,
20430
+ body,
20431
+ labels: modalLabels,
20432
+ status,
20433
+ confirmOptions,
20434
+ requireCodeVerification
20435
+ },
20381
20436
  ariaDescribedby: 'modal-body',
20382
20437
  ariaLabelledBy: 'modal-title',
20383
20438
  ignoreBackdropClick: true
@@ -20818,7 +20873,9 @@ class PasswordService {
20818
20873
  return password.search(/[0-9]/) !== -1;
20819
20874
  }
20820
20875
  hasSpecialChars(password) {
20821
- return password.search(/[^0-9a-zA-Z]+/) !== -1;
20876
+ // Only match ALLOWED symbols, not any non-alphanumeric character
20877
+ // Allowed: `~!@#$%^&*()_|+-=?;:'",.<>{}[]\\/
20878
+ return password.search(/[`~!@#$%^&*()_|+\-=?;:'",.<>{}\[\]\\/]/) !== -1;
20822
20879
  }
20823
20880
  getStrengthColor(password) {
20824
20881
  const passwordStrength = filter$2([
@@ -21059,6 +21116,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
21059
21116
  type: Input
21060
21117
  }] } });
21061
21118
 
21119
+ /**
21120
+ * Shared password validation service for Angular and AngularJS.
21121
+ *
21122
+ * Validation logic:
21123
+ * - Invalid characters → error with full message (allowed symbols)
21124
+ * - Too long (>32) → error
21125
+ * - Too short when NOT enforced → simple error (length only)
21126
+ * - Too short when enforced → valid (checklist handles it)
21127
+ */
21128
+ class PasswordValidationService {
21129
+ constructor() {
21130
+ this.DEFAULT_MIN_LENGTH = 8;
21131
+ this.MAX_LENGTH = 32;
21132
+ this.ALLOWED_SYMBOLS = '`~!@#$%^&*()_|+-=?;:\'",.<>{}[]\\/';
21133
+ this.VALID_CHARS_PATTERN = /^[a-zA-Z0-9`~!@#$%^&*()_|+\-=?;:'",.<>{}[\]\\/]*$/;
21134
+ }
21135
+ /**
21136
+ * @param password The password to validate.
21137
+ * @param strengthEnforced Whether password strength enforcement is enabled.
21138
+ * @param minGreenLength Minimum length to be considered strong/green.
21139
+ * When strength is enforced, this is the green minimum from tenant settings.
21140
+ * Defaults to DEFAULT_MIN_LENGTH.
21141
+ */
21142
+ validate(password, strengthEnforced, minGreenLength) {
21143
+ const min = minGreenLength ?? this.DEFAULT_MIN_LENGTH;
21144
+ if (!password) {
21145
+ return { valid: true, errorKey: null };
21146
+ }
21147
+ // Invalid characters - always show full message with allowed symbols
21148
+ if (!this.hasValidCharsOnly(password)) {
21149
+ return { valid: false, errorKey: 'password' };
21150
+ }
21151
+ // Too long - always validate
21152
+ if (password.length > this.MAX_LENGTH) {
21153
+ return { valid: false, errorKey: strengthEnforced ? 'password' : 'passwordSimple' };
21154
+ }
21155
+ // Shorter than absolute minimum - always invalid regardless of enforcement
21156
+ if (password.length < this.DEFAULT_MIN_LENGTH) {
21157
+ return { valid: false, errorKey: 'passwordSimple' };
21158
+ }
21159
+ // Too short for configured min - only validate when strength is NOT enforced (checklist handles it otherwise)
21160
+ if (!strengthEnforced && password.length < min) {
21161
+ return { valid: false, errorKey: 'passwordSimple' };
21162
+ }
21163
+ return { valid: true, errorKey: null };
21164
+ }
21165
+ hasValidCharsOnly(password) {
21166
+ return this.VALID_CHARS_PATTERN.test(password);
21167
+ }
21168
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21169
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordValidationService, providedIn: 'root' }); }
21170
+ }
21171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordValidationService, decorators: [{
21172
+ type: Injectable,
21173
+ args: [{ providedIn: 'root' }]
21174
+ }] });
21175
+
21176
+ /**
21177
+ * Password validation directive using shared PasswordValidationService.
21178
+ *
21179
+ * Returns `{ password: { minLength, maxLength, allowedCharactersList } }` for full message (with allowed symbols)
21180
+ * or `{ passwordSimple: { minLength, maxLength, allowedCharactersList } }` for simple message (length only).
21181
+ */
21182
+ class PasswordValidationDirective {
21183
+ constructor() {
21184
+ this.validationService = inject(PasswordValidationService);
21185
+ }
21186
+ validate(control) {
21187
+ const password = control.value;
21188
+ if (!password) {
21189
+ return null;
21190
+ }
21191
+ const strengthEnforced = this.passwordStrengthEnforced === true;
21192
+ const min = strengthEnforced
21193
+ ? (this.minLength ?? this.validationService.DEFAULT_MIN_LENGTH)
21194
+ : this.validationService.DEFAULT_MIN_LENGTH;
21195
+ const result = this.validationService.validate(password, strengthEnforced, min);
21196
+ if (result.valid) {
21197
+ return null;
21198
+ }
21199
+ return {
21200
+ [result.errorKey]: {
21201
+ minLength: min,
21202
+ maxLength: this.validationService.MAX_LENGTH,
21203
+ allowedCharactersList: this.validationService.ALLOWED_SYMBOLS
21204
+ }
21205
+ };
21206
+ }
21207
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordValidationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
21208
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: PasswordValidationDirective, isStandalone: true, selector: "[c8yPasswordValidation]", inputs: { passwordStrengthEnforced: "passwordStrengthEnforced", minLength: "minLength" }, providers: [{ provide: NG_VALIDATORS, useExisting: PasswordValidationDirective, multi: true }], ngImport: i0 }); }
21209
+ }
21210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordValidationDirective, decorators: [{
21211
+ type: Directive,
21212
+ args: [{
21213
+ selector: '[c8yPasswordValidation]',
21214
+ providers: [{ provide: NG_VALIDATORS, useExisting: PasswordValidationDirective, multi: true }],
21215
+ standalone: true
21216
+ }]
21217
+ }], propDecorators: { passwordStrengthEnforced: [{
21218
+ type: Input
21219
+ }], minLength: [{
21220
+ type: Input
21221
+ }] } });
21222
+
21062
21223
  class PasswordConfirm {
21063
21224
  constructor(passwordConfirm) {
21064
21225
  this.passwordConfirm = passwordConfirm;
@@ -21109,7 +21270,7 @@ class PasswordStrengthService {
21109
21270
  };
21110
21271
  }
21111
21272
  /**
21112
- * Gets the minimal number of characters that a password should have to be considered a green strong one.
21273
+ * Gets the minimal number of characters that a password should have to be considered a "green" strong one.
21113
21274
  * @return The min length for password or default value.
21114
21275
  */
21115
21276
  async getGreenMinLength() {
@@ -21193,43 +21354,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
21193
21354
  }], ctorParameters: () => [{ type: AppStateService }] });
21194
21355
 
21195
21356
  class PasswordCheckListComponent {
21196
- set password(password) {
21197
- if (typeof password === 'string') {
21198
- this.onPasswordChange(password);
21199
- }
21200
- }
21201
- constructor(passwordStrength, passwordStrengthChecker, passwordService) {
21357
+ constructor(passwordStrength, passwordService) {
21202
21358
  this.passwordStrength = passwordStrength;
21203
- this.passwordStrengthChecker = passwordStrengthChecker;
21204
21359
  this.passwordService = passwordService;
21205
21360
  this.strengthEnforced = false;
21361
+ this.password = '';
21206
21362
  this.onRequirementsFulfilled = new EventEmitter();
21207
21363
  this.minGreenLength = 8;
21208
21364
  this.enhancedStrengthCheckList = [
21209
21365
  {
21210
21366
  label: gettext$1('Include lowercase characters (for example, abcdef)'),
21211
- check: this.passwordStrengthChecker.hasLowerCase,
21367
+ check: this.passwordService.hasLowerCase,
21212
21368
  icon: '',
21213
21369
  contextualColor: '',
21214
21370
  textColor: ''
21215
21371
  },
21216
21372
  {
21217
21373
  label: gettext$1('Include uppercase characters (for example, ABCDEF)'),
21218
- check: this.passwordStrengthChecker.hasUpperCase,
21374
+ check: this.passwordService.hasUpperCase,
21219
21375
  icon: '',
21220
21376
  contextualColor: '',
21221
21377
  textColor: ''
21222
21378
  },
21223
21379
  {
21224
21380
  label: gettext$1('Include numbers (for example, 123456)'),
21225
- check: this.passwordStrengthChecker.hasNumbers,
21381
+ check: this.passwordService.hasNumbers,
21226
21382
  icon: '',
21227
21383
  contextualColor: '',
21228
21384
  textColor: ''
21229
21385
  },
21230
21386
  {
21231
21387
  label: gettext$1('Include symbols (for example, !@#$%^)'),
21232
- check: this.passwordStrengthChecker.hasSpecialChars,
21388
+ check: this.passwordService.hasSpecialChars,
21233
21389
  icon: '',
21234
21390
  contextualColor: '',
21235
21391
  textColor: ''
@@ -21238,7 +21394,7 @@ class PasswordCheckListComponent {
21238
21394
  this.basicChecklist = [
21239
21395
  {
21240
21396
  label: gettext$1('Must have at least {{length}} characters'),
21241
- check: password => password.length >= this.minGreenLength,
21397
+ check: (password) => password.length >= this.minGreenLength,
21242
21398
  icon: '',
21243
21399
  contextualColor: '',
21244
21400
  textColor: ''
@@ -21247,15 +21403,26 @@ class PasswordCheckListComponent {
21247
21403
  this.combinedChecklist = [];
21248
21404
  }
21249
21405
  async ngOnInit() {
21250
- this.minGreenLength = await this.passwordStrength.getGreenMinLength();
21251
- if (!this.minGreenLength) {
21252
- this.minGreenLength = this.passwordService.getDefaultPasswordMinLength();
21406
+ this.defaultMinLength = this.passwordService.getDefaultPasswordMinLength();
21407
+ if (!this.greenMinLength) {
21408
+ this.greenMinLength = await this.passwordStrength.getGreenMinLength();
21409
+ }
21410
+ this.updateMinGreenLength();
21411
+ this.onPasswordChange(this.password);
21412
+ }
21413
+ ngOnChanges(changes) {
21414
+ if ((changes.strengthEnforced && !changes.strengthEnforced.firstChange) ||
21415
+ (changes.greenMinLength && !changes.greenMinLength.firstChange)) {
21416
+ this.updateMinGreenLength();
21417
+ }
21418
+ if (changes.password || changes.strengthEnforced || changes.greenMinLength) {
21419
+ this.onPasswordChange(this.password);
21253
21420
  }
21254
- this.onPasswordChange('');
21255
21421
  }
21256
21422
  get translateParams() {
21257
21423
  return {
21258
- length: this.minGreenLength
21424
+ length: this.minGreenLength,
21425
+ recommendedLength: this.recommendedMinLength
21259
21426
  };
21260
21427
  }
21261
21428
  checkRequirement(requirement, password) {
@@ -21268,12 +21435,16 @@ class PasswordCheckListComponent {
21268
21435
  return requirement;
21269
21436
  }
21270
21437
  onPasswordChange(password) {
21438
+ const pwd = typeof password === 'string' ? password : '';
21271
21439
  this.basicChecklist.forEach(requirement => {
21272
- this.checkRequirement(requirement, password);
21440
+ this.checkRequirement(requirement, pwd);
21273
21441
  });
21274
21442
  this.enhancedStrengthCheckList.forEach(requirement => {
21275
- this.checkRequirement(requirement, password);
21443
+ this.checkRequirement(requirement, pwd);
21276
21444
  });
21445
+ if (this.recommendedMinLengthCheck) {
21446
+ this.checkRequirement(this.recommendedMinLengthCheck, pwd);
21447
+ }
21277
21448
  this.combinedChecklist = [...this.basicChecklist, ...this.enhancedStrengthCheckList];
21278
21449
  this.onRequirementsFulfilled.emit(this.isPasswordValid());
21279
21450
  }
@@ -21281,30 +21452,61 @@ class PasswordCheckListComponent {
21281
21452
  const checklist = this.strengthEnforced ? this.combinedChecklist : this.basicChecklist;
21282
21453
  return checklist.every(requirement => requirement.icon !== 'radio-button-unchecked');
21283
21454
  }
21284
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordCheckListComponent, deps: [{ token: PasswordStrengthService }, { token: PasswordService }, { token: PasswordService }], target: i0.ɵɵFactoryTarget.Component }); }
21285
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PasswordCheckListComponent, isStandalone: true, selector: "c8y-password-check-list", inputs: { strengthEnforced: "strengthEnforced", password: "password" }, outputs: { onRequirementsFulfilled: "onRequirementsFulfilled" }, ngImport: i0, template: "<div *ngIf=\"strengthEnforced\">\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of combinedChecklist\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n</div>\n\n<div *ngIf=\"!strengthEnforced\">\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of basicChecklist\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n\n <div class=\"m-b-8\">\n {{ 'We recommend you to meet these conditions for a stronger password:' | translate }}\n </div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of enhancedStrengthCheckList\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
21455
+ updateMinGreenLength() {
21456
+ this.minGreenLength = this.strengthEnforced
21457
+ ? this.greenMinLength || this.defaultMinLength
21458
+ : this.defaultMinLength;
21459
+ if (!this.strengthEnforced && this.greenMinLength > this.defaultMinLength) {
21460
+ this.recommendedMinLength = this.greenMinLength;
21461
+ this.recommendedMinLengthCheck = {
21462
+ label: gettext$1('Have at least {{recommendedLength}} characters'),
21463
+ check: (password) => password.length >= this.recommendedMinLength,
21464
+ icon: '',
21465
+ contextualColor: '',
21466
+ textColor: ''
21467
+ };
21468
+ }
21469
+ else {
21470
+ this.recommendedMinLength = undefined;
21471
+ this.recommendedMinLengthCheck = undefined;
21472
+ }
21473
+ }
21474
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordCheckListComponent, deps: [{ token: PasswordStrengthService }, { token: PasswordService }], target: i0.ɵɵFactoryTarget.Component }); }
21475
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PasswordCheckListComponent, isStandalone: true, selector: "c8y-password-check-list", inputs: { strengthEnforced: "strengthEnforced", password: "password", greenMinLength: "greenMinLength" }, outputs: { onRequirementsFulfilled: "onRequirementsFulfilled" }, usesOnChanges: true, ngImport: i0, template: "@if (strengthEnforced) {\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n @for (requirement of combinedChecklist; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n} @else {\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n @for (requirement of basicChecklist; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n\n <div class=\"m-b-8\">\n {{ 'We recommend you to meet these conditions for a stronger password:' | translate }}\n </div>\n <ul class=\"list-unstyled\">\n @if (recommendedMinLengthCheck) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ recommendedMinLengthCheck.contextualColor }}\"\n [c8yIcon]=\"recommendedMinLengthCheck.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ recommendedMinLengthCheck.textColor }}\"\n [translate]=\"recommendedMinLengthCheck.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n @for (requirement of enhancedStrengthCheckList; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n}\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
21286
21476
  }
21287
21477
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PasswordCheckListComponent, decorators: [{
21288
21478
  type: Component,
21289
- args: [{ selector: 'c8y-password-check-list', standalone: true, imports: [NgIf, NgFor, IconDirective, C8yTranslateDirective, C8yTranslatePipe], template: "<div *ngIf=\"strengthEnforced\">\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of combinedChecklist\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n</div>\n\n<div *ngIf=\"!strengthEnforced\">\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of basicChecklist\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n\n <div class=\"m-b-8\">\n {{ 'We recommend you to meet these conditions for a stronger password:' | translate }}\n </div>\n <ul class=\"list-unstyled\">\n <li\n class=\"small d-flex\"\n *ngFor=\"let requirement of enhancedStrengthCheckList\"\n >\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n </ul>\n</div>\n" }]
21290
- }], ctorParameters: () => [{ type: PasswordStrengthService }, { type: PasswordService }, { type: PasswordService }], propDecorators: { strengthEnforced: [{
21479
+ args: [{ selector: 'c8y-password-check-list', standalone: true, imports: [IconDirective, C8yTranslateDirective, C8yTranslatePipe], template: "@if (strengthEnforced) {\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n @for (requirement of combinedChecklist; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n} @else {\n <div class=\"m-b-8\">{{ 'Password must meet the requirements below:' | translate }}</div>\n <ul class=\"list-unstyled\">\n @for (requirement of basicChecklist; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n\n <div class=\"m-b-8\">\n {{ 'We recommend you to meet these conditions for a stronger password:' | translate }}\n </div>\n <ul class=\"list-unstyled\">\n @if (recommendedMinLengthCheck) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ recommendedMinLengthCheck.contextualColor }}\"\n [c8yIcon]=\"recommendedMinLengthCheck.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ recommendedMinLengthCheck.textColor }}\"\n [translate]=\"recommendedMinLengthCheck.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n @for (requirement of enhancedStrengthCheckList; track requirement.label) {\n <li class=\"small d-flex\">\n <i\n class=\"{{ requirement.contextualColor }}\"\n [c8yIcon]=\"requirement.icon\"\n ></i>\n <span\n class=\"m-l-4 small {{ requirement.textColor }}\"\n [translate]=\"requirement.label\"\n [translateParams]=\"this.translateParams\"\n ></span>\n </li>\n }\n </ul>\n}\n" }]
21480
+ }], ctorParameters: () => [{ type: PasswordStrengthService }, { type: PasswordService }], propDecorators: { strengthEnforced: [{
21291
21481
  type: Input
21292
21482
  }], password: [{
21293
- type: Input,
21294
- args: ['password']
21483
+ type: Input
21484
+ }], greenMinLength: [{
21485
+ type: Input
21295
21486
  }], onRequirementsFulfilled: [{
21296
21487
  type: Output
21297
21488
  }] } });
21298
21489
 
21299
21490
  class NewPasswordComponent {
21491
+ /**
21492
+ * Returns effective min length for validation:
21493
+ * - When enforceStrength=true: use greenMinLength (or default 8)
21494
+ * - When enforceStrength=false: always use default 8
21495
+ */
21496
+ get effectiveMinLength() {
21497
+ return this.passwordEnforced
21498
+ ? this.minlength || this.DEFAULT_MIN_LENGTH
21499
+ : this.DEFAULT_MIN_LENGTH;
21500
+ }
21300
21501
  set _newPasswordModel(ngModel) {
21301
21502
  if (ngModel) {
21302
21503
  this.newPasswordModel = ngModel;
21303
21504
  ngModel.control.addValidators(this.passwordChecklistValidator);
21304
21505
  }
21305
21506
  }
21306
- constructor(passwordStrength, cdRef, elementRef) {
21507
+ constructor(passwordStrength, passwordValidation, cdRef, elementRef) {
21307
21508
  this.passwordStrength = passwordStrength;
21509
+ this.passwordValidation = passwordValidation;
21308
21510
  this.cdRef = cdRef;
21309
21511
  this.elementRef = elementRef;
21310
21512
  this.password = new EventEmitter();
@@ -21312,13 +21514,22 @@ class NewPasswordComponent {
21312
21514
  this.model = {};
21313
21515
  this.changePassword = false;
21314
21516
  this.passwordEnforced = false;
21315
- this.passwordChecklistValidator = () => this.requirementsFulfilled ? null : { passwordStrengthChecklist: true };
21517
+ this.DEFAULT_MIN_LENGTH = 8;
21518
+ // Only enforce checklist validation when password strength is enforced.
21519
+ // When not enforced, checklist is just informational/recommendations.
21520
+ this.passwordChecklistValidator = control => !this.passwordEnforced || this.requirementsFulfilled || !control.value
21521
+ ? null
21522
+ : { passwordStrengthChecklist: true };
21316
21523
  }
21317
- ngOnInit() {
21318
- this.loadPasswordStrengthSettings();
21319
- this.passwordStrength.getGreenMinLength().then(value => {
21320
- this.minlength = value;
21321
- });
21524
+ async ngOnInit() {
21525
+ try {
21526
+ await this.loadPasswordStrengthSettings();
21527
+ this.minlength = await this.passwordStrength.getGreenMinLength();
21528
+ }
21529
+ catch (e) {
21530
+ this.passwordEnforced = false;
21531
+ this.minlength = this.DEFAULT_MIN_LENGTH;
21532
+ }
21322
21533
  }
21323
21534
  async ngOnChanges(changes) {
21324
21535
  if (changes.showChangePasswordButton) {
@@ -21337,12 +21548,29 @@ class NewPasswordComponent {
21337
21548
  updateValidity(requirementsFulfilled) {
21338
21549
  this.requirementsFulfilled = requirementsFulfilled;
21339
21550
  this.cdRef.detectChanges();
21551
+ if (!this.newPasswordModel) {
21552
+ return;
21553
+ }
21340
21554
  this.newPasswordModel.control.updateValueAndValidity();
21341
- // There are two validators checking password validity, but we only want to show one of these errors at a time,
21342
- // where checklist validator takes priority.
21343
- if (!this.requirementsFulfilled) {
21344
- delete this.newPasswordModel.control.errors['password'];
21555
+ const errors = this.newPasswordModel.control.errors;
21556
+ if (!errors || !this.passwordEnforced) {
21557
+ return;
21558
+ }
21559
+ // Check if password has invalid characters (pattern error should take priority)
21560
+ const password = this.model.newPassword || '';
21561
+ const hasInvalidChars = password && !this.passwordValidation.hasValidCharsOnly(password);
21562
+ const filteredErrors = { ...errors };
21563
+ if (!this.requirementsFulfilled && !hasInvalidChars) {
21564
+ // Checklist not fulfilled AND no invalid chars - show checklist error, hide pattern errors
21565
+ delete filteredErrors['password'];
21566
+ delete filteredErrors['passwordSimple'];
21345
21567
  }
21568
+ else if (filteredErrors['password'] || filteredErrors['passwordSimple']) {
21569
+ // Pattern error (invalid chars or checklist fulfilled) - show pattern error, hide checklist
21570
+ delete filteredErrors['passwordStrengthChecklist'];
21571
+ }
21572
+ const remaining = Object.keys(filteredErrors).length ? filteredErrors : null;
21573
+ this.newPasswordModel.control.setErrors(remaining);
21346
21574
  }
21347
21575
  async loadPasswordStrengthSettings() {
21348
21576
  if (this.requireStrongPassword) {
@@ -21362,23 +21590,22 @@ class NewPasswordComponent {
21362
21590
  this.model = {};
21363
21591
  }
21364
21592
  }
21365
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NewPasswordComponent, deps: [{ token: PasswordStrengthService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
21366
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: NewPasswordComponent, isStandalone: true, selector: "c8y-new-password", inputs: { showChangePasswordButton: "showChangePasswordButton", requireStrongPassword: "requireStrongPassword" }, outputs: { password: "password" }, viewQueries: [{ propertyName: "_newPasswordModel", first: true, predicate: ["newPassword"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: PasswordInputComponent, selector: "c8y-password-input", inputs: ["id", "autocomplete", "large"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: PasswordConfirm, selector: "[passwordConfirm]" }, { kind: "component", type: PasswordCheckListComponent, selector: "c8y-password-check-list", inputs: ["strengthEnforced", "password"], outputs: ["onRequirementsFulfilled"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
21593
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NewPasswordComponent, deps: [{ token: PasswordStrengthService }, { token: PasswordValidationService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
21594
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: NewPasswordComponent, isStandalone: true, selector: "c8y-new-password", inputs: { showChangePasswordButton: "showChangePasswordButton", requireStrongPassword: "requireStrongPassword" }, outputs: { password: "password" }, viewQueries: [{ propertyName: "_newPasswordModel", first: true, predicate: ["newPassword"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (showChangePasswordButton) {\n <div class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n @if (!changePassword) {\n {{ 'Change password' | translate }}\n } @else {\n {{ 'Cancel password change' | translate }}\n }\n </button>\n </div>\n}\n\n@if (changePassword) {\n <div class=\"row content-flex-50\">\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yPasswordValidation\n [passwordStrengthEnforced]=\"passwordEnforced\"\n [minLength]=\"effectiveMinLength\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n </div>\n}\n", dependencies: [{ kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: PasswordInputComponent, selector: "c8y-password-input", inputs: ["id", "autocomplete", "large"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: PasswordValidationDirective, selector: "[c8yPasswordValidation]", inputs: ["passwordStrengthEnforced", "minLength"] }, { kind: "directive", type: PasswordConfirm, selector: "[passwordConfirm]" }, { kind: "component", type: PasswordCheckListComponent, selector: "c8y-password-check-list", inputs: ["strengthEnforced", "password", "greenMinLength"], outputs: ["onRequirementsFulfilled"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
21367
21595
  }
21368
21596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NewPasswordComponent, decorators: [{
21369
21597
  type: Component,
21370
21598
  args: [{ selector: 'c8y-new-password', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
21371
- NgIf,
21372
21599
  FormGroupComponent,
21373
21600
  C8yTranslateDirective,
21374
21601
  PasswordInputComponent,
21375
21602
  FormsModule$1,
21376
- DefaultValidationDirective,
21603
+ PasswordValidationDirective,
21377
21604
  PasswordConfirm,
21378
21605
  PasswordCheckListComponent,
21379
21606
  C8yTranslatePipe
21380
- ], template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n" }]
21381
- }], ctorParameters: () => [{ type: PasswordStrengthService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { password: [{
21607
+ ], template: "@if (showChangePasswordButton) {\n <div class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n @if (!changePassword) {\n {{ 'Change password' | translate }}\n } @else {\n {{ 'Cancel password change' | translate }}\n }\n </button>\n </div>\n}\n\n@if (changePassword) {\n <div class=\"row content-flex-50\">\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yPasswordValidation\n [passwordStrengthEnforced]=\"passwordEnforced\"\n [minLength]=\"effectiveMinLength\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n </div>\n}\n" }]
21608
+ }], ctorParameters: () => [{ type: PasswordStrengthService }, { type: PasswordValidationService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { password: [{
21382
21609
  type: Output
21383
21610
  }], showChangePasswordButton: [{
21384
21611
  type: Input
@@ -23861,7 +24088,9 @@ class PasswordStrengthCheckerService {
23861
24088
  return password.search(/[0-9]/) !== -1;
23862
24089
  }
23863
24090
  hasSpecialChars(password) {
23864
- return password.search(/[^0-9a-zA-Z]+/) !== -1;
24091
+ // Only match ALLOWED symbols, not any non-alphanumeric character
24092
+ // Allowed: `~!@#$%^&*()_|+-=?;:'",.<>{}[]\\/
24093
+ return password.search(/[`~!@#$%^&*()_|+\-=?;:'",.<>{}\[\]\\/]/) !== -1;
23865
24094
  }
23866
24095
  getStrengthColor(password) {
23867
24096
  const passwordStrength = filter$2([
@@ -38611,7 +38840,7 @@ class AssetTypesService {
38611
38840
  */
38612
38841
  getIcon(type) {
38613
38842
  const assetType = this.getAssetTypeByName(type);
38614
- return assetType?.c8y_IsAssetType?.icon?.name || this.DEFAULT_ASSET_ICON;
38843
+ return (assetType?.c8y_IsAssetType?.icon?.name || assetType?.icon?.name || this.DEFAULT_ASSET_ICON);
38615
38844
  }
38616
38845
  /**
38617
38846
  * Add an asset type to the local cache.
@@ -39647,5 +39876,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
39647
39876
  * Generated bundle index. Do not edit.
39648
39877
  */
39649
39878
 
39650
- export { ACTIONS_STEPPER, AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, ARRAY_VALIDATION_PREFIX, ASSET_PATH, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionControlsExtensionService, ActionModule, ActionOutletComponent, ActionService, AggregationPickerComponent, AggregationService, AlarmRealtimeService, AlarmWithChildrenRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppHrefPipe, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherInlineComponent, AppSwitcherService, ApplicationModule, ApplicationPluginStatus, AssetHierarchyService, AssetLinkPipe, AssetPropertyService, AssetTypesRealtimeService, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BooleanFilterMapper, BootstrapComponent, BootstrapModule, BottomDrawerComponent, BottomDrawerRef, BottomDrawerService, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BuiltInActionType, BytesPipe, C8Y_PLUGIN_CONTEXT_PATH, C8Y_PLUGIN_NAME, C8yComponentOutlet, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yTranslationCache, C8yTranslationLoader, C8yValidators, CUSTOM, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangeCurrentUserPasswordService, ChangeIconComponent, ClipboardModule, ClipboardService, ColorInputComponent, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CopyDashboardDisabledReason, CoreModule, CoreSearchModule, CountdownIntervalComponent, CountdownIntervalModule, CurrentPasswordModalComponent, CustomColumn, CustomTranslateService, CustomTranslateStore, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DEFAULT_INTERVAL_STATE, DEFAULT_INTERVAL_VALUE, DEFAULT_INTERVAL_VALUES, DRAWER_ANIMATION_TIME, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatapointSyncService, DateContextQueryParamNames, DateFilterMapper, DateFormatService, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DrawerModule, DrawerOutletComponent, DrawerService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DropdownFocusTrapDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentAlertsComponent, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EmptyStateContextDirective, EventRealtimeService, ExpandableRowDirective, ExtensionPointForPlugins, ExtensionPointWithoutStateForPlugins, ExtractArrayValidationErrorsPipe, FeatureCacheService, FeedbackFormComponent, FilePickerComponent, FilePickerFormControlComponent, FilePickerFormControlModule, FilePickerModule, FilesService, FilterByPipe, FilterInputComponent, FilterMapperFactory, FilterMapperModule, FilterMapperPipe, FilterMapperService, FilterNonArrayValidationErrorsPipe, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GLOBAL_CONTEXT_AUTO_REFRESH, GainsightService, GenericFileIconPipe, GeoService, GetGroupIconPipe, GlobalConfigService, GridDataSource, GroupFragment, GroupService, GroupedFilterChips, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_CURRENT_APPLICATION, HOOK_CURRENT_TENANT, HOOK_CURRENT_USER, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_PLUGIN, HOOK_PREVIEW, HOOK_QUERY_PARAM, HOOK_QUERY_PARAM_BOTTOM_DRAWER, HOOK_QUERY_PARAM_MODAL, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, HumanizeValidationMessagePipe, I18nModule, INTERVAL_OPTIONS, IconDirective, IconPanelComponent, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InterAppService, IntervalBasedReload, InventorySearchService, IpRangeInputListComponent, JsonValidationPrettifierDirective, LANGUAGES, LAST_DAY, LAST_HOUR, LAST_MINUTE, LAST_MONTH, LAST_WEEK, LOCALE_PATH, LegacyGridConfigMapperService, LegendFieldWrapper, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, MAX_PAGE_SIZE, MESSAGES_CORE_I18N, MOChunkLoaderService, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageBannerService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, MoNamePipe, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NEW_DASHBOARD_ROUTER_STATE_PROP, NULL_VALUE_PLACEHOLDER, NUMBER_FORMAT_REGEXP, NameTransformPipe, NavigatorBottomModule, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NavigatorTopModule, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PREVIEW_FEATURE_PROVIDERS, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PackageType, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordInputComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthService, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginLoadedPipe, PluginsExportScopes, PluginsLoaderService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, PreviewFeatureButtonComponent, PreviewFeatureShowNotification, PreviewService, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, PropertyValueTransformService, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QUERY_PARAM_HANDLER_PROVIDERS, QueryParamBottomDrawerFactory, QueryParamBottomDrawerStateService, QueryParamHandlerService, QueryParamModalFactory, QueryParamModalStateService, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RadioFilterMapper, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeControlComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RelativeTimePipe, RequiredInputPlaceholderDirective, ResizableGridComponent, ResolverServerError, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SHOW_PREVIEW_FEATURES, SearchComponent, SearchFilters, SearchInputComponent, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent, SelectFilterMapper, SelectItemDirective, SelectKeyboardService, SelectLegacyComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SelectedItemsComponent, SelectedItemsDirective, SendStatus, SendStatusLabels, ServiceRegistry, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SimplifiedAuthService, SkipLinkDirective, SplitViewAlertsComponent, SplitViewComponent, SplitViewDetailsActionsComponent, SplitViewDetailsComponent, SplitViewExtraHeaderComponent, SplitViewFooterComponent, SplitViewHeaderActionsComponent, SplitViewListComponent, SplitViewListItemDirective, SplitViewSelectionService, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StringFilterMapper, StringifyObjectPipe, StripHtmlPipe, SupportedApps, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, ThemeSwitcherService, TimeIntervalComponent, TimePickerComponent, TimePickerModule, TitleComponent, TitleOutletComponent, TotpChallengeComponent, TotpSetupComponent, TranslateService, TreeNodeCellRendererComponent, TreeNodeColumn, TreeNodeHeaderCellRendererComponent, TypeaheadComponent, TypeaheadFilterMapper, UiSettingsComponent, UiSettingsModule, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserEngagementsService, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, VisibleControlsPipe, WIDGET_CONFIGURATION_GRID_SIZE, WIDGET_TYPE_VALUES, WILDCARD_SEARCH_FEATURE_KEY, WebSDKVersionFactory, WidgetActionWrapperComponent, WidgetGlobalAutoRefreshService, WidgetTimeContextActionBarPriority, WidgetTimeContextComponent, WidgetTimeContextDateRangeService, WidgetTimeContextMediatorService, WidgetsDashboardComponent, WidgetsDashboardEventService, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _virtualScrollWindowStrategyFactory, alertOnError, allEntriesAreEqual, asyncValidateArrayElements, colorValidator, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getDictionaryWithTrimmedKeys, getInjectedHooks, gettext, globalAutoRefreshLoading, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookCurrentApplication, hookCurrentTenant, hookCurrentUser, hookDataGridActionControls, hookDocs, hookDrawer, hookDynamicProviderConfig, hookFilterMapper, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookPlugin, hookPreview, hookQueryParam, hookQueryParamBottomDrawer, hookQueryParamModal, hookRoute, hookSearch, hookService, hookStepper, hookTab, hookUserMenu, hookVersion, hookWidget, hookWizard, internalApps, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, provideBootstrapMetadata, provideCommonPipes, provideCommonServices, provideDefaultOptionsAppInitializer, provideI18n, provideLanguageSelectorAppInitializer, providePluginsLoaderServiceAppInitializer, provideTranslationServiceInstance, ratiosByColumnTypes, removeContextIndicators, removeDuplicatesIds, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, trimTranslationKey, uniqueInCollectionByPathValidator, validateArrayElements, validateInternationalPhoneNumber, viewContextRoutes, wrapperLegendFieldConfig };
39879
+ export { ACTIONS_STEPPER, AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, ARRAY_VALIDATION_PREFIX, ASSET_PATH, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionControlsExtensionService, ActionModule, ActionOutletComponent, ActionService, AggregationPickerComponent, AggregationService, AlarmRealtimeService, AlarmWithChildrenRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppHrefPipe, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherInlineComponent, AppSwitcherService, ApplicationModule, ApplicationPluginStatus, AssetHierarchyService, AssetLinkPipe, AssetPropertyService, AssetTypesRealtimeService, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BooleanFilterMapper, BootstrapComponent, BootstrapModule, BottomDrawerComponent, BottomDrawerRef, BottomDrawerService, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BuiltInActionType, BytesPipe, C8Y_PLUGIN_CONTEXT_PATH, C8Y_PLUGIN_NAME, C8yComponentOutlet, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yTranslationCache, C8yTranslationLoader, C8yValidators, CUSTOM, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangeCurrentUserPasswordService, ChangeIconComponent, ClipboardModule, ClipboardService, ColorInputComponent, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CopyDashboardDisabledReason, CoreModule, CoreSearchModule, CountdownIntervalComponent, CountdownIntervalModule, CurrentPasswordModalComponent, CustomColumn, CustomTranslateService, CustomTranslateStore, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DEFAULT_INTERVAL_STATE, DEFAULT_INTERVAL_VALUE, DEFAULT_INTERVAL_VALUES, DRAWER_ANIMATION_TIME, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatapointSyncService, DateContextQueryParamNames, DateFilterMapper, DateFormatService, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DrawerModule, DrawerOutletComponent, DrawerService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DropdownFocusTrapDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentAlertsComponent, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EmptyStateContextDirective, EventRealtimeService, ExpandableRowDirective, ExtensionPointForPlugins, ExtensionPointWithoutStateForPlugins, ExtractArrayValidationErrorsPipe, FeatureCacheService, FeedbackFormComponent, FilePickerComponent, FilePickerFormControlComponent, FilePickerFormControlModule, FilePickerModule, FilesService, FilterByPipe, FilterInputComponent, FilterMapperFactory, FilterMapperModule, FilterMapperPipe, FilterMapperService, FilterNonArrayValidationErrorsPipe, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GLOBAL_CONTEXT_AUTO_REFRESH, GainsightService, GenericFileIconPipe, GeoService, GetGroupIconPipe, GlobalConfigService, GridDataSource, GroupFragment, GroupService, GroupedFilterChips, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_CURRENT_APPLICATION, HOOK_CURRENT_TENANT, HOOK_CURRENT_USER, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_PLUGIN, HOOK_PREVIEW, HOOK_QUERY_PARAM, HOOK_QUERY_PARAM_BOTTOM_DRAWER, HOOK_QUERY_PARAM_MODAL, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, HumanizeValidationMessagePipe, I18nModule, INTERVAL_OPTIONS, IconDirective, IconPanelComponent, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InterAppService, IntervalBasedReload, InventorySearchService, IpRangeInputListComponent, JsonValidationPrettifierDirective, LANGUAGES, LAST_DAY, LAST_HOUR, LAST_MINUTE, LAST_MONTH, LAST_WEEK, LOCALE_PATH, LegacyGridConfigMapperService, LegendFieldWrapper, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, MAX_PAGE_SIZE, MESSAGES_CORE_I18N, MOChunkLoaderService, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageBannerService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, MoNamePipe, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NEW_DASHBOARD_ROUTER_STATE_PROP, NULL_VALUE_PLACEHOLDER, NUMBER_FORMAT_REGEXP, NameTransformPipe, NavigatorBottomModule, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NavigatorTopModule, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PREVIEW_FEATURE_PROVIDERS, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PackageType, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordInputComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthService, PasswordValidationDirective, PasswordValidationService, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginLoadedPipe, PluginsExportScopes, PluginsLoaderService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, PreviewFeatureButtonComponent, PreviewFeatureShowNotification, PreviewService, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, PropertyValueTransformService, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QUERY_PARAM_HANDLER_PROVIDERS, QueryParamBottomDrawerFactory, QueryParamBottomDrawerStateService, QueryParamHandlerService, QueryParamModalFactory, QueryParamModalStateService, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RadioFilterMapper, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeControlComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RelativeTimePipe, RequiredInputPlaceholderDirective, ResizableGridComponent, ResolverServerError, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SHOW_PREVIEW_FEATURES, SearchComponent, SearchFilters, SearchInputComponent, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent, SelectFilterMapper, SelectItemDirective, SelectKeyboardService, SelectLegacyComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SelectedItemsComponent, SelectedItemsDirective, SendStatus, SendStatusLabels, ServiceRegistry, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SimplifiedAuthService, SkipLinkDirective, SplitViewAlertsComponent, SplitViewComponent, SplitViewDetailsActionsComponent, SplitViewDetailsComponent, SplitViewExtraHeaderComponent, SplitViewFooterComponent, SplitViewHeaderActionsComponent, SplitViewListComponent, SplitViewListItemDirective, SplitViewSelectionService, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StringFilterMapper, StringifyObjectPipe, StripHtmlPipe, SupportedApps, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, ThemeSwitcherService, TimeIntervalComponent, TimePickerComponent, TimePickerModule, TitleComponent, TitleOutletComponent, TotpChallengeComponent, TotpSetupComponent, TranslateService, TreeNodeCellRendererComponent, TreeNodeColumn, TreeNodeHeaderCellRendererComponent, TypeaheadComponent, TypeaheadFilterMapper, UiSettingsComponent, UiSettingsModule, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserEngagementsService, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, VisibleControlsPipe, WIDGET_CONFIGURATION_GRID_SIZE, WIDGET_TYPE_VALUES, WILDCARD_SEARCH_FEATURE_KEY, WebSDKVersionFactory, WidgetActionWrapperComponent, WidgetGlobalAutoRefreshService, WidgetTimeContextActionBarPriority, WidgetTimeContextComponent, WidgetTimeContextDateRangeService, WidgetTimeContextMediatorService, WidgetsDashboardComponent, WidgetsDashboardEventService, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _virtualScrollWindowStrategyFactory, alertOnError, allEntriesAreEqual, asyncValidateArrayElements, colorValidator, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getDictionaryWithTrimmedKeys, getInjectedHooks, gettext, globalAutoRefreshLoading, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookCurrentApplication, hookCurrentTenant, hookCurrentUser, hookDataGridActionControls, hookDocs, hookDrawer, hookDynamicProviderConfig, hookFilterMapper, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookPlugin, hookPreview, hookQueryParam, hookQueryParamBottomDrawer, hookQueryParamModal, hookRoute, hookSearch, hookService, hookStepper, hookTab, hookUserMenu, hookVersion, hookWidget, hookWizard, internalApps, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, provideBootstrapMetadata, provideCommonPipes, provideCommonServices, provideDefaultOptionsAppInitializer, provideI18n, provideLanguageSelectorAppInitializer, providePluginsLoaderServiceAppInitializer, provideTranslationServiceInstance, ratiosByColumnTypes, removeContextIndicators, removeDuplicatesIds, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, trimTranslationKey, uniqueInCollectionByPathValidator, validateArrayElements, validateInternationalPhoneNumber, viewContextRoutes, wrapperLegendFieldConfig };
39651
39880
  //# sourceMappingURL=c8y-ngx-components.mjs.map