@snabcentr/client-ui 3.54.0 → 3.54.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.
@@ -5771,6 +5771,20 @@ class ScCatalogFiltersComponent {
5771
5771
  this.form.valueChanges.pipe(debounceTime(0), takeUntilDestroyed()).subscribe((filters) => {
5772
5772
  this.catalogProductsFilters$.next(this.buildPropertyFilters(filters));
5773
5773
  });
5774
+ // Внешний сброс фильтров (например, при смене категории): приводим форму к исходным значениям без повторной отправки в хранилище.
5775
+ this.catalogProductsFilters$
5776
+ .pipe(filter((value) => Object.keys(value).length === 0), takeUntilDestroyed())
5777
+ .subscribe(() => {
5778
+ this.resetAllFilters(false);
5779
+ });
5780
+ }
5781
+ /**
5782
+ * Возвращает текущие применённые фильтры из хранилища фильтров.
5783
+ *
5784
+ * Позволяет восстанавливать выбранные значения при пересоздании компонента (повторное открытие диалога или блока фильтров).
5785
+ */
5786
+ getAppliedFilters() {
5787
+ return this.catalogProductsFilters$ instanceof BehaviorSubject ? this.catalogProductsFilters$.value : {};
5774
5788
  }
5775
5789
  /**
5776
5790
  * Обновляет состав контролов формы на основе переданных фильтров.
@@ -5780,13 +5794,16 @@ class ScCatalogFiltersComponent {
5780
5794
  updateFormControls(filters) {
5781
5795
  this.formSyncs.unsubscribe();
5782
5796
  this.formSyncs = new Subscription();
5797
+ const appliedFilters = this.getAppliedFilters();
5783
5798
  Object.keys(this.form.controls).forEach((key) => {
5784
5799
  this.form.removeControl(key, { emitEvent: false });
5785
5800
  });
5786
5801
  filters.forEach((item) => {
5802
+ // eslint-disable-next-line security/detect-object-injection
5803
+ const appliedValue = appliedFilters[item.id];
5787
5804
  switch (item.type) {
5788
5805
  case 'checkbox': {
5789
- const checkboxControl = this.createCheckboxFormControl(item);
5806
+ const checkboxControl = this.createCheckboxFormControl(item, appliedValue);
5790
5807
  this.form.addControl(item.id, checkboxControl, { emitEvent: false });
5791
5808
  // Single-select для !isMultiple: при выборе одного остальные снимаются.
5792
5809
  if (!item.isMultiple && item.values.length > 1) {
@@ -5795,13 +5812,13 @@ class ScCatalogFiltersComponent {
5795
5812
  break;
5796
5813
  }
5797
5814
  case 'range': {
5798
- const rangeControl = this.createRangeFormControl(item);
5815
+ const rangeControl = this.createRangeFormControl(item, appliedValue);
5799
5816
  this.form.addControl(item.id, rangeControl, { emitEvent: false });
5800
5817
  this.formSyncs.add(this.syncRangeFromToAndSlider(rangeControl));
5801
5818
  break;
5802
5819
  }
5803
5820
  case 'toggle':
5804
- this.form.addControl(item.id, this.createToggleFormControl(item), { emitEvent: false });
5821
+ this.form.addControl(item.id, this.createToggleFormControl(item, appliedValue), { emitEvent: false });
5805
5822
  break;
5806
5823
  default:
5807
5824
  break;
@@ -5848,9 +5865,11 @@ class ScCatalogFiltersComponent {
5848
5865
  * Различие в API-выводе для одиночного значения (boolean вместо массива) обрабатывается в {@link processCheckboxFilter}.
5849
5866
  *
5850
5867
  * @param checkboxFilter Фильтр типа checkbox.
5868
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5851
5869
  */
5852
- createCheckboxFormControl(checkboxFilter) {
5853
- const isSelected = (id) => checkboxFilter.selectedValues?.includes(id) ?? false;
5870
+ createCheckboxFormControl(checkboxFilter, appliedValue) {
5871
+ const appliedIds = Array.isArray(appliedValue) ? appliedValue : null;
5872
+ const isSelected = (id) => appliedIds?.includes(id) ?? checkboxFilter.selectedValues?.includes(id) ?? false;
5854
5873
  const controls = {};
5855
5874
  checkboxFilter.values.forEach((value) => {
5856
5875
  controls[value.id] = new FormControl(isSelected(value.id), { nonNullable: true });
@@ -5874,10 +5893,14 @@ class ScCatalogFiltersComponent {
5874
5893
  * Поля заполнены дефолтами и валидируются границами; округление значений — на стороне поля ввода Taiga.
5875
5894
  *
5876
5895
  * @param rangeFilter Фильтр типа range.
5896
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5877
5897
  */
5878
- createRangeFormControl(rangeFilter) {
5898
+ createRangeFormControl(rangeFilter, appliedValue) {
5879
5899
  const { min, max } = rangeFilter;
5880
- const { from: fromValue, to: toValue } = this.getRangeDefaults(rangeFilter);
5900
+ const appliedRange = appliedValue && typeof appliedValue === 'object' && !Array.isArray(appliedValue) ? appliedValue : null;
5901
+ const defaults = this.getRangeDefaults(rangeFilter);
5902
+ const fromValue = Number(appliedRange?.from ?? defaults.from);
5903
+ const toValue = Number(appliedRange?.to ?? defaults.to);
5881
5904
  return new FormGroup({
5882
5905
  from: new FormControl(fromValue, { nonNullable: true, validators: [Validators.min(min), Validators.max(max)] }),
5883
5906
  to: new FormControl(toValue, { nonNullable: true, validators: [Validators.min(min), Validators.max(max)] }),
@@ -5961,9 +5984,11 @@ class ScCatalogFiltersComponent {
5961
5984
  * Создает FormControl для toggle.
5962
5985
  *
5963
5986
  * @param toggleFilter Фильтр типа toggle.
5987
+ * @param appliedValue Применённое ранее значение фильтра из хранилища фильтров.
5964
5988
  */
5965
- createToggleFormControl(toggleFilter) {
5966
- return new FormControl(toggleFilter.selectedValue ?? false, { nonNullable: true });
5989
+ createToggleFormControl(toggleFilter, appliedValue) {
5990
+ const appliedToggle = typeof appliedValue === 'boolean' ? appliedValue : undefined;
5991
+ return new FormControl(appliedToggle ?? toggleFilter.selectedValue ?? false, { nonNullable: true });
5967
5992
  }
5968
5993
  /**
5969
5994
  * Обрабатывает checkbox: FormGroup → string[] выбранных id; для единственного значения — boolean (как toggle).
@@ -6086,8 +6111,10 @@ class ScCatalogFiltersComponent {
6086
6111
  }
6087
6112
  /**
6088
6113
  * Сбрасывает все фильтры к исходным значениям.
6114
+ *
6115
+ * @param emitEvent Признак необходимости эмитить события изменения контролов (false — тихий сброс без отправки значений в хранилище фильтров).
6089
6116
  */
6090
- resetAllFilters() {
6117
+ resetAllFilters(emitEvent = true) {
6091
6118
  this.filters()?.forEach((filterItem) => {
6092
6119
  const control = this.form.get(filterItem.id);
6093
6120
  if (!control) {
@@ -6101,16 +6128,16 @@ class ScCatalogFiltersComponent {
6101
6128
  // eslint-disable-next-line security/detect-object-injection
6102
6129
  resetValue[id] = false;
6103
6130
  });
6104
- group.reset(resetValue);
6131
+ group.reset(resetValue, { emitEvent });
6105
6132
  break;
6106
6133
  }
6107
6134
  case 'toggle':
6108
- control.reset(false);
6135
+ control.reset(false, { emitEvent });
6109
6136
  break;
6110
6137
  case 'range': {
6111
6138
  const group = control;
6112
6139
  const defaults = this.getRangeDefaults(filterItem);
6113
- group.reset({ from: defaults.from, to: defaults.to, slider: [defaults.from, defaults.to] });
6140
+ group.reset({ from: defaults.from, to: defaults.to, slider: [defaults.from, defaults.to] }, { emitEvent });
6114
6141
  break;
6115
6142
  }
6116
6143
  default: