nexheal-lib 0.0.45 → 0.0.48

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.
@@ -2791,10 +2791,13 @@ class PaginatedAutocompleteControl {
2791
2791
  paginationType = 'scroll';
2792
2792
  pageSize = 10;
2793
2793
  searchDebounce = 300;
2794
+ /** Re-fetch page 1 every time the dropdown opens, instead of reusing cached results */
2795
+ refreshOnOpen = false;
2794
2796
  /** Total record count for the current search, from the API response */
2795
2797
  totalCount = 0;
2796
2798
  _disabled = false;
2797
2799
  _pendingPage = 1;
2800
+ lastLoadedSearch = null;
2798
2801
  /** Items of the page just loaded. Page 1 replaces the list, later pages append. */
2799
2802
  _displayedOptions = [];
2800
2803
  set options(value) {
@@ -2811,6 +2814,8 @@ class PaginatedAutocompleteControl {
2811
2814
  ];
2812
2815
  }
2813
2816
  this.isPageLoading = false;
2817
+ this.loadErrorMessage = null;
2818
+ this.failedPage = null;
2814
2819
  this.processValueBuffer();
2815
2820
  if (this.isDropdownOpen) {
2816
2821
  if (this._pendingPage <= 1) {
@@ -2846,7 +2851,6 @@ class PaginatedAutocompleteControl {
2846
2851
  optionPatched = new EventEmitter();
2847
2852
  valueBuffer = null;
2848
2853
  popperInstance;
2849
- preventDropdownReopen = false;
2850
2854
  preventClearOnBlur = false;
2851
2855
  onChange = () => { };
2852
2856
  onTouched = () => { };
@@ -2856,6 +2860,8 @@ class PaginatedAutocompleteControl {
2856
2860
  isDropdownOpen = false;
2857
2861
  hasFocus = false;
2858
2862
  isPageLoading = false;
2863
+ loadErrorMessage = null;
2864
+ failedPage = null;
2859
2865
  selectedItems;
2860
2866
  highlightedIndex = null;
2861
2867
  currentPage = 1;
@@ -2868,12 +2874,12 @@ class PaginatedAutocompleteControl {
2868
2874
  this.subscription.add(this.inputControl.valueChanges
2869
2875
  .pipe(debounceTime(this.searchDebounce), distinctUntilChanged())
2870
2876
  .subscribe((value) => {
2871
- if (this.preventDropdownReopen) {
2872
- this.preventDropdownReopen = false;
2873
- return;
2874
- }
2875
2877
  if (this.readonly || !this.hasFocus)
2876
2878
  return;
2879
+ // Discard stale debounced emissions — e.g. an Enter-selection replaced
2880
+ // the text while this search was still waiting out the debounce.
2881
+ if ((value || "") !== (this.inputControl.value || ""))
2882
+ return;
2877
2883
  this.loadPage(1, value || "");
2878
2884
  }));
2879
2885
  }
@@ -2888,7 +2894,6 @@ class PaginatedAutocompleteControl {
2888
2894
  }
2889
2895
  // CVA
2890
2896
  writeValue(value) {
2891
- this.preventDropdownReopen = true;
2892
2897
  if (value == null) {
2893
2898
  this.valueBuffer = null;
2894
2899
  this.selectedItems = null;
@@ -2906,7 +2911,6 @@ class PaginatedAutocompleteControl {
2906
2911
  if (this._displayedOptions.length > 0) {
2907
2912
  const matchedSuggestion = this._displayedOptions.find((s) => s.id === this.valueBuffer);
2908
2913
  if (matchedSuggestion) {
2909
- this.preventDropdownReopen = true;
2910
2914
  this.inputControl.setValue(matchedSuggestion[this.optionDisplayProperty], { emitEvent: false });
2911
2915
  this.selectedItems = matchedSuggestion;
2912
2916
  this.onChange(matchedSuggestion.id);
@@ -2933,6 +2937,9 @@ class PaginatedAutocompleteControl {
2933
2937
  loadPage(page, search) {
2934
2938
  this.currentPage = page;
2935
2939
  this._pendingPage = page;
2940
+ this.lastLoadedSearch = search;
2941
+ this.loadErrorMessage = null;
2942
+ this.failedPage = null;
2936
2943
  this.isPageLoading = true;
2937
2944
  if (page === 1) {
2938
2945
  this.openDropdown();
@@ -2960,6 +2967,22 @@ class PaginatedAutocompleteControl {
2960
2967
  event.stopPropagation();
2961
2968
  this.loadNextPage();
2962
2969
  }
2970
+ /** Call from the parent's API error handler to unblock paging and show a
2971
+ * Retry row in the dropdown. e.g. error: () => ctrl.pageLoadFailed() */
2972
+ pageLoadFailed(message = "Couldn't load results") {
2973
+ this.isPageLoading = false;
2974
+ this.loadErrorMessage = message;
2975
+ this.failedPage = this._pendingPage;
2976
+ if (this._pendingPage > 1) {
2977
+ // Roll back so a retry re-requests the failed page, not the one after it
2978
+ this.currentPage = this._pendingPage - 1;
2979
+ }
2980
+ }
2981
+ retryLoad(event) {
2982
+ event.stopPropagation();
2983
+ const page = this.failedPage ?? 1;
2984
+ this.loadPage(page, this.lastLoadedSearch || "");
2985
+ }
2963
2986
  openDropdown() {
2964
2987
  if (this.isDropdownOpen)
2965
2988
  return;
@@ -2971,7 +2994,6 @@ class PaginatedAutocompleteControl {
2971
2994
  }
2972
2995
  // selection
2973
2996
  selectSuggestion(suggestion) {
2974
- this.preventDropdownReopen = true;
2975
2997
  this.inputControl.setValue(suggestion[this.optionDisplayProperty], {
2976
2998
  emitEvent: false,
2977
2999
  });
@@ -2987,28 +3009,64 @@ class PaginatedAutocompleteControl {
2987
3009
  // events
2988
3010
  onFocus() {
2989
3011
  this.hasFocus = true;
2990
- if (this.readonly)
3012
+ if (this.readonly || this.isDropdownOpen)
2991
3013
  return;
2992
- this.loadPage(1, this.inputControl.value || "");
3014
+ this.openWithSearch();
2993
3015
  }
2994
3016
  onInputClick() {
2995
3017
  if (this.readonly || this.isDropdownOpen)
2996
3018
  return;
2997
3019
  if (this.hasFocus) {
2998
- this.loadPage(1, this.inputControl.value || "");
3020
+ this.openWithSearch();
2999
3021
  }
3000
3022
  }
3023
+ /** Text to search with when the dropdown opens: if the input just holds the
3024
+ * selected item's display text, open with the full list instead. */
3025
+ openSearchTerm() {
3026
+ const value = this.inputControl.value || "";
3027
+ if (this.selectedItems &&
3028
+ value === this.selectedItems[this.optionDisplayProperty]) {
3029
+ return "";
3030
+ }
3031
+ return value;
3032
+ }
3033
+ openWithSearch() {
3034
+ const term = this.openSearchTerm();
3035
+ // Reuse cached results when reopening with the same search term
3036
+ if (!this.refreshOnOpen &&
3037
+ this.lastLoadedSearch === term &&
3038
+ this._displayedOptions.length > 0) {
3039
+ this.openDropdown();
3040
+ const idx = this.selectedItems
3041
+ ? this._displayedOptions.findIndex((o) => o.id === this.selectedItems.id)
3042
+ : -1;
3043
+ this.highlightedIndex =
3044
+ idx >= 0 ? idx : this._displayedOptions.length > 0 ? 0 : null;
3045
+ return;
3046
+ }
3047
+ this.loadPage(1, term);
3048
+ }
3001
3049
  onBlur() {
3002
3050
  this.blurEvent.emit();
3003
3051
  this.onTouched();
3052
+ // mousedown fires before blur — if no dropdown interaction flagged itself,
3053
+ // the user clicked outside: close immediately instead of waiting 300ms.
3054
+ if (!this.preventClearOnBlur) {
3055
+ this.isDropdownOpen = false;
3056
+ this.isPageLoading = false;
3057
+ }
3004
3058
  // Delay so option / load-more mousedown and click can occur first.
3005
3059
  setTimeout(() => {
3006
3060
  if (this.preventClearOnBlur) {
3007
3061
  this.preventClearOnBlur = false;
3008
- // Keep the dropdown alive for load-more clicks
3009
- if (this.inputElement) {
3062
+ // Refocus only while the dropdown is still open (load more / clear).
3063
+ // After selecting an option the dropdown is closed — don't reopen it.
3064
+ if (this.isDropdownOpen && this.inputElement) {
3010
3065
  this.inputElement.nativeElement.focus();
3011
3066
  }
3067
+ else {
3068
+ this.hasFocus = false;
3069
+ }
3012
3070
  return;
3013
3071
  }
3014
3072
  this.hasFocus = false;
@@ -3090,6 +3148,19 @@ class PaginatedAutocompleteControl {
3090
3148
  fallbackPlacements: ["top-start", "bottom-start"],
3091
3149
  },
3092
3150
  },
3151
+ // Make the dropdown exactly as wide as the input
3152
+ {
3153
+ name: "sameWidth",
3154
+ enabled: true,
3155
+ phase: "beforeWrite",
3156
+ requires: ["computeStyles"],
3157
+ fn: ({ state }) => {
3158
+ state.styles["popper"].width = `${state.rects.reference.width}px`;
3159
+ },
3160
+ effect: ({ state }) => {
3161
+ state.elements.popper.style.width = `${state.elements.reference.offsetWidth}px`;
3162
+ },
3163
+ },
3093
3164
  ],
3094
3165
  });
3095
3166
  }
@@ -3114,13 +3185,13 @@ class PaginatedAutocompleteControl {
3114
3185
  }
3115
3186
  }
3116
3187
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
3117
- 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", optionDisplayProperty: "optionDisplayProperty", paginationType: "paginationType", pageSize: "pageSize", searchDebounce: "searchDebounce", totalCount: "totalCount", options: "options", disabled: "disabled" }, outputs: { pageChange: "pageChange", optionSelected: "optionSelected", selectionCleared: "selectionCleared", blurEvent: "blurEvent", optionPatched: "optionPatched" }, providers: [
3188
+ 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", 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" }, providers: [
3118
3189
  {
3119
3190
  provide: NG_VALUE_ACCESSOR,
3120
3191
  useExisting: PaginatedAutocompleteControl,
3121
3192
  multi: true,
3122
3193
  },
3123
- ], 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 paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (mousedown)=\"onOptionMouseDown()\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading) {\n <div class=\"load-more\" (mousedown)=\"onOptionMouseDown()\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}\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"] }] });
3194
+ ], 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 paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (loadErrorMessage) {\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\n </div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\n <div class=\"list-footer\">\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.paginated-autocomplete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .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}\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"] }] });
3124
3195
  }
3125
3196
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, decorators: [{
3126
3197
  type: Component,
@@ -3130,7 +3201,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3130
3201
  useExisting: PaginatedAutocompleteControl,
3131
3202
  multi: true,
3132
3203
  },
3133
- ], template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (mousedown)=\"onOptionMouseDown()\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading) {\n <div class=\"load-more\" (mousedown)=\"onOptionMouseDown()\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}\n"] }]
3204
+ ], template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (loadErrorMessage) {\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\n </div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\n <div class=\"list-footer\">\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .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.paginated-autocomplete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.paginated-autocomplete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .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}\n"] }]
3134
3205
  }], ctorParameters: () => [], propDecorators: { title: [{
3135
3206
  type: Input
3136
3207
  }], required: [{
@@ -3159,6 +3230,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
3159
3230
  type: Input
3160
3231
  }], searchDebounce: [{
3161
3232
  type: Input
3233
+ }], refreshOnOpen: [{
3234
+ type: Input
3162
3235
  }], totalCount: [{
3163
3236
  type: Input
3164
3237
  }], options: [{