nexheal-lib 0.0.70 → 0.0.71

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.
@@ -3061,6 +3061,7 @@ class PaginatedAutocompleteControl {
3061
3061
  required = false;
3062
3062
  placeholder = "";
3063
3063
  customClass = '';
3064
+ showSearchIcon = true;
3064
3065
  clearVal = true;
3065
3066
  error = false;
3066
3067
  errorMessage = "";
@@ -3073,6 +3074,11 @@ class PaginatedAutocompleteControl {
3073
3074
  paginationType = 'scroll';
3074
3075
  pageSize = 10;
3075
3076
  searchDebounce = 300;
3077
+ /**
3078
+ * Min trimmed length before page-1 search. When omitted, search runs only from the
3079
+ * search icon (and Enter). Empty search always allowed. Use 0 for type-to-search with no minimum.
3080
+ */
3081
+ minSearchLength;
3076
3082
  /** Re-fetch page 1 every time the dropdown opens, instead of reusing cached results */
3077
3083
  refreshOnOpen = false;
3078
3084
  /** Total record count for the current search, from the API response */
@@ -3127,12 +3133,15 @@ class PaginatedAutocompleteControl {
3127
3133
  this._disabled = value;
3128
3134
  if (this.inputControl) {
3129
3135
  if (value) {
3130
- this.inputControl.disable();
3136
+ this.inputControl.disable({ emitEvent: false });
3131
3137
  }
3132
3138
  else {
3133
- this.inputControl.enable();
3139
+ this.inputControl.enable({ emitEvent: false });
3134
3140
  }
3135
3141
  }
3142
+ if (value) {
3143
+ this.onControlDisabled();
3144
+ }
3136
3145
  }
3137
3146
  pageChange = new EventEmitter();
3138
3147
  optionSelected = new EventEmitter();
@@ -3174,6 +3183,12 @@ class PaginatedAutocompleteControl {
3174
3183
  get pageRangeEnd() {
3175
3184
  return Math.min((this.currentPage - 1) * this.pageSize + this._displayedOptions.length, this.totalCount);
3176
3185
  }
3186
+ get controlDisabled() {
3187
+ return this._disabled || this.inputControl.disabled;
3188
+ }
3189
+ get searchOnButtonOnly() {
3190
+ return this.minSearchLength === undefined;
3191
+ }
3177
3192
  constructor() { }
3178
3193
  ngOnInit() {
3179
3194
  this.inputControl.markAsPristine();
@@ -3185,8 +3200,12 @@ class PaginatedAutocompleteControl {
3185
3200
  // A selection happened after this keystroke — drop the search
3186
3201
  if (this.cancelPendingSearch)
3187
3202
  return;
3188
- if (this.readonly || !this.hasFocus)
3203
+ if (this.searchOnButtonOnly ||
3204
+ this.readonly ||
3205
+ this.controlDisabled ||
3206
+ !this.hasFocus) {
3189
3207
  return;
3208
+ }
3190
3209
  this.loadPage(1, value);
3191
3210
  }));
3192
3211
  }
@@ -3234,15 +3253,51 @@ class PaginatedAutocompleteControl {
3234
3253
  this.onTouched = fn;
3235
3254
  }
3236
3255
  setDisabledState(isDisabled) {
3256
+ this._disabled = isDisabled;
3237
3257
  if (isDisabled) {
3238
- this.inputControl.disable();
3258
+ this.inputControl.disable({ emitEvent: false });
3259
+ this.onControlDisabled();
3239
3260
  }
3240
3261
  else {
3241
- this.inputControl.enable();
3262
+ this.inputControl.enable({ emitEvent: false });
3242
3263
  }
3243
3264
  }
3265
+ onControlDisabled() {
3266
+ this.isPageLoading = false;
3267
+ this.isDropdownOpen = false;
3268
+ this.hasFocus = false;
3269
+ }
3244
3270
  // paging
3271
+ isSearchAllowed(search) {
3272
+ if (this.minSearchLength == null || this.minSearchLength <= 0) {
3273
+ return true;
3274
+ }
3275
+ const trimmed = search.trim();
3276
+ if (trimmed.length === 0) {
3277
+ return true;
3278
+ }
3279
+ return trimmed.length >= this.minSearchLength;
3280
+ }
3281
+ handleSearchBelowMinLength() {
3282
+ this.isPageLoading = false;
3283
+ this.isDropdownOpen = false;
3284
+ this.loadErrorMessage = null;
3285
+ this.failedPage = null;
3286
+ this._displayedOptions = [];
3287
+ this.currentPage = 1;
3288
+ this._pendingPage = 1;
3289
+ this.pageCache.clear();
3290
+ this.highlightedIndex = null;
3291
+ }
3245
3292
  loadPage(page, search) {
3293
+ if (this.readonly || this.controlDisabled) {
3294
+ this.isPageLoading = false;
3295
+ return;
3296
+ }
3297
+ if (page === 1 && !this.isSearchAllowed(search)) {
3298
+ this.handleSearchBelowMinLength();
3299
+ return;
3300
+ }
3246
3301
  this.currentPage = page;
3247
3302
  this._pendingPage = page;
3248
3303
  if (page === 1) {
@@ -3358,7 +3413,7 @@ class PaginatedAutocompleteControl {
3358
3413
  }
3359
3414
  // events
3360
3415
  onUserType(event) {
3361
- if (this.readonly)
3416
+ if (this.readonly || this.controlDisabled)
3362
3417
  return;
3363
3418
  // A real keystroke re-arms searching after any selection cancelled it
3364
3419
  this.cancelPendingSearch = false;
@@ -3366,17 +3421,31 @@ class PaginatedAutocompleteControl {
3366
3421
  }
3367
3422
  onFocus() {
3368
3423
  this.hasFocus = true;
3369
- if (this.readonly || this.isDropdownOpen)
3424
+ if (this.readonly || this.controlDisabled || this.isDropdownOpen)
3370
3425
  return;
3371
3426
  this.openWithSearch();
3372
3427
  }
3373
3428
  onInputClick() {
3374
- if (this.readonly || this.isDropdownOpen)
3429
+ if (this.readonly || this.controlDisabled || this.isDropdownOpen)
3375
3430
  return;
3376
3431
  if (this.hasFocus) {
3377
3432
  this.openWithSearch();
3378
3433
  }
3379
3434
  }
3435
+ onSearchIconClick(event) {
3436
+ event.preventDefault();
3437
+ event.stopPropagation();
3438
+ this.inputElement?.nativeElement.focus();
3439
+ this.runSearchAction();
3440
+ }
3441
+ runSearchAction() {
3442
+ if (this.readonly || this.controlDisabled) {
3443
+ return;
3444
+ }
3445
+ this.cancelPendingSearch = false;
3446
+ this.hasFocus = true;
3447
+ this.loadPage(1, this.openSearchTerm());
3448
+ }
3380
3449
  /** Text to search with when the dropdown opens: if the input just holds the
3381
3450
  * selected item's display text, open with the full list instead. */
3382
3451
  openSearchTerm() {
@@ -3387,21 +3456,34 @@ class PaginatedAutocompleteControl {
3387
3456
  }
3388
3457
  return value;
3389
3458
  }
3459
+ tryReopenCachedSearch(term) {
3460
+ if (this.refreshOnOpen ||
3461
+ this.lastLoadedSearch !== term ||
3462
+ this._displayedOptions.length === 0) {
3463
+ return false;
3464
+ }
3465
+ this.isPageLoading = false;
3466
+ this.openDropdown();
3467
+ if (this.paginationType === 'arrow') {
3468
+ this.showCachedPage(1);
3469
+ }
3470
+ const idx = this.selectedItems
3471
+ ? this._displayedOptions.findIndex((o) => o.id === this.selectedItems.id)
3472
+ : -1;
3473
+ this.highlightedIndex =
3474
+ idx >= 0 ? idx : this._displayedOptions.length > 0 ? 0 : null;
3475
+ return true;
3476
+ }
3390
3477
  openWithSearch() {
3478
+ if (this.readonly || this.controlDisabled) {
3479
+ return;
3480
+ }
3391
3481
  const term = this.openSearchTerm();
3392
- // Reuse cached results when reopening with the same search term
3393
- if (!this.refreshOnOpen &&
3394
- this.lastLoadedSearch === term &&
3395
- this._displayedOptions.length > 0) {
3396
- this.openDropdown();
3397
- if (this.paginationType === 'arrow') {
3398
- this.showCachedPage(1);
3399
- }
3400
- const idx = this.selectedItems
3401
- ? this._displayedOptions.findIndex((o) => o.id === this.selectedItems.id)
3402
- : -1;
3403
- this.highlightedIndex =
3404
- idx >= 0 ? idx : this._displayedOptions.length > 0 ? 0 : null;
3482
+ if (this.searchOnButtonOnly) {
3483
+ this.tryReopenCachedSearch(term);
3484
+ return;
3485
+ }
3486
+ if (this.tryReopenCachedSearch(term)) {
3405
3487
  return;
3406
3488
  }
3407
3489
  this.loadPage(1, term);
@@ -3452,6 +3534,10 @@ class PaginatedAutocompleteControl {
3452
3534
  }
3453
3535
  onKeyDown(event) {
3454
3536
  if (!this.isDropdownOpen) {
3537
+ if (this.searchOnButtonOnly && event.key === "Enter") {
3538
+ event.preventDefault();
3539
+ this.runSearchAction();
3540
+ }
3455
3541
  return;
3456
3542
  }
3457
3543
  switch (event.key) {
@@ -3568,18 +3654,26 @@ class PaginatedAutocompleteControl {
3568
3654
  this.valueBuffer = null;
3569
3655
  this.onChange(null);
3570
3656
  this.selectionCleared.emit();
3657
+ if (this.searchOnButtonOnly) {
3658
+ this.isDropdownOpen = false;
3659
+ this.isPageLoading = false;
3660
+ this._displayedOptions = [];
3661
+ this.pageCache.clear();
3662
+ this.lastLoadedSearch = null;
3663
+ return;
3664
+ }
3571
3665
  if (this.hasFocus) {
3572
3666
  this.loadPage(1, "");
3573
3667
  }
3574
3668
  }
3575
3669
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
3576
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PaginatedAutocompleteControl, isStandalone: true, selector: "paginated-autocomplete-control", inputs: { title: "title", required: "required", placeholder: "placeholder", customClass: "customClass", clearVal: "clearVal", error: "error", errorMessage: "errorMessage", autocomplete: "autocomplete", inputLoader: "inputLoader", readonly: "readonly", isAddNewItem: "isAddNewItem", optionDisplayProperty: "optionDisplayProperty", paginationType: "paginationType", pageSize: "pageSize", searchDebounce: "searchDebounce", refreshOnOpen: "refreshOnOpen", totalCount: "totalCount", options: "options", disabled: "disabled" }, outputs: { pageChange: "pageChange", optionSelected: "optionSelected", selectionCleared: "selectionCleared", blurEvent: "blurEvent", optionPatched: "optionPatched", addNewItemClicked: "addNewItemClicked" }, providers: [
3670
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PaginatedAutocompleteControl, isStandalone: true, selector: "paginated-autocomplete-control", inputs: { title: "title", required: "required", placeholder: "placeholder", customClass: "customClass", showSearchIcon: "showSearchIcon", clearVal: "clearVal", error: "error", errorMessage: "errorMessage", autocomplete: "autocomplete", inputLoader: "inputLoader", readonly: "readonly", isAddNewItem: "isAddNewItem", optionDisplayProperty: "optionDisplayProperty", paginationType: "paginationType", pageSize: "pageSize", searchDebounce: "searchDebounce", minSearchLength: "minSearchLength", refreshOnOpen: "refreshOnOpen", totalCount: "totalCount", options: "options", disabled: "disabled" }, outputs: { pageChange: "pageChange", optionSelected: "optionSelected", selectionCleared: "selectionCleared", blurEvent: "blurEvent", optionPatched: "optionPatched", addNewItemClicked: "addNewItemClicked" }, providers: [
3577
3671
  {
3578
3672
  provide: NG_VALUE_ACCESSOR,
3579
3673
  useExisting: PaginatedAutocompleteControl,
3580
3674
  multi: true,
3581
3675
  },
3582
- ], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }, { propertyName: "dropdownElement", first: true, predicate: ["dropdownElement"], descendants: true }], ngImport: i0, template: "<div class=\"form-group auto-complete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\r\n @if (title) {\r\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\r\n }\r\n\r\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\r\n (input)=\"onUserType($event)\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\r\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\r\n\r\n <span class=\"focus-border\"></span>\r\n\r\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\r\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if (true) {\r\n <div #dropdownElement class=\"option-list\" [class.fixed-height]=\"paginationType === 'arrow' && totalPages > 1\"\r\n (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\r\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"no-results\">\r\n <div>No results found</div>\r\n @if (isAddNewItem) {\r\n <div (click)=\"onAddNewItemClick()\" class=\"btn-new\">\r\n Add New Item\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @for (suggestion of options; track suggestion.id; let i = $index) {\r\n <div class=\"list-item\" [ngClass]=\"{\r\n 'active': suggestion === selectedItems,\r\n 'highlighted': highlightedIndex === i\r\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\r\n {{ suggestion[optionDisplayProperty] }}\r\n </div>\r\n }\r\n\r\n @if (isPageLoading) {\r\n <div class=\"list-loading\">Loading...</div>\r\n }\r\n\r\n @if (loadErrorMessage) {\r\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\r\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\r\n </div>\r\n }\r\n\r\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\r\n Load more ({{ options.length }} of {{ totalCount }})\r\n </div>\r\n }\r\n\r\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\r\n <div class=\"list-footer\" [class.pager-footer]=\"paginationType === 'arrow'\">\r\n @if (paginationType === 'arrow') {\r\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\r\n <span class=\"pager-nav\">\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\r\n <i class=\"he he-chevron-left\"></i>\r\n </span>\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\r\n <i class=\"he he-chevron-right\"></i>\r\n </span>\r\n </span>\r\n } @else {\r\n {{ options.length }} of {{ totalCount }}\r\n @if (hasMore && paginationType === 'scroll') {\r\n <span> \u00B7 scroll for more</span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n\r\n @if (error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n</div>\r\n", styles: [".form-group.auto-complete .form-control{padding-right:unset}.form-group.auto-complete .clear{right:7px}.form-group.auto-complete .option-list{max-height:220px;overflow-y:auto}.form-group.auto-complete .option-list.fixed-height{height:220px;display:flex;flex-direction:column}.form-group.auto-complete .option-list.fixed-height .list-item,.form-group.auto-complete .option-list.fixed-height .no-results,.form-group.auto-complete .option-list.fixed-height .list-loading,.form-group.auto-complete .option-list.fixed-height .load-error{flex-shrink:0}.form-group.auto-complete .option-list.fixed-height .list-footer{margin-top:auto}.form-group.auto-complete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.auto-complete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.auto-complete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.auto-complete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.auto-complete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.auto-complete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:4px;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;line-height:1;cursor:pointer;background-color:#fff}.form-group.auto-complete .option-list .list-footer .pager-btn .he{font-size:13px;color:#2ba599;font-weight:600}.form-group.auto-complete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled{border-color:transparent;cursor:default;pointer-events:none}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled .he{color:#ccc}.form-group.auto-complete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
3676
+ ], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }, { propertyName: "dropdownElement", first: true, predicate: ["dropdownElement"], descendants: true }], ngImport: i0, template: "<div class=\"form-group auto-complete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\"\r\n [class.with-search-icon]=\"showSearchIcon\">\r\n @if (title) {\r\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\r\n }\r\n\r\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\r\n (input)=\"onUserType($event)\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\r\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\r\n\r\n <span class=\"focus-border\"></span>\r\n\r\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\r\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if (showSearchIcon && !readonly && !controlDisabled) {\r\n <label class=\"rs-search\" (mousedown)=\"onOptionMouseDown()\" (click)=\"onSearchIconClick($event)\">\r\n <i class=\"he he-search\"></i>\r\n </label>\r\n } @else if (!inputLoader) {\r\n <label class=\"arrow\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </label>\r\n }\r\n\r\n @if (isDropdownOpen) {\r\n <div #dropdownElement class=\"option-list\" [class.fixed-height]=\"paginationType === 'arrow' && totalPages > 1\"\r\n (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\r\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"no-results\">\r\n <div>No results found</div>\r\n @if (isAddNewItem) {\r\n <div (click)=\"onAddNewItemClick()\" class=\"btn-new\">\r\n Add New Item\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @for (suggestion of options; track suggestion.id; let i = $index) {\r\n <div class=\"list-item\" [ngClass]=\"{\r\n 'active': suggestion === selectedItems,\r\n 'highlighted': highlightedIndex === i\r\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\r\n {{ suggestion[optionDisplayProperty] }}\r\n </div>\r\n }\r\n\r\n @if (isPageLoading) {\r\n <div class=\"list-loading\">Loading...</div>\r\n }\r\n\r\n @if (loadErrorMessage) {\r\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\r\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\r\n </div>\r\n }\r\n\r\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\r\n Load more ({{ options.length }} of {{ totalCount }})\r\n </div>\r\n }\r\n\r\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\r\n <div class=\"list-footer\" [class.pager-footer]=\"paginationType === 'arrow'\">\r\n @if (paginationType === 'arrow') {\r\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\r\n <span class=\"pager-nav\">\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\r\n <i class=\"he he-chevron-left\"></i>\r\n </span>\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\r\n <i class=\"he he-chevron-right\"></i>\r\n </span>\r\n </span>\r\n } @else {\r\n {{ options.length }} of {{ totalCount }}\r\n @if (hasMore && paginationType === 'scroll') {\r\n <span> \u00B7 scroll for more</span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n\r\n @if (error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n</div>\r\n", styles: [".form-group.auto-complete.with-search-icon .form-control{padding-right:4rem}.form-group.auto-complete.with-search-icon .rs-search{top:27px;right:7px;z-index:2;padding:5px;width:30px;height:30px;display:grid;cursor:pointer;position:absolute;border-radius:5px;place-items:center}.form-group.auto-complete.with-search-icon .rs-search i{font-size:16px;color:#807a7a}.form-group.auto-complete.with-search-icon .rs-search:hover{background:#ff7f5d1a}.form-group.auto-complete.with-search-icon .rs-search:hover i{color:#ff7f5d}.form-group.auto-complete.with-search-icon .clear{right:2.5rem}.form-group.auto-complete:not(.with-search-icon) .clear{right:7px}.form-group.auto-complete .option-list{max-height:220px;overflow-y:auto}.form-group.auto-complete .option-list.fixed-height{height:220px;display:flex;flex-direction:column}.form-group.auto-complete .option-list.fixed-height .list-item,.form-group.auto-complete .option-list.fixed-height .no-results,.form-group.auto-complete .option-list.fixed-height .list-loading,.form-group.auto-complete .option-list.fixed-height .load-error{flex-shrink:0}.form-group.auto-complete .option-list.fixed-height .list-footer{margin-top:auto}.form-group.auto-complete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.auto-complete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.auto-complete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.auto-complete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.auto-complete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.auto-complete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:4px;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;line-height:1;cursor:pointer;background-color:#fff}.form-group.auto-complete .option-list .list-footer .pager-btn .he{font-size:13px;color:#2ba599;font-weight:600}.form-group.auto-complete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled{border-color:transparent;cursor:default;pointer-events:none}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled .he{color:#ccc}.form-group.auto-complete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
3583
3677
  }
3584
3678
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, decorators: [{
3585
3679
  type: Component,
@@ -3589,7 +3683,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3589
3683
  useExisting: PaginatedAutocompleteControl,
3590
3684
  multi: true,
3591
3685
  },
3592
- ], template: "<div class=\"form-group auto-complete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\r\n @if (title) {\r\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\r\n }\r\n\r\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\r\n (input)=\"onUserType($event)\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\r\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\r\n\r\n <span class=\"focus-border\"></span>\r\n\r\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\r\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if (true) {\r\n <div #dropdownElement class=\"option-list\" [class.fixed-height]=\"paginationType === 'arrow' && totalPages > 1\"\r\n (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\r\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"no-results\">\r\n <div>No results found</div>\r\n @if (isAddNewItem) {\r\n <div (click)=\"onAddNewItemClick()\" class=\"btn-new\">\r\n Add New Item\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @for (suggestion of options; track suggestion.id; let i = $index) {\r\n <div class=\"list-item\" [ngClass]=\"{\r\n 'active': suggestion === selectedItems,\r\n 'highlighted': highlightedIndex === i\r\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\r\n {{ suggestion[optionDisplayProperty] }}\r\n </div>\r\n }\r\n\r\n @if (isPageLoading) {\r\n <div class=\"list-loading\">Loading...</div>\r\n }\r\n\r\n @if (loadErrorMessage) {\r\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\r\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\r\n </div>\r\n }\r\n\r\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\r\n Load more ({{ options.length }} of {{ totalCount }})\r\n </div>\r\n }\r\n\r\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\r\n <div class=\"list-footer\" [class.pager-footer]=\"paginationType === 'arrow'\">\r\n @if (paginationType === 'arrow') {\r\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\r\n <span class=\"pager-nav\">\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\r\n <i class=\"he he-chevron-left\"></i>\r\n </span>\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\r\n <i class=\"he he-chevron-right\"></i>\r\n </span>\r\n </span>\r\n } @else {\r\n {{ options.length }} of {{ totalCount }}\r\n @if (hasMore && paginationType === 'scroll') {\r\n <span> \u00B7 scroll for more</span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n\r\n @if (error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n</div>\r\n", styles: [".form-group.auto-complete .form-control{padding-right:unset}.form-group.auto-complete .clear{right:7px}.form-group.auto-complete .option-list{max-height:220px;overflow-y:auto}.form-group.auto-complete .option-list.fixed-height{height:220px;display:flex;flex-direction:column}.form-group.auto-complete .option-list.fixed-height .list-item,.form-group.auto-complete .option-list.fixed-height .no-results,.form-group.auto-complete .option-list.fixed-height .list-loading,.form-group.auto-complete .option-list.fixed-height .load-error{flex-shrink:0}.form-group.auto-complete .option-list.fixed-height .list-footer{margin-top:auto}.form-group.auto-complete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.auto-complete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.auto-complete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.auto-complete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.auto-complete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.auto-complete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:4px;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;line-height:1;cursor:pointer;background-color:#fff}.form-group.auto-complete .option-list .list-footer .pager-btn .he{font-size:13px;color:#2ba599;font-weight:600}.form-group.auto-complete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled{border-color:transparent;cursor:default;pointer-events:none}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled .he{color:#ccc}.form-group.auto-complete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\n"] }]
3686
+ ], template: "<div class=\"form-group auto-complete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\"\r\n [class.with-search-icon]=\"showSearchIcon\">\r\n @if (title) {\r\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\r\n }\r\n\r\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\r\n (input)=\"onUserType($event)\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\r\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\r\n\r\n <span class=\"focus-border\"></span>\r\n\r\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\r\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if (showSearchIcon && !readonly && !controlDisabled) {\r\n <label class=\"rs-search\" (mousedown)=\"onOptionMouseDown()\" (click)=\"onSearchIconClick($event)\">\r\n <i class=\"he he-search\"></i>\r\n </label>\r\n } @else if (!inputLoader) {\r\n <label class=\"arrow\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </label>\r\n }\r\n\r\n @if (isDropdownOpen) {\r\n <div #dropdownElement class=\"option-list\" [class.fixed-height]=\"paginationType === 'arrow' && totalPages > 1\"\r\n (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\r\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"no-results\">\r\n <div>No results found</div>\r\n @if (isAddNewItem) {\r\n <div (click)=\"onAddNewItemClick()\" class=\"btn-new\">\r\n Add New Item\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n @for (suggestion of options; track suggestion.id; let i = $index) {\r\n <div class=\"list-item\" [ngClass]=\"{\r\n 'active': suggestion === selectedItems,\r\n 'highlighted': highlightedIndex === i\r\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\r\n {{ suggestion[optionDisplayProperty] }}\r\n </div>\r\n }\r\n\r\n @if (isPageLoading) {\r\n <div class=\"list-loading\">Loading...</div>\r\n }\r\n\r\n @if (loadErrorMessage) {\r\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\r\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\r\n </div>\r\n }\r\n\r\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\r\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\r\n Load more ({{ options.length }} of {{ totalCount }})\r\n </div>\r\n }\r\n\r\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\r\n <div class=\"list-footer\" [class.pager-footer]=\"paginationType === 'arrow'\">\r\n @if (paginationType === 'arrow') {\r\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\r\n <span class=\"pager-nav\">\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\r\n <i class=\"he he-chevron-left\"></i>\r\n </span>\r\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\r\n <i class=\"he he-chevron-right\"></i>\r\n </span>\r\n </span>\r\n } @else {\r\n {{ options.length }} of {{ totalCount }}\r\n @if (hasMore && paginationType === 'scroll') {\r\n <span> \u00B7 scroll for more</span>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n\r\n @if (error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n</div>\r\n", styles: [".form-group.auto-complete.with-search-icon .form-control{padding-right:4rem}.form-group.auto-complete.with-search-icon .rs-search{top:27px;right:7px;z-index:2;padding:5px;width:30px;height:30px;display:grid;cursor:pointer;position:absolute;border-radius:5px;place-items:center}.form-group.auto-complete.with-search-icon .rs-search i{font-size:16px;color:#807a7a}.form-group.auto-complete.with-search-icon .rs-search:hover{background:#ff7f5d1a}.form-group.auto-complete.with-search-icon .rs-search:hover i{color:#ff7f5d}.form-group.auto-complete.with-search-icon .clear{right:2.5rem}.form-group.auto-complete:not(.with-search-icon) .clear{right:7px}.form-group.auto-complete .option-list{max-height:220px;overflow-y:auto}.form-group.auto-complete .option-list.fixed-height{height:220px;display:flex;flex-direction:column}.form-group.auto-complete .option-list.fixed-height .list-item,.form-group.auto-complete .option-list.fixed-height .no-results,.form-group.auto-complete .option-list.fixed-height .list-loading,.form-group.auto-complete .option-list.fixed-height .load-error{flex-shrink:0}.form-group.auto-complete .option-list.fixed-height .list-footer{margin-top:auto}.form-group.auto-complete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.auto-complete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.auto-complete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.auto-complete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.auto-complete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.auto-complete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.auto-complete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:4px;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;line-height:1;cursor:pointer;background-color:#fff}.form-group.auto-complete .option-list .list-footer .pager-btn .he{font-size:13px;color:#2ba599;font-weight:600}.form-group.auto-complete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled{border-color:transparent;cursor:default;pointer-events:none}.form-group.auto-complete .option-list .list-footer .pager-btn.disabled .he{color:#ccc}.form-group.auto-complete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\n"] }]
3593
3687
  }], ctorParameters: () => [], propDecorators: { title: [{
3594
3688
  type: Input
3595
3689
  }], required: [{
@@ -3598,6 +3692,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3598
3692
  type: Input
3599
3693
  }], customClass: [{
3600
3694
  type: Input
3695
+ }], showSearchIcon: [{
3696
+ type: Input
3601
3697
  }], clearVal: [{
3602
3698
  type: Input
3603
3699
  }], error: [{
@@ -3620,6 +3716,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3620
3716
  type: Input
3621
3717
  }], searchDebounce: [{
3622
3718
  type: Input
3719
+ }], minSearchLength: [{
3720
+ type: Input
3623
3721
  }], refreshOnOpen: [{
3624
3722
  type: Input
3625
3723
  }], totalCount: [{