ng-easycommerce-v18 0.3.16-beta.1 → 0.3.17-beta.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.
- package/README.md +2 -4
- package/esm2022/lib/classes/filters/dynamics-filter.mjs +23 -31
- package/esm2022/lib/classes/filters/filter.mjs +3 -12
- package/esm2022/lib/classes/filters/price_range-filter.mjs +1 -1
- package/esm2022/lib/ec-components/filters-ec/filters-ec.component.mjs +31 -6
- package/esm2022/lib/ec-components/header-ec/header-ec.component.mjs +1 -1
- package/esm2022/lib/ec-services/filters.service.mjs +19 -54
- package/esm2022/lib/ec-services/pagination.service.mjs +6 -17
- package/esm2022/lib/ec-services/products.service.mjs +3 -10
- package/esm2022/lib/interfaces/filter.mjs +1 -1
- package/esm2022/lib/interfaces/options.mjs +1 -1
- package/fesm2022/ng-easycommerce-v18.mjs +79 -124
- package/fesm2022/ng-easycommerce-v18.mjs.map +1 -1
- package/lib/classes/filters/dynamics-filter.d.ts +2 -2
- package/lib/classes/filters/filter.d.ts +0 -1
- package/lib/ec-components/filters-ec/filters-ec.component.d.ts +12 -4
- package/lib/ec-components/header-ec/header-ec.component.d.ts +1 -1
- package/lib/ec-services/filters.service.d.ts +1 -14
- package/lib/ec-services/pagination.service.d.ts +0 -2
- package/lib/interfaces/filter.d.ts +1 -0
- package/lib/interfaces/options.d.ts +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { InjectionToken, makeEnvironmentProviders, inject, Injectable, PLATFORM_ID, RendererFactory2, afterNextRender, signal, EnvironmentInjector, runInInjectionContext, Component, ChangeDetectorRef, HostListener, CUSTOM_ELEMENTS_SCHEMA, Input, Pipe, Injector, EventEmitter, Output, forwardRef, afterRender, ViewChild, Inject, computed, Renderer2, ChangeDetectionStrategy, Directive } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { DOCUMENT, isPlatformBrowser, AsyncPipe, CommonModule, TitleCasePipe, JsonPipe, UpperCasePipe, Location } from '@angular/common';
|
|
5
|
-
import { take, BehaviorSubject, shareReplay, map, catchError, of, filter, ReplaySubject, firstValueFrom, concatMap, throwError,
|
|
5
|
+
import { take, BehaviorSubject, shareReplay, map, catchError, of, filter, ReplaySubject, firstValueFrom, concatMap, throwError, switchMap, combineLatest } from 'rxjs';
|
|
6
6
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
7
7
|
import * as i1$1 from '@ngx-translate/core';
|
|
8
8
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
@@ -2651,12 +2651,10 @@ class Filter {
|
|
|
2651
2651
|
throw new Error("Method not implemented.");
|
|
2652
2652
|
}
|
|
2653
2653
|
setContent(options) {
|
|
2654
|
-
|
|
2655
|
-
this.data = options;
|
|
2656
|
-
}
|
|
2654
|
+
throw new Error("Method not implemented.");
|
|
2657
2655
|
}
|
|
2658
2656
|
getContent() {
|
|
2659
|
-
|
|
2657
|
+
throw new Error("Method not implemented.");
|
|
2660
2658
|
}
|
|
2661
2659
|
toUrlParams() {
|
|
2662
2660
|
throw new Error("Method not implemented.");
|
|
@@ -2727,13 +2725,6 @@ class Filter {
|
|
|
2727
2725
|
});
|
|
2728
2726
|
return result;
|
|
2729
2727
|
};
|
|
2730
|
-
reset(children) {
|
|
2731
|
-
let data = children || this.data;
|
|
2732
|
-
data.forEach((element) => {
|
|
2733
|
-
element.selected = false;
|
|
2734
|
-
(element.children && element.children.length > 0) && this.reset(element.children);
|
|
2735
|
-
});
|
|
2736
|
-
}
|
|
2737
2728
|
}
|
|
2738
2729
|
|
|
2739
2730
|
class CategoryFilter extends Filter {
|
|
@@ -2870,31 +2861,27 @@ class DynamicsFilter extends Filter {
|
|
|
2870
2861
|
return 'dynamics';
|
|
2871
2862
|
}
|
|
2872
2863
|
setContent(options) {
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
return;
|
|
2876
|
-
}
|
|
2877
|
-
this.data = options.map((opt) => this.createElement(opt));
|
|
2864
|
+
options = options.map((option) => option = this.createElement(option));
|
|
2865
|
+
this.data = options;
|
|
2878
2866
|
}
|
|
2879
2867
|
getContent() {
|
|
2880
|
-
|
|
2868
|
+
throw new Error("Method not implemented.");
|
|
2881
2869
|
}
|
|
2882
2870
|
toUrlParams = (actual_url = '&optionCodes=', sublist, already) => {
|
|
2883
|
-
|
|
2871
|
+
let elements = sublist || this.data;
|
|
2884
2872
|
let aux_url = '';
|
|
2885
2873
|
elements.forEach((element) => {
|
|
2886
|
-
if (element.type
|
|
2887
|
-
|
|
2888
|
-
if (
|
|
2874
|
+
if (element.type == 'sub') {
|
|
2875
|
+
let result = this.toUrlParams('', element.children, (actual_url != '&optionCodes=' && actual_url != ''));
|
|
2876
|
+
if (!actual_url.includes(result))
|
|
2889
2877
|
actual_url += this.cleanResult(result);
|
|
2890
|
-
}
|
|
2891
2878
|
}
|
|
2892
2879
|
else if (element.selected) {
|
|
2893
|
-
if (actual_url
|
|
2880
|
+
if (actual_url == '&optionCodes=' && aux_url == '') {
|
|
2894
2881
|
aux_url = element.value;
|
|
2895
2882
|
}
|
|
2896
2883
|
else {
|
|
2897
|
-
if (aux_url
|
|
2884
|
+
if (aux_url == '')
|
|
2898
2885
|
aux_url = (already ? '<and>' : '') + element.value;
|
|
2899
2886
|
else
|
|
2900
2887
|
aux_url += ('<and>' + element.value);
|
|
@@ -2904,24 +2891,20 @@ class DynamicsFilter extends Filter {
|
|
|
2904
2891
|
return actual_url + aux_url;
|
|
2905
2892
|
};
|
|
2906
2893
|
createElement(option) {
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
type: 'child',
|
|
2920
|
-
value: value?.code,
|
|
2921
|
-
selected: false,
|
|
2922
|
-
image: value?.image
|
|
2923
|
-
}))
|
|
2894
|
+
option = {
|
|
2895
|
+
title: option.label, useToFilter: option.useToFilter, type: 'sub', multi: false, code: option.code, shape: option.type, children: option.values.map((value) => {
|
|
2896
|
+
return {
|
|
2897
|
+
title: value.code,
|
|
2898
|
+
description: value.name,
|
|
2899
|
+
code: (option.code + ' ' + value.name),
|
|
2900
|
+
type: 'child',
|
|
2901
|
+
value: value.code,
|
|
2902
|
+
selected: false,
|
|
2903
|
+
image: value.image
|
|
2904
|
+
};
|
|
2905
|
+
})
|
|
2924
2906
|
};
|
|
2907
|
+
return option;
|
|
2925
2908
|
}
|
|
2926
2909
|
cleanResult(text) { return text.replace('&optionCodes=', ''); }
|
|
2927
2910
|
;
|
|
@@ -3682,8 +3665,6 @@ class FiltersService {
|
|
|
3682
3665
|
environmentInjector = inject(EnvironmentInjector);
|
|
3683
3666
|
_optionsFilters = ['all'];
|
|
3684
3667
|
_defaultFilters = [];
|
|
3685
|
-
_filtersInView = new BehaviorSubject(null);
|
|
3686
|
-
filtersInView$ = this._filtersInView.asObservable();
|
|
3687
3668
|
_paginationSettings = {
|
|
3688
3669
|
value: '',
|
|
3689
3670
|
type: '',
|
|
@@ -3708,17 +3689,12 @@ class FiltersService {
|
|
|
3708
3689
|
*/
|
|
3709
3690
|
generateFinalApi(search_value) {
|
|
3710
3691
|
let extra_params = '';
|
|
3711
|
-
|
|
3712
|
-
const extra =
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
extra_params += extra;
|
|
3718
|
-
}
|
|
3719
|
-
if (search_value) {
|
|
3720
|
-
extra_params += `&criteria[search][type]=contains&criteria[search][value]=${encodeURIComponent(search_value)}`;
|
|
3721
|
-
}
|
|
3692
|
+
this._filtersSubject.value.forEach(filter => {
|
|
3693
|
+
const extra = filter.toUrlParams();
|
|
3694
|
+
extra.split('=')[1] != '' ? extra_params += extra : null;
|
|
3695
|
+
});
|
|
3696
|
+
if (search_value)
|
|
3697
|
+
extra_params += ('&criteria[search][type]=contains&criteria[search][value]=' + search_value);
|
|
3722
3698
|
return this.productsFilterApi(extra_params);
|
|
3723
3699
|
}
|
|
3724
3700
|
isUpdated(paginationSettings) {
|
|
@@ -3737,24 +3713,26 @@ class FiltersService {
|
|
|
3737
3713
|
setFilters(paginationSettings, search_value) {
|
|
3738
3714
|
this._paginationSettings = paginationSettings;
|
|
3739
3715
|
let final_filters = [];
|
|
3740
|
-
|
|
3716
|
+
let filtersToProcess = this._optionsFilters?.includes('all')
|
|
3741
3717
|
? ['attributes', 'categories', 'dynamics', 'sort', 'price_range']
|
|
3742
3718
|
: this._optionsFilters;
|
|
3743
3719
|
runInInjectionContext(this.environmentInjector, () => {
|
|
3744
3720
|
const filterFactory = new FilterFactory();
|
|
3745
3721
|
filtersToProcess?.forEach(filterType => {
|
|
3746
3722
|
const filter = filterFactory.create(filterType, paginationSettings);
|
|
3747
|
-
if (filter)
|
|
3723
|
+
if (filter) {
|
|
3748
3724
|
final_filters.push(filter);
|
|
3725
|
+
}
|
|
3726
|
+
else {
|
|
3727
|
+
// console.warn(`❌ Failed to create filter for type: ${filterType}`);
|
|
3728
|
+
}
|
|
3749
3729
|
});
|
|
3750
3730
|
});
|
|
3751
|
-
this._defaultFilters?.forEach(
|
|
3752
|
-
|
|
3753
|
-
|
|
3731
|
+
this._defaultFilters?.forEach(filterDefault => {
|
|
3732
|
+
let filter = final_filters.find(filter => filter.type() == filterDefault.filter_type);
|
|
3733
|
+
filter && filterDefault.codes.forEach(value => filter.setSelected(value));
|
|
3754
3734
|
});
|
|
3755
3735
|
this._filtersSubject.next(final_filters);
|
|
3756
|
-
if (!this._readySubject.value)
|
|
3757
|
-
this._readySubject.next(true);
|
|
3758
3736
|
}
|
|
3759
3737
|
getFilters(paginationSettings) {
|
|
3760
3738
|
if (this._filtersInitialized)
|
|
@@ -3793,13 +3771,12 @@ class FiltersService {
|
|
|
3793
3771
|
setFilterSelected(filterObj, filterElem) {
|
|
3794
3772
|
let final_filters = this._filtersSubject.value;
|
|
3795
3773
|
if (filterObj.type() !== 'price_range') {
|
|
3796
|
-
|
|
3774
|
+
let index = final_filters.findIndex(filter => filter.type() == filterObj.type());
|
|
3797
3775
|
final_filters[index].setSelected(filterElem, filterElem.value || filterElem.code);
|
|
3776
|
+
console.log(index, final_filters);
|
|
3798
3777
|
}
|
|
3799
3778
|
this._filtersSubject.next(final_filters);
|
|
3800
|
-
|
|
3801
|
-
this._filtersInView.next(filterElem);
|
|
3802
|
-
}
|
|
3779
|
+
// }
|
|
3803
3780
|
}
|
|
3804
3781
|
updateFilters(paginationFilters) {
|
|
3805
3782
|
const claves = Object.keys(paginationFilters);
|
|
@@ -3832,35 +3809,6 @@ class FiltersService {
|
|
|
3832
3809
|
pr.setSelected(min, max);
|
|
3833
3810
|
this._filtersSubject.next([...filters]);
|
|
3834
3811
|
}
|
|
3835
|
-
setOptionsFilters(filters) {
|
|
3836
|
-
this._optionsFilters = filters?.length ? filters : ['all'];
|
|
3837
|
-
}
|
|
3838
|
-
setDefaultFilters(defaults) {
|
|
3839
|
-
this._defaultFilters = defaults || [];
|
|
3840
|
-
}
|
|
3841
|
-
hydrateDynamics(options) {
|
|
3842
|
-
if (!options)
|
|
3843
|
-
return;
|
|
3844
|
-
const filters = this._filtersSubject.value || [];
|
|
3845
|
-
const dyn = filters.find(f => f.type() === 'dynamics');
|
|
3846
|
-
if (!dyn?.setContent)
|
|
3847
|
-
return;
|
|
3848
|
-
dyn.setContent(options);
|
|
3849
|
-
this._filtersSubject.next([...filters]);
|
|
3850
|
-
// Si querés que ready$ represente "filtros listos para render (incluye dinámicos)"
|
|
3851
|
-
if (!this._readySubject.value)
|
|
3852
|
-
this._readySubject.next(true);
|
|
3853
|
-
}
|
|
3854
|
-
/**
|
|
3855
|
-
* @description redirecciona segun la url del filtro.
|
|
3856
|
-
* @param filterElem No hace nada por ahora, es para mantener el mismo formato que como se usa en collection
|
|
3857
|
-
* @param data Filtro que se usa para redireccion
|
|
3858
|
-
*/
|
|
3859
|
-
setFilterSelectedByPath(filterElem, data, router) {
|
|
3860
|
-
if (!router || !data?.path)
|
|
3861
|
-
return;
|
|
3862
|
-
router.navigateByUrl(data.path);
|
|
3863
|
-
}
|
|
3864
3812
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FiltersService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3865
3813
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FiltersService, providedIn: 'root' });
|
|
3866
3814
|
}
|
|
@@ -3879,11 +3827,10 @@ class PaginationService {
|
|
|
3879
3827
|
_connectionService = inject(ConnectionService);
|
|
3880
3828
|
_filtersService = inject(FiltersService);
|
|
3881
3829
|
_constants = inject(CoreConstantsService);
|
|
3882
|
-
|
|
3883
|
-
paginationData$ = this._filtersService.filters$.pipe(filter(filters => Array.isArray(filters) && filters.length > 0), map(filters => {
|
|
3830
|
+
paginationData$ = this._filtersService.filters$.pipe(shareReplay(1), filter(filters => filters && filters.length > 0), switchMap((filters) => {
|
|
3884
3831
|
const url = this.buildUrl(filters);
|
|
3885
|
-
return
|
|
3886
|
-
})
|
|
3832
|
+
return this.getData(url);
|
|
3833
|
+
}));
|
|
3887
3834
|
_dataPagination = signal({
|
|
3888
3835
|
attributes: [],
|
|
3889
3836
|
category: [],
|
|
@@ -3920,7 +3867,6 @@ class PaginationService {
|
|
|
3920
3867
|
this._finished = false;
|
|
3921
3868
|
this._start = true;
|
|
3922
3869
|
this._nextProductsSubject.next([]);
|
|
3923
|
-
this._hydratedDynamics = false;
|
|
3924
3870
|
}
|
|
3925
3871
|
/**
|
|
3926
3872
|
* Obtengo los datos de la siguiente página.
|
|
@@ -4029,21 +3975,12 @@ class PaginationService {
|
|
|
4029
3975
|
this._resetSubject.next(true);
|
|
4030
3976
|
this._nextProductsSubject.next([]);
|
|
4031
3977
|
this._connectionService.get(url, { limit: 10, page: 1 }).pipe(map(res => {
|
|
4032
|
-
//
|
|
4033
|
-
if (!this._hydratedDynamics && res?.options) {
|
|
4034
|
-
this._filtersService.hydrateDynamics(res.options);
|
|
4035
|
-
this._hydratedDynamics = true;
|
|
4036
|
-
}
|
|
3978
|
+
//console.log(res)
|
|
4037
3979
|
this._nextProductsSubject.next(res.items);
|
|
4038
3980
|
res.links ? this.updatePageData(res) : this.finish(res);
|
|
4039
3981
|
})).subscribe();
|
|
4040
3982
|
return this.nextProducts$;
|
|
4041
3983
|
}
|
|
4042
|
-
urlSignature(filters) {
|
|
4043
|
-
const params = filters.map(f => (f?.toUrlParams?.() || '')).join('|');
|
|
4044
|
-
const sv = this._constants.searchValue || '';
|
|
4045
|
-
return params + '::' + sv;
|
|
4046
|
-
}
|
|
4047
3984
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PaginationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4048
3985
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PaginationService, providedIn: 'root' });
|
|
4049
3986
|
}
|
|
@@ -4108,15 +4045,8 @@ class ProductsService {
|
|
|
4108
4045
|
* @param searchValue
|
|
4109
4046
|
*/
|
|
4110
4047
|
getProductsForFilter(paginationSettings, searchValue) {
|
|
4111
|
-
|
|
4112
|
-
this.
|
|
4113
|
-
this._consts.searchValue = sv;
|
|
4114
|
-
if (paginationSettings) {
|
|
4115
|
-
this._filtersService.setFilters(paginationSettings);
|
|
4116
|
-
}
|
|
4117
|
-
const apiUrl = this._filtersService.generateFinalApi(sv);
|
|
4118
|
-
const limit = paginationSettings?.limit ?? 10;
|
|
4119
|
-
this._paginationService.initialize(apiUrl, limit);
|
|
4048
|
+
searchValue ? this.searchValue.set(searchValue) : this.searchValue.set('');
|
|
4049
|
+
paginationSettings && this._filtersService.setFilters(paginationSettings);
|
|
4120
4050
|
}
|
|
4121
4051
|
/**
|
|
4122
4052
|
* Actualiza los productos con los de la siguiente pagina.
|
|
@@ -8791,6 +8721,8 @@ class FiltersEcComponent {
|
|
|
8791
8721
|
console.error('Filter or selected element is undefined:', { filter, selected });
|
|
8792
8722
|
return;
|
|
8793
8723
|
}
|
|
8724
|
+
if (selected.isVisible !== true)
|
|
8725
|
+
return;
|
|
8794
8726
|
if (typeof filter.setSelected !== 'function') {
|
|
8795
8727
|
console.error('filter.setSelected is not a function. Filter might not be an instance of the expected class:', filter);
|
|
8796
8728
|
return;
|
|
@@ -8802,7 +8734,7 @@ class FiltersEcComponent {
|
|
|
8802
8734
|
this.router.navigate([selected.path]);
|
|
8803
8735
|
}
|
|
8804
8736
|
}
|
|
8805
|
-
else if (
|
|
8737
|
+
else if (filter.type() === 'attributes') {
|
|
8806
8738
|
// Manejar la navegación para atributos
|
|
8807
8739
|
this._filtersService.setFilterSelected(filter, selected);
|
|
8808
8740
|
}
|
|
@@ -8860,13 +8792,36 @@ class FiltersEcComponent {
|
|
|
8860
8792
|
}) ?? false;
|
|
8861
8793
|
}
|
|
8862
8794
|
/**
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8795
|
+
* Verifica si una categoría tiene la propiedad isVisible y está marcada como visible
|
|
8796
|
+
* @param category - La categoría a verificar
|
|
8797
|
+
* @returns true si la categoría es visible, false en caso contrario
|
|
8798
|
+
*/
|
|
8867
8799
|
hasVisibleProperty(category) {
|
|
8868
8800
|
return category.isVisible === true;
|
|
8869
8801
|
}
|
|
8802
|
+
/** Lista visible (filtra recursivo por isVisible) */
|
|
8803
|
+
getVisibleData(filter) {
|
|
8804
|
+
if (!filter)
|
|
8805
|
+
return [];
|
|
8806
|
+
return this.filterVisibleTree(filter.data);
|
|
8807
|
+
}
|
|
8808
|
+
/** Children visibles de un nodo */
|
|
8809
|
+
getVisibleChildren(node) {
|
|
8810
|
+
return this.filterVisibleTree(node?.children ?? []);
|
|
8811
|
+
}
|
|
8812
|
+
/** Tiene hijos visibles? */
|
|
8813
|
+
hasVisibleChildren(node) {
|
|
8814
|
+
return this.getVisibleChildren(node).length > 0;
|
|
8815
|
+
}
|
|
8816
|
+
/** Utilidad recursiva */
|
|
8817
|
+
filterVisibleTree(list = []) {
|
|
8818
|
+
return (list ?? [])
|
|
8819
|
+
.filter(n => n.isVisible === true)
|
|
8820
|
+
.map(n => ({
|
|
8821
|
+
...n,
|
|
8822
|
+
children: this.filterVisibleTree(n.children ?? [])
|
|
8823
|
+
}));
|
|
8824
|
+
}
|
|
8870
8825
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FiltersEcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8871
8826
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FiltersEcComponent, isStandalone: true, selector: "lib-filters-ec", inputs: { setSelect: "setSelect" }, ngImport: i0, template: "<p>filters-ec works!</p>\n", styles: [""] });
|
|
8872
8827
|
}
|