@elderbyte/ngx-starter 16.3.0 → 16.3.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.
@@ -2539,6 +2539,9 @@ class FilterContext {
2539
2539
  **************************************************************************/
2540
2540
  this._filters$ = new BehaviorSubject([]);
2541
2541
  }
2542
+ static empty() {
2543
+ return new FilterContext();
2544
+ }
2542
2545
  /***************************************************************************
2543
2546
  * *
2544
2547
  * Static Utilities *
@@ -25822,58 +25825,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.11", ngImpo
25822
25825
  type: Input
25823
25826
  }] } });
25824
25827
 
25825
- class SearchContextOrchestrator {
25826
- /***************************************************************************
25827
- * *
25828
- * Constructor *
25829
- * *
25830
- **************************************************************************/
25831
- constructor(filterContext, forcedFilters) {
25832
- this.filterContext = filterContext;
25833
- this.forcedFilters = forcedFilters;
25834
- this.initialFilterContext = new FilterContext();
25835
- this.log = LoggerFactory.getLogger(this.constructor.name);
25836
- this.initialFilterContext.updateFilters(filterContext.filtersSnapshot);
25837
- if (forcedFilters) {
25838
- this.initialFilterContext.updateFilters(forcedFilters);
25839
- }
25840
- }
25841
- /***************************************************************************
25842
- * *
25843
- * Properties *
25844
- * *
25845
- **************************************************************************/
25846
- get initialFilters$() {
25847
- return this.initialFilterContext.filters
25848
- .pipe(startWith(this.initialFilterContext.filtersSnapshot));
25849
- }
25850
- get filters() {
25851
- return this.filterContext.filters;
25852
- }
25853
- /***************************************************************************
25854
- * *
25855
- * Public Api *
25856
- * *
25857
- **************************************************************************/
25858
- addInitialFilters(filters) {
25859
- this.initialFilterContext.updateFilters(filters);
25860
- }
25861
- applyFilters(userFilters) {
25862
- const context = this.filterContext;
25863
- if (context) {
25864
- context.updateFilters(userFilters);
25865
- context.mergeFilters(this.forcedFilters);
25866
- this.log.trace("Search-Model filters updated:", Array.from(context.filtersSnapshot));
25867
- }
25868
- else {
25869
- this.log.warn("Failed to apply filters since no FilterContext is available!", {
25870
- userFilters: userFilters,
25871
- forcedFilters: this.forcedFilters
25872
- });
25873
- }
25874
- }
25875
- }
25876
-
25877
25828
  /**
25878
25829
  * The search container manages a group of search-inputs
25879
25830
  * and holds their values in a central search model.
@@ -25890,6 +25841,7 @@ class ElderSearchContextDirective {
25890
25841
  this.destroy$ = new Subject$1();
25891
25842
  this._searchInputs$ = new BehaviorSubject$1([]);
25892
25843
  this._searchStates$ = new BehaviorSubject$1([]);
25844
+ this._filterContext$ = new BehaviorSubject$1(null);
25893
25845
  }
25894
25846
  /***************************************************************************
25895
25847
  * *
@@ -25897,19 +25849,32 @@ class ElderSearchContextDirective {
25897
25849
  * *
25898
25850
  **************************************************************************/
25899
25851
  ngAfterContentInit() {
25900
- this._searchInputs$.pipe(takeUntil(this.destroy$), switchMap(inputs => combineLatest(inputs.map(i => i.state$))), debounceTime(5)).subscribe((states) => {
25852
+ this._searchInputs$.pipe(takeUntil(this.destroy$), switchMap(inputs => combineLatest(inputs.map(i => i.state$))), combineLatestWith(this._forcedFilters$), debounceTime(5)).subscribe(([states, forcedFilters]) => {
25901
25853
  this._searchStates$.next(states);
25902
25854
  const userFilters = this.convertToFilters(states);
25903
- this.searchContextOrchestrator.applyFilters(userFilters);
25855
+ this.applyFilters(userFilters, forcedFilters);
25904
25856
  });
25905
25857
  }
25858
+ applyFilters(userFilters, forcedFilters) {
25859
+ const context = this.filterContext;
25860
+ if (context) {
25861
+ context.updateFilters(userFilters);
25862
+ context.mergeFilters(forcedFilters);
25863
+ this.log.trace("Search-Model filters updated:", Array.from(context.filtersSnapshot));
25864
+ }
25865
+ else {
25866
+ this.log.warn("Failed to apply filters since no FilterContext is available!", {
25867
+ userFilters: userFilters,
25868
+ forcedFilters: forcedFilters
25869
+ });
25870
+ }
25871
+ }
25906
25872
  ngAfterViewInit() {
25907
- this.subscribeInitialFilters();
25873
+ this.applyModelToInputs();
25908
25874
  }
25909
25875
  ngOnDestroy() {
25910
25876
  this.destroy$.next();
25911
25877
  this.destroy$.complete();
25912
- this._searchContextOrchestrator = null;
25913
25878
  }
25914
25879
  /***************************************************************************
25915
25880
  * *
@@ -25917,21 +25882,23 @@ class ElderSearchContextDirective {
25917
25882
  * *
25918
25883
  **************************************************************************/
25919
25884
  set filterContext(value) {
25885
+ let context;
25920
25886
  if (value) {
25921
- if (typeof value !== 'string') {
25922
- this._searchContextOrchestrator = new SearchContextOrchestrator(value, this.forcedFilters);
25887
+ if (typeof value !== "string") {
25888
+ context = value;
25923
25889
  }
25924
25890
  else {
25925
- this.log.warn('Illegal value provided for property filterContext: ', JSON.stringify(value));
25926
- throw new Error('Illegal value provided for property filterContext! ' + value);
25891
+ this.log.warn("Illegal value provided for property filterContext: ", JSON.stringify(value));
25892
+ throw new Error("Illegal value provided for property filterContext! " + value);
25927
25893
  }
25928
25894
  }
25929
25895
  else {
25930
- this._searchContextOrchestrator = new SearchContextOrchestrator(null);
25896
+ context = FilterContext.empty();
25931
25897
  }
25898
+ this._filterContext$.next(context);
25932
25899
  }
25933
25900
  get filterContext() {
25934
- return this.searchContextOrchestrator.filterContext;
25901
+ return this._filterContext$.getValue();
25935
25902
  }
25936
25903
  /**
25937
25904
  * Forced filters are always merged into the final FilterContext.
@@ -25957,9 +25924,6 @@ class ElderSearchContextDirective {
25957
25924
  get statesSnapshot() {
25958
25925
  return this._searchStates$.getValue();
25959
25926
  }
25960
- get searchContextOrchestrator() {
25961
- return this._searchContextOrchestrator;
25962
- }
25963
25927
  /**
25964
25928
  * Returns the current user touched attributes. (ignoring fallbacks)
25965
25929
  */
@@ -25975,7 +25939,7 @@ class ElderSearchContextDirective {
25975
25939
  * Register a new search name in this container
25976
25940
  */
25977
25941
  register(searchInput) {
25978
- this.log.debug('Registering search input [' + searchInput.name + ']');
25942
+ this.log.debug("Registering search input [" + searchInput.name + "]");
25979
25943
  const current = this._searchInputs$.getValue();
25980
25944
  this._searchInputs$.next([...current, searchInput]);
25981
25945
  }
@@ -25991,14 +25955,27 @@ class ElderSearchContextDirective {
25991
25955
  * Private *
25992
25956
  * *
25993
25957
  **************************************************************************/
25994
- subscribeInitialFilters() {
25995
- this.searchContextOrchestrator.initialFilters$.pipe(takeUntil(this.destroy$), combineLatestWith(this._searchInputs$)).subscribe(([initialFilters, searchInputs]) => {
25996
- searchInputs.forEach(input => {
25997
- const filter = this.findFilterForInput(input, initialFilters);
25998
- if (filter) {
25999
- input.applyInitialValue(filter.value);
26000
- }
26001
- });
25958
+ applyModelToInputs() {
25959
+ this.log.warn('applyModelToInputs', {
25960
+ filterSnapshot: this._filterContext$.getValue().filtersSnapshot,
25961
+ forcedFilters: this.forcedFilters
25962
+ });
25963
+ const mergedFilters = this.mergeFilters(this._filterContext$.getValue().filtersSnapshot, this.forcedFilters);
25964
+ this.applyFiltersToInputs(mergedFilters);
25965
+ }
25966
+ mergeFilters(filtersA, filtersB) {
25967
+ const mergeContext = new FilterContext();
25968
+ mergeContext.updateFilters(filtersA);
25969
+ mergeContext.mergeFilters(filtersB);
25970
+ return mergeContext.filtersSnapshot;
25971
+ }
25972
+ applyFiltersToInputs(filters) {
25973
+ this.log.warn('applyFiltersToInputs', filters);
25974
+ this._searchInputs$.getValue().forEach(input => {
25975
+ const filter = this.findFilterForInput(input, filters);
25976
+ if (filter) {
25977
+ input.applyInitialValue(filter.value);
25978
+ }
26002
25979
  });
26003
25980
  }
26004
25981
  findFilterForInput(input, filters) {
@@ -26020,12 +25997,12 @@ class ElderSearchContextDirective {
26020
25997
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.11", ngImport: i0, type: ElderSearchContextDirective, decorators: [{
26021
25998
  type: Directive,
26022
25999
  args: [{
26023
- selector: '[elderSearchContext]',
26024
- exportAs: 'elderSearchContext'
26000
+ selector: "[elderSearchContext]",
26001
+ exportAs: "elderSearchContext"
26025
26002
  }]
26026
26003
  }], propDecorators: { filterContext: [{
26027
26004
  type: Input,
26028
- args: ['elderSearchContext']
26005
+ args: ["elderSearchContext"]
26029
26006
  }], forcedFilters: [{
26030
26007
  type: Input
26031
26008
  }] } });
@@ -26121,7 +26098,7 @@ class ElderInitialValueDirective {
26121
26098
  **************************************************************************/
26122
26099
  constructor(ngModel) {
26123
26100
  //TODO: The debounce time is a hacky workaround, find a proper way to set initial value.
26124
- // Currently two way binding ngModel deosnt work.
26101
+ // ngModel regular and two way binding differ in initial value, which led to this solution
26125
26102
  this.ngModel = ngModel;
26126
26103
  /***************************************************************************
26127
26104
  * *
@@ -26132,19 +26109,15 @@ class ElderInitialValueDirective {
26132
26109
  this.initialValue$ = new BehaviorSubject(null);
26133
26110
  this.destroy$ = new Subject();
26134
26111
  this.initialDone$ = new Subject();
26135
- this.isInitial = true;
26136
26112
  const ngModelValue$ = of("dummy")
26137
26113
  .pipe(delay(10), map(() => this.ngModel.model));
26138
26114
  ngModelValue$
26139
- .pipe(combineLatestWith$1(this.initialValue$), takeUntil(this.initialDone$), takeUntil(this.destroy$)).subscribe({
26140
- next: ([ngModelValue, initialValue]) => {
26141
- this.log.warn("initialValue: " + initialValue);
26142
- if (initialValue) {
26143
- ngModel.control.setValue(initialValue);
26144
- }
26145
- this.initialDone$.next();
26146
- this.initialDone$.complete();
26115
+ .pipe(combineLatestWith$1(this.initialValue$), takeUntil(this.initialDone$), takeUntil(this.destroy$)).subscribe(([ngModelValue, initialValue]) => {
26116
+ if (initialValue) {
26117
+ ngModel.control.setValue(initialValue);
26147
26118
  }
26119
+ this.initialDone$.next();
26120
+ this.initialDone$.complete();
26148
26121
  });
26149
26122
  // this.ngModelValue = this.ngModel.model;
26150
26123
  // ngModel.control.valueChanges
@@ -26181,9 +26154,7 @@ class ElderInitialValueDirective {
26181
26154
  **************************************************************************/
26182
26155
  get valueChanges$() {
26183
26156
  return this.ngModel.control.valueChanges
26184
- .pipe(takeUntil(this.destroy$)
26185
- //filter(value => this.filterInitialValue(value))
26186
- );
26157
+ .pipe(takeUntil(this.destroy$));
26187
26158
  }
26188
26159
  applyInitialValue(value) {
26189
26160
  this.initialValue$.next(value);
@@ -26192,18 +26163,6 @@ class ElderInitialValueDirective {
26192
26163
  this.destroy$.next();
26193
26164
  this.destroy$.complete();
26194
26165
  }
26195
- /***************************************************************************
26196
- * *
26197
- * Private methods *
26198
- * *
26199
- **************************************************************************/
26200
- filterInitialValue(value) {
26201
- if (this.isInitial && this.ngModelValue$ === value) {
26202
- this.isInitial = false;
26203
- return false;
26204
- }
26205
- return true;
26206
- }
26207
26166
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.11", ngImport: i0, type: ElderInitialValueDirective, deps: [{ token: i3.NgModel, host: true }], target: i0.ɵɵFactoryTarget.Directive }); }
26208
26167
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.11", type: ElderInitialValueDirective, selector: "[elderInitialValue]", exportAs: ["elderInitialValue"], ngImport: i0 }); }
26209
26168
  }
@@ -26240,10 +26199,13 @@ class ElderSearchInputDirective {
26240
26199
  * Life Cycle *
26241
26200
  * *
26242
26201
  **************************************************************************/
26243
- ngAfterViewInit() {
26202
+ ngOnInit() {
26244
26203
  this._extractedName = this.extractName();
26245
- this.log.debug(this.extractName() + "|" + this.queryKey + "|" + this.resolvePath);
26246
26204
  this.searchContext.register(this);
26205
+ }
26206
+ ngAfterViewInit() {
26207
+ this._extractedName = this.extractName();
26208
+ this.log.debug(this._extractedName + "|" + this.queryKey + "|" + this.resolvePath);
26247
26209
  this.stateObservable().subscribe(state => {
26248
26210
  this.emitState(state);
26249
26211
  });
@@ -26899,71 +26861,101 @@ class ElderSearchContextFilters {
26899
26861
  }
26900
26862
 
26901
26863
  class ElderSearchUrlBindingService {
26864
+ /***************************************************************************
26865
+ * *
26866
+ * Constructor *
26867
+ * *
26868
+ **************************************************************************/
26902
26869
  constructor(router, route) {
26903
26870
  this.router = router;
26904
26871
  this.route = route;
26905
- //A search param has following structure: search-[searchContextId]-[filterId]=[value]
26872
+ //A search param has following structure: q-[searchContextId]-[filterId]=[value]
26906
26873
  //Example: search-browser1-hasStarted=true
26907
- this._searchMap$ = new BehaviorSubject$1(new Map());
26874
+ /***************************************************************************
26875
+ * *
26876
+ * Fields *
26877
+ * *
26878
+ **************************************************************************/
26879
+ this.log = LoggerFactory.getLogger(this.constructor.name);
26880
+ this._searchMap$ = new BehaviorSubject$1({
26881
+ value: new Map(),
26882
+ emit: true
26883
+ });
26908
26884
  this._initialSearchMap$ = new BehaviorSubject$1(new Map());
26909
26885
  this.searchParamPrefix = "q";
26910
26886
  this.unsubscribe$ = new Subject();
26911
26887
  this.router.events.pipe(first()).subscribe(() => {
26912
26888
  this.handleSearchParameters(this.route.snapshot.queryParams);
26913
26889
  });
26914
- this._searchMap$.pipe(takeUntil(this.unsubscribe$)).subscribe(searchMap => {
26890
+ this._searchMap$.pipe(filter(searchMapUpdate => searchMapUpdate.emit), takeUntil(this.unsubscribe$)).subscribe(searchMapUpdate => {
26891
+ this.log.warn("SET URL");
26892
+ const searchMap = searchMapUpdate.value;
26915
26893
  const resetParams = this.resetSearchParams();
26916
26894
  const queryParams = { ...resetParams, ...this.buildQueryParams(searchMap) };
26895
+ this.log.warn("searchMap :", searchMap);
26896
+ this.log.warn("queryParams :", queryParams);
26917
26897
  this.router.navigate([], {
26918
- relativeTo: this.route,
26919
26898
  queryParams: queryParams,
26920
26899
  replaceUrl: true,
26921
26900
  queryParamsHandling: "merge"
26922
26901
  });
26923
26902
  });
26903
+ this.router.events.subscribe((event) => this.log.warn("Type: " + event.constructor?.name, event));
26924
26904
  }
26925
- resetSearchParams() {
26926
- let params = { ...this.route.snapshot.queryParams };
26927
- const searchParams = this.extractSearchParameters(params);
26928
- for (const searchParam of searchParams) {
26929
- params[searchParam] = null;
26930
- }
26931
- return params;
26932
- }
26933
- buildQueryParams(searchMap) {
26934
- const params = {};
26935
- for (const searchContextId of searchMap.keys()) {
26936
- const filters = searchMap.get(searchContextId).filters;
26937
- for (const filter of filters.values()) {
26938
- params[`${this.searchParamPrefix}-${searchContextId}-${filter.key}`] = this.convertValueToArrayOrSingleValue(filter.value);
26939
- }
26940
- }
26941
- return params;
26942
- }
26943
- convertValueToArrayOrSingleValue(value) {
26944
- return Array.isArray(value) ? `(${value.toString()})` : value;
26905
+ /***************************************************************************
26906
+ * *
26907
+ * Life Cycle *
26908
+ * *
26909
+ **************************************************************************/
26910
+ ngOnDestroy() {
26911
+ this.unsubscribe$.next();
26912
+ this.unsubscribe$.complete();
26945
26913
  }
26914
+ /***************************************************************************
26915
+ * *
26916
+ * Properties *
26917
+ * *
26918
+ **************************************************************************/
26946
26919
  get initialSearchMap$() {
26947
26920
  return this._initialSearchMap$;
26948
26921
  }
26922
+ /***************************************************************************
26923
+ * *
26924
+ * Public API *
26925
+ * *
26926
+ **************************************************************************/
26949
26927
  updateFiltersForContext(searchContextId, filters) {
26950
- const searchMap = this._searchMap$.getValue();
26928
+ const searchMapUpdate = this._searchMap$.getValue();
26929
+ const searchMap = searchMapUpdate.value;
26951
26930
  const filtersMap = new Map(filters
26952
26931
  .filter(filter => filter.value != null)
26953
26932
  .map(filter => {
26954
26933
  return [filter.key, filter];
26955
26934
  }));
26956
26935
  searchMap.set(searchContextId, new ElderSearchContextFilters(searchContextId, filtersMap));
26957
- this._searchMap$.next(searchMap);
26936
+ this._searchMap$.next({ value: searchMap, emit: true });
26958
26937
  }
26938
+ resetFilterForContext(contextId) {
26939
+ const searchMapUpdate = this._searchMap$.getValue();
26940
+ const searchMap = searchMapUpdate.value;
26941
+ if (searchMap.has(contextId)) {
26942
+ searchMap.delete(contextId);
26943
+ this._searchMap$.next({ value: searchMap, emit: false });
26944
+ }
26945
+ }
26946
+ /***************************************************************************
26947
+ * *
26948
+ * Private methods *
26949
+ * *
26950
+ **************************************************************************/
26959
26951
  handleSearchParameters(params) {
26960
26952
  const searchParamKeys = this.extractSearchParameters(params);
26961
26953
  const searchMap = this.buildSearchContextMap(params, searchParamKeys);
26962
- this._searchMap$.next(searchMap);
26954
+ this._searchMap$.next({ value: searchMap, emit: true });
26963
26955
  this._initialSearchMap$.next(searchMap);
26964
26956
  }
26965
26957
  extractSearchParameters(params) {
26966
- return Object.getOwnPropertyNames(params).filter(param => param.startsWith(this.searchParamPrefix));
26958
+ return Object.getOwnPropertyNames(params).filter(param => param.startsWith(this.searchParamPrefix + "-"));
26967
26959
  }
26968
26960
  buildSearchContextMap(params, searchParamKeys) {
26969
26961
  const searchMap = new Map();
@@ -27012,9 +27004,26 @@ class ElderSearchUrlBindingService {
27012
27004
  convertValueToArray(value) {
27013
27005
  return value.slice(1).slice(0, -1).split(",");
27014
27006
  }
27015
- ngOnDestroy() {
27016
- this.unsubscribe$.next();
27017
- this.unsubscribe$.complete();
27007
+ resetSearchParams() {
27008
+ let params = { ...this.route.snapshot.queryParams };
27009
+ const searchParams = this.extractSearchParameters(params);
27010
+ for (const searchParam of searchParams) {
27011
+ params[searchParam] = null;
27012
+ }
27013
+ return params;
27014
+ }
27015
+ buildQueryParams(searchMap) {
27016
+ const params = {};
27017
+ for (const searchContextId of searchMap.keys()) {
27018
+ const filters = searchMap.get(searchContextId).filters;
27019
+ for (const filter of filters.values()) {
27020
+ params[`${this.searchParamPrefix}-${searchContextId}-${filter.key}`] = this.convertValueToArrayOrSingleValue(filter.value);
27021
+ }
27022
+ }
27023
+ return params;
27024
+ }
27025
+ convertValueToArrayOrSingleValue(value) {
27026
+ return Array.isArray(value) ? `(${value.toString()})` : value;
27018
27027
  }
27019
27028
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.11", ngImport: i0, type: ElderSearchUrlBindingService, deps: [{ token: i1$3.Router }, { token: i1$3.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable }); }
27020
27029
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.11", ngImport: i0, type: ElderSearchUrlBindingService, providedIn: "root" }); }
@@ -27053,12 +27062,17 @@ class ElderSearchContextUrlBindingDirective {
27053
27062
  * *
27054
27063
  **************************************************************************/
27055
27064
  ngAfterViewInit() {
27056
- this.urlBindingService.initialSearchMap$.pipe(first(), takeUntil(this._unsubscribe$), filter(searchMap => searchMap.has(this._urlBinding)), map(searchMap => searchMap.get(this._urlBinding)), map(filterMap => Array.from(filterMap.filters.values()))).subscribe(filters => {
27057
- this.searchContext.searchContextOrchestrator.addInitialFilters(filters);
27058
- });
27059
- this.searchContext.searchContextOrchestrator.filters.pipe(takeUntil(this._unsubscribe$)).subscribe(filters => this.urlBindingService.updateFiltersForContext(this._urlBinding, filters));
27065
+ if (this._urlBinding) {
27066
+ this.urlBindingService.initialSearchMap$.pipe(first(), takeUntil(this._unsubscribe$), filter(searchMap => searchMap.has(this._urlBinding)), map(searchMap => searchMap.get(this._urlBinding)), map(filterMap => Array.from(filterMap.filters.values()))).subscribe(filters => {
27067
+ this.searchContext.filterContext.updateFilters(filters);
27068
+ this.searchContext.applyModelToInputs();
27069
+ // this.searchContext.searchFilterContext.addInitialFilters(filters)
27070
+ });
27071
+ this.searchContext.filterContext.filters.pipe(takeUntil(this._unsubscribe$)).subscribe(filters => this.urlBindingService.updateFiltersForContext(this._urlBinding, filters));
27072
+ }
27060
27073
  }
27061
27074
  ngOnDestroy() {
27075
+ this.urlBindingService.resetFilterForContext(this._urlBinding);
27062
27076
  this._unsubscribe$.next();
27063
27077
  this._unsubscribe$.complete();
27064
27078
  }