@snabcentr/client-ui 4.8.1 → 4.8.2

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.
@@ -5648,11 +5648,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5648
5648
  }] });
5649
5649
 
5650
5650
  /**
5651
- * Токен для инъекции {@link Subject} для хранения фильтров продуктов.
5651
+ * Токен для инъекции {@link BehaviorSubject} для хранения фильтров продуктов.
5652
5652
  */
5653
5653
  const SC_CATALOG_PRODUCTS_FILTERS = new InjectionToken('SC_CATALOG_PRODUCTS_FILTERS$', {
5654
5654
  providedIn: 'root',
5655
- factory: () => new Subject(),
5655
+ factory: () => new BehaviorSubject({}),
5656
5656
  });
5657
5657
 
5658
5658
  /**
@@ -5773,6 +5773,12 @@ class ScCatalogFiltersComponent {
5773
5773
  this.form.valueChanges.pipe(debounceTime(0), takeUntilDestroyed()).subscribe((filters) => {
5774
5774
  this.catalogProductsFilters$.next(this.buildPropertyFilters(filters));
5775
5775
  });
5776
+ // Внешний сброс фильтров (например, при смене категории): приводим форму к исходным значениям без повторной отправки в хранилище.
5777
+ this.catalogProductsFilters$
5778
+ .pipe(filter((value) => Object.keys(value).length === 0), takeUntilDestroyed())
5779
+ .subscribe(() => {
5780
+ this.resetAllFilters(false);
5781
+ });
5776
5782
  }
5777
5783
  /**
5778
5784
  * Обновляет состав контролов формы на основе переданных фильтров.
@@ -5782,13 +5788,16 @@ class ScCatalogFiltersComponent {
5782
5788
  updateFormControls(filters) {
5783
5789
  this.formSyncs.unsubscribe();
5784
5790
  this.formSyncs = new Subscription();
5791
+ const appliedFilters = this.getAppliedFilters();
5785
5792
  Object.keys(this.form.controls).forEach((key) => {
5786
5793
  this.form.removeControl(key, { emitEvent: false });
5787
5794
  });
5788
5795
  filters.forEach((item) => {
5796
+ // eslint-disable-next-line security/detect-object-injection
5797
+ const appliedValue = appliedFilters[item.id];
5789
5798
  switch (item.type) {
5790
5799
  case 'checkbox': {
5791
- const checkboxControl = this.createCheckboxFormControl(item);
5800
+ const checkboxControl = this.createCheckboxFormControl(item, appliedValue);
5792
5801
  this.form.addControl(item.id, checkboxControl, { emitEvent: false });
5793
5802
  // Single-select для !isMultiple: при выборе одного остальные снимаются.
5794
5803
  if (!item.isMultiple && item.values.length > 1) {
@@ -5797,19 +5806,27 @@ class ScCatalogFiltersComponent {
5797
5806
  break;
5798
5807
  }
5799
5808
  case 'range': {
5800
- const rangeControl = this.createRangeFormControl(item);
5809
+ const rangeControl = this.createRangeFormControl(item, appliedValue);
5801
5810
  this.form.addControl(item.id, rangeControl, { emitEvent: false });
5802
5811
  this.formSyncs.add(this.syncRangeFromToAndSlider(rangeControl));
5803
5812
  break;
5804
5813
  }
5805
5814
  case 'toggle':
5806
- this.form.addControl(item.id, this.createToggleFormControl(item), { emitEvent: false });
5815
+ this.form.addControl(item.id, this.createToggleFormControl(item, appliedValue), { emitEvent: false });
5807
5816
  break;
5808
5817
  default:
5809
5818
  break;
5810
5819
  }
5811
5820
  });
5812
5821
  }
5822
+ /**
5823
+ * Возвращает текущие применённые фильтры из хранилища фильтров.
5824
+ *
5825
+ * Позволяет восстанавливать выбранные значения при пересоздании компонента (повторное открытие диалога или блока фильтров).
5826
+ */
5827
+ getAppliedFilters() {
5828
+ return this.catalogProductsFilters$ instanceof BehaviorSubject ? this.catalogProductsFilters$.value : {};
5829
+ }
5813
5830
  /**
5814
5831
  * Преобразует значения формы в объект фильтров свойств.
5815
5832
  *
@@ -5846,9 +5863,11 @@ class ScCatalogFiltersComponent {
5846
5863
  * Различие в API-выводе для одиночного значения (boolean вместо массива) обрабатывается в {@link processCheckboxFilter}.
5847
5864
  *
5848
5865
  * @param checkboxFilter Фильтр типа checkbox.
5866
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5849
5867
  */
5850
- createCheckboxFormControl(checkboxFilter) {
5851
- const isSelected = (id) => checkboxFilter.selectedValues?.includes(id) ?? false;
5868
+ createCheckboxFormControl(checkboxFilter, appliedValue) {
5869
+ const appliedIds = Array.isArray(appliedValue) ? appliedValue : null;
5870
+ const isSelected = (id) => appliedIds?.includes(id) ?? checkboxFilter.selectedValues?.includes(id) ?? false;
5852
5871
  const controls = {};
5853
5872
  checkboxFilter.values.forEach((value) => {
5854
5873
  controls[value.id] = new FormControl(isSelected(value.id), { nonNullable: true });
@@ -5859,10 +5878,12 @@ class ScCatalogFiltersComponent {
5859
5878
  * Создаёт {@link FormGroup} для range: {@code from}, {@code to}, {@code slider} (кортеж для {@link TuiRange}).
5860
5879
  *
5861
5880
  * @param rangeFilter Фильтр типа range.
5881
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5862
5882
  */
5863
- createRangeFormControl(rangeFilter) {
5864
- const fromValue = Number(rangeFilter.selectedMin ?? rangeFilter.min);
5865
- const toValue = Number(rangeFilter.selectedMax ?? rangeFilter.max);
5883
+ createRangeFormControl(rangeFilter, appliedValue) {
5884
+ const appliedRange = appliedValue && typeof appliedValue === 'object' && !Array.isArray(appliedValue) ? appliedValue : null;
5885
+ const fromValue = Number(appliedRange?.from ?? rangeFilter.selectedMin ?? rangeFilter.min);
5886
+ const toValue = Number(appliedRange?.to ?? rangeFilter.selectedMax ?? rangeFilter.max);
5866
5887
  return new FormGroup({
5867
5888
  from: new FormControl(fromValue, { nonNullable: true }),
5868
5889
  to: new FormControl(toValue, { nonNullable: true }),
@@ -5946,9 +5967,11 @@ class ScCatalogFiltersComponent {
5946
5967
  * Создает FormControl для toggle.
5947
5968
  *
5948
5969
  * @param toggleFilter Фильтр типа toggle.
5970
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5949
5971
  */
5950
- createToggleFormControl(toggleFilter) {
5951
- return new FormControl(toggleFilter.selectedValue ?? false, { nonNullable: true });
5972
+ createToggleFormControl(toggleFilter, appliedValue) {
5973
+ const appliedToggle = typeof appliedValue === 'boolean' ? appliedValue : undefined;
5974
+ return new FormControl(appliedToggle ?? toggleFilter.selectedValue ?? false, { nonNullable: true });
5952
5975
  }
5953
5976
  /**
5954
5977
  * Обрабатывает checkbox: FormGroup → string[] выбранных id; для единственного значения — boolean (как toggle).
@@ -6046,8 +6069,10 @@ class ScCatalogFiltersComponent {
6046
6069
  }
6047
6070
  /**
6048
6071
  * Сбрасывает все фильтры к исходным значениям.
6072
+ *
6073
+ * @param emitEvent Признак необходимости эмитить события изменения контролов (false — тихий сброс без отправки значений в хранилище фильтров).
6049
6074
  */
6050
- resetAllFilters() {
6075
+ resetAllFilters(emitEvent = true) {
6051
6076
  this.filters()?.forEach((filterItem) => {
6052
6077
  const control = this.form.get(filterItem.id);
6053
6078
  if (!control) {
@@ -6061,17 +6086,17 @@ class ScCatalogFiltersComponent {
6061
6086
  // eslint-disable-next-line security/detect-object-injection
6062
6087
  resetValue[id] = false;
6063
6088
  });
6064
- group.reset(resetValue);
6089
+ group.reset(resetValue, { emitEvent });
6065
6090
  break;
6066
6091
  }
6067
6092
  case 'toggle':
6068
- control.reset(false);
6093
+ control.reset(false, { emitEvent });
6069
6094
  break;
6070
6095
  case 'range': {
6071
6096
  const group = control;
6072
6097
  const min = +filterItem.min;
6073
6098
  const max = +filterItem.max;
6074
- group.reset({ from: min, to: max, slider: [min, max] });
6099
+ group.reset({ from: min, to: max, slider: [min, max] }, { emitEvent });
6075
6100
  break;
6076
6101
  }
6077
6102
  default: