@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.
- package/catalog/catalog-filters/sc-catalog-filters.component.d.ts +14 -3
- package/catalog/catalog-filters/tokens/sc-catalog-products-filters.d.ts +3 -3
- package/esm2022/catalog/catalog-filters/sc-catalog-filters.component.mjs +41 -16
- package/esm2022/catalog/catalog-filters/tokens/sc-catalog-products-filters.mjs +4 -4
- package/fesm2022/snabcentr-client-ui.mjs +41 -16
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/release_notes.tmp +2 -4
|
@@ -5648,11 +5648,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5648
5648
|
}] });
|
|
5649
5649
|
|
|
5650
5650
|
/**
|
|
5651
|
-
* Токен для инъекции {@link
|
|
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
|
|
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
|
|
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
|
|
5865
|
-
const
|
|
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
|
-
|
|
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:
|