@snabcentr/client-ui 5.5.0 → 5.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4644,11 +4644,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
4644
4644
  }] });
4645
4645
 
4646
4646
  /**
4647
- * Токен для инъекции {@link Subject} для хранения фильтров продуктов.
4647
+ * Токен для инъекции {@link BehaviorSubject} для хранения фильтров продуктов.
4648
4648
  */
4649
4649
  const SC_CATALOG_PRODUCTS_FILTERS = new InjectionToken('SC_CATALOG_PRODUCTS_FILTERS$', {
4650
4650
  providedIn: 'root',
4651
- factory: () => new Subject(),
4651
+ factory: () => new BehaviorSubject({}),
4652
4652
  });
4653
4653
 
4654
4654
  /**
@@ -4769,6 +4769,12 @@ class ScCatalogFiltersComponent {
4769
4769
  this.form.valueChanges.pipe(debounceTime(0), takeUntilDestroyed()).subscribe((filters) => {
4770
4770
  this.catalogProductsFilters$.next(this.buildPropertyFilters(filters));
4771
4771
  });
4772
+ // Внешний сброс фильтров (например, при смене категории): приводим форму к исходным значениям без повторной отправки в хранилище.
4773
+ this.catalogProductsFilters$
4774
+ .pipe(filter((value) => Object.keys(value).length === 0), takeUntilDestroyed())
4775
+ .subscribe(() => {
4776
+ this.resetAllFilters(false);
4777
+ });
4772
4778
  }
4773
4779
  /**
4774
4780
  * Обновляет состав контролов формы на основе переданных фильтров.
@@ -4778,13 +4784,16 @@ class ScCatalogFiltersComponent {
4778
4784
  updateFormControls(filters) {
4779
4785
  this.formSyncs.unsubscribe();
4780
4786
  this.formSyncs = new Subscription();
4787
+ const appliedFilters = this.getAppliedFilters();
4781
4788
  Object.keys(this.form.controls).forEach((key) => {
4782
4789
  this.form.removeControl(key, { emitEvent: false });
4783
4790
  });
4784
4791
  filters.forEach((item) => {
4792
+ // eslint-disable-next-line security/detect-object-injection
4793
+ const appliedValue = appliedFilters[item.id];
4785
4794
  switch (item.type) {
4786
4795
  case 'checkbox': {
4787
- const checkboxControl = this.createCheckboxFormControl(item);
4796
+ const checkboxControl = this.createCheckboxFormControl(item, appliedValue);
4788
4797
  this.form.addControl(item.id, checkboxControl, { emitEvent: false });
4789
4798
  // Single-select для !isMultiple: при выборе одного остальные снимаются.
4790
4799
  if (!item.isMultiple && item.values.length > 1) {
@@ -4793,19 +4802,27 @@ class ScCatalogFiltersComponent {
4793
4802
  break;
4794
4803
  }
4795
4804
  case 'range': {
4796
- const rangeControl = this.createRangeFormControl(item);
4805
+ const rangeControl = this.createRangeFormControl(item, appliedValue);
4797
4806
  this.form.addControl(item.id, rangeControl, { emitEvent: false });
4798
4807
  this.formSyncs.add(this.syncRangeFromToAndSlider(rangeControl));
4799
4808
  break;
4800
4809
  }
4801
4810
  case 'toggle':
4802
- this.form.addControl(item.id, this.createToggleFormControl(item), { emitEvent: false });
4811
+ this.form.addControl(item.id, this.createToggleFormControl(item, appliedValue), { emitEvent: false });
4803
4812
  break;
4804
4813
  default:
4805
4814
  break;
4806
4815
  }
4807
4816
  });
4808
4817
  }
4818
+ /**
4819
+ * Возвращает текущие применённые фильтры из хранилища фильтров.
4820
+ *
4821
+ * Позволяет восстанавливать выбранные значения при пересоздании компонента (повторное открытие диалога или блока фильтров).
4822
+ */
4823
+ getAppliedFilters() {
4824
+ return this.catalogProductsFilters$ instanceof BehaviorSubject ? this.catalogProductsFilters$.value : {};
4825
+ }
4809
4826
  /**
4810
4827
  * Преобразует значения формы в объект фильтров свойств.
4811
4828
  *
@@ -4842,9 +4859,11 @@ class ScCatalogFiltersComponent {
4842
4859
  * Различие в API-выводе для одиночного значения (boolean вместо массива) обрабатывается в {@link processCheckboxFilter}.
4843
4860
  *
4844
4861
  * @param checkboxFilter Фильтр типа checkbox.
4862
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
4845
4863
  */
4846
- createCheckboxFormControl(checkboxFilter) {
4847
- const isSelected = (id) => checkboxFilter.selectedValues?.includes(id) ?? false;
4864
+ createCheckboxFormControl(checkboxFilter, appliedValue) {
4865
+ const appliedIds = Array.isArray(appliedValue) ? appliedValue : null;
4866
+ const isSelected = (id) => appliedIds?.includes(id) ?? checkboxFilter.selectedValues?.includes(id) ?? false;
4848
4867
  const controls = {};
4849
4868
  checkboxFilter.values.forEach((value) => {
4850
4869
  controls[value.id] = new FormControl(isSelected(value.id), { nonNullable: true });
@@ -4855,10 +4874,12 @@ class ScCatalogFiltersComponent {
4855
4874
  * Создаёт {@link FormGroup} для range: {@code from}, {@code to}, {@code slider} (кортеж для {@link TuiRange}).
4856
4875
  *
4857
4876
  * @param rangeFilter Фильтр типа range.
4877
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
4858
4878
  */
4859
- createRangeFormControl(rangeFilter) {
4860
- const fromValue = Number(rangeFilter.selectedMin ?? rangeFilter.min);
4861
- const toValue = Number(rangeFilter.selectedMax ?? rangeFilter.max);
4879
+ createRangeFormControl(rangeFilter, appliedValue) {
4880
+ const appliedRange = appliedValue && typeof appliedValue === 'object' && !Array.isArray(appliedValue) ? appliedValue : null;
4881
+ const fromValue = Number(appliedRange?.from ?? rangeFilter.selectedMin ?? rangeFilter.min);
4882
+ const toValue = Number(appliedRange?.to ?? rangeFilter.selectedMax ?? rangeFilter.max);
4862
4883
  return new FormGroup({
4863
4884
  from: new FormControl(fromValue, { nonNullable: true }),
4864
4885
  to: new FormControl(toValue, { nonNullable: true }),
@@ -4942,9 +4963,11 @@ class ScCatalogFiltersComponent {
4942
4963
  * Создает FormControl для toggle.
4943
4964
  *
4944
4965
  * @param toggleFilter Фильтр типа toggle.
4966
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
4945
4967
  */
4946
- createToggleFormControl(toggleFilter) {
4947
- return new FormControl(toggleFilter.selectedValue ?? false, { nonNullable: true });
4968
+ createToggleFormControl(toggleFilter, appliedValue) {
4969
+ const appliedToggle = typeof appliedValue === 'boolean' ? appliedValue : undefined;
4970
+ return new FormControl(appliedToggle ?? toggleFilter.selectedValue ?? false, { nonNullable: true });
4948
4971
  }
4949
4972
  /**
4950
4973
  * Обрабатывает checkbox: FormGroup → string[] выбранных id; для единственного значения — boolean (как toggle).
@@ -5042,8 +5065,10 @@ class ScCatalogFiltersComponent {
5042
5065
  }
5043
5066
  /**
5044
5067
  * Сбрасывает все фильтры к исходным значениям.
5068
+ *
5069
+ * @param emitEvent Признак необходимости эмитить события изменения контролов (false — тихий сброс без отправки значений в хранилище фильтров).
5045
5070
  */
5046
- resetAllFilters() {
5071
+ resetAllFilters(emitEvent = true) {
5047
5072
  this.filters()?.forEach((filterItem) => {
5048
5073
  const control = this.form.get(filterItem.id);
5049
5074
  if (!control) {
@@ -5057,17 +5082,17 @@ class ScCatalogFiltersComponent {
5057
5082
  // eslint-disable-next-line security/detect-object-injection
5058
5083
  resetValue[id] = false;
5059
5084
  });
5060
- group.reset(resetValue);
5085
+ group.reset(resetValue, { emitEvent });
5061
5086
  break;
5062
5087
  }
5063
5088
  case 'toggle':
5064
- control.reset(false);
5089
+ control.reset(false, { emitEvent });
5065
5090
  break;
5066
5091
  case 'range': {
5067
5092
  const group = control;
5068
5093
  const min = +filterItem.min;
5069
5094
  const max = +filterItem.max;
5070
- group.reset({ from: min, to: max, slider: [min, max] });
5095
+ group.reset({ from: min, to: max, slider: [min, max] }, { emitEvent });
5071
5096
  break;
5072
5097
  }
5073
5098
  default: