@firestitch/filter 12.12.0 → 12.12.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.
@@ -2,12 +2,8 @@ import * as i0 from '@angular/core';
2
2
  import { Injectable, Optional, Component, ChangeDetectionStrategy, Inject, InjectionToken, Input, Directive, Self, Pipe, ViewChild, EventEmitter, Output, HostListener, TemplateRef, ViewEncapsulation, ContentChild, HostBinding, NgModule } from '@angular/core';
3
3
  import { BehaviorSubject, Subject, isObservable, forkJoin, of, fromEvent, merge, timer, combineLatest } from 'rxjs';
4
4
  import { tap, finalize, take, takeUntil, debounceTime, filter as filter$1, distinctUntilChanged, switchMap, skip, delay, mapTo, startWith, map } from 'rxjs/operators';
5
+ import { filter, isArrayEqual, list, isEmpty, getNormalizedPath, remove, FsCommonModule } from '@firestitch/common';
5
6
  import { isFunction, isObject, clone, isString, toString, pickBy } from 'lodash-es';
6
- import { filter, isArrayEqual, isEmpty, getNormalizedPath, list, remove, FsCommonModule } from '@firestitch/common';
7
- import { simpleFormat, format } from '@firestitch/date';
8
- import { parseISO, isValid, isDate } from 'date-fns';
9
- import * as i3$3 from '@firestitch/datepicker';
10
- import { formatPeriodObject, FsDatePickerModule } from '@firestitch/datepicker';
11
7
  import * as i3 from '@angular/common';
12
8
  import { CommonModule } from '@angular/common';
13
9
  import * as i1$1 from '@angular/router';
@@ -17,6 +13,10 @@ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
17
13
  import * as i6 from '@firestitch/drawer';
18
14
  import * as i1 from '@firestitch/store';
19
15
  import { FsPersistanceStore, FsStoreModule, FsStore } from '@firestitch/store';
16
+ import { simpleFormat, format } from '@firestitch/date';
17
+ import { parseISO, isValid, isDate } from 'date-fns';
18
+ import * as i3$3 from '@firestitch/datepicker';
19
+ import { formatPeriodObject, FsDatePickerModule } from '@firestitch/datepicker';
20
20
  import * as i1$3 from '@angular/material/form-field';
21
21
  import * as i2 from '@angular/material/select';
22
22
  import { MatSelectModule } from '@angular/material/select';
@@ -57,6 +57,16 @@ import * as i1$5 from '@angular/cdk/layout';
57
57
  import * as i1$7 from '@angular/cdk/overlay';
58
58
  import { OverlayConfig } from '@angular/cdk/overlay';
59
59
 
60
+ const QUERY_PARAM_DELIMITER = ':';
61
+
62
+ function filterToQueryParam(value, name) {
63
+ return `${encodeURIComponent(value)}${QUERY_PARAM_DELIMITER}${encodeURIComponent(name)}`;
64
+ }
65
+ function filterFromQueryParam(param) {
66
+ const parts = param.split(QUERY_PARAM_DELIMITER);
67
+ return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])];
68
+ }
69
+
60
70
  var ItemType;
61
71
  (function (ItemType) {
62
72
  ItemType["Text"] = "text";
@@ -464,176 +474,31 @@ class MultipleSelectItem extends BaseSelectItem {
464
474
  }
465
475
  }
466
476
 
467
- function findValue(values, value, children) {
468
- for (let i = 0; i < values.length; i++) {
469
- const val = values[i];
470
- if (val[children]) {
471
- return findValue(val[children], value, children);
472
- }
473
- if (val.value === value) {
474
- return val;
475
- }
476
- }
477
- return undefined;
478
- }
479
-
480
- class SimpleSelectItem extends BaseSelectItem {
481
- constructor(itemConfig, _persistedValues) {
482
- super(itemConfig, _persistedValues);
483
- }
484
- get value() {
485
- let value = this.model;
486
- if (value == '__all' || value === undefined) {
487
- value = undefined;
488
- }
489
- return value;
490
- }
491
- getChipsContent(type = null) {
492
- if (this.children) {
493
- const itemValue = findValue(this.values, this.model, this.children);
494
- return itemValue && itemValue.name;
495
- }
496
- else {
497
- const itemValue = this.values.find((val) => val.value === this.model);
498
- if (itemValue) {
499
- return itemValue.name;
500
- }
501
- else if (this.isolate) {
502
- return this.isolate.label;
477
+ function buildQueryParams(flattenedParams, items) {
478
+ items.forEach(filterItem => {
479
+ if (filterItem instanceof MultipleSelectItem && filterItem.isolate) {
480
+ if (filterItem.multiple && filterItem.value) {
481
+ const isolated = list(filterItem.values, 'value').sort();
482
+ const value = filterItem.value.sort();
483
+ if (arraysAreEquals(value, isolated)) {
484
+ flattenedParams[filterItem.name] = null;
485
+ }
503
486
  }
504
487
  }
505
- }
506
- get isChipVisible() {
507
- return this.model !== '__all' && this.model !== undefined;
508
- }
509
- _init() {
510
- super._init();
511
- if (this.model === undefined && this.defaultValue === undefined) {
512
- this._model = '__all';
513
- }
514
- }
515
- get isolateOptionNotSelected() {
516
- const modelValue = this.model;
517
- const isolate = this.isolate;
518
- return isolate && !isolate.enabled && (modelValue === null || modelValue === void 0 ? void 0 : modelValue.length) === 0;
519
- }
520
- _setModel(value) {
521
- if (value) {
522
- if (!isNaN(value)) {
523
- value = +value;
488
+ if (filterItem.isTypeAutocomplete) {
489
+ if (isObject(filterItem.model)) {
490
+ flattenedParams[filterItem.name] = filterToQueryParam(filterItem.model.value, filterItem.model.name);
524
491
  }
525
492
  }
526
- super._setModel(value);
527
- }
528
- _validateModel() {
529
- const item = this.values.find(value => {
530
- return value.value == this.model;
531
- });
532
- const value = item ? item.value : '__all';
533
- if (this._model !== value) {
534
- this.model = value;
535
- }
536
- }
537
- _clearValue(defaultValue = undefined) {
538
- super._clearValue(defaultValue);
539
- const value = Array.isArray(this.values) && this.values.some((val) => val.value === '__all')
540
- ? '__all'
541
- : undefined;
542
- this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
543
- }
544
- }
545
-
546
- class SelectItem {
547
- static create(config) {
548
- if (config.multiple) {
549
- return new MultipleSelectItem(config, null);
550
- }
551
- else {
552
- return new SimpleSelectItem(config, null);
553
- }
554
- }
555
- }
556
-
557
- class ChipsItem extends BaseItem {
558
- static create(config) {
559
- return new ChipsItem(config, null);
560
- }
561
- get isTypeChips() {
562
- return true;
563
- }
564
- get value() {
565
- const value = clone(this.model);
566
- if (Array.isArray(value) && value.length === 0) {
567
- return undefined;
568
- }
569
- return value;
570
- }
571
- get isChipVisible() {
572
- return !!this.value;
573
- }
574
- get queryObject() {
575
- const value = this.value;
576
- const name = this.name;
577
- return {
578
- [name]: value
579
- };
580
- }
581
- get persistanceObject() {
582
- const value = this.value;
583
- const name = this.name;
584
- const params = {};
585
- if (Array.isArray(value)) {
586
- params[name] = value.join(',');
587
- }
588
- else {
589
- params[name] = undefined;
590
- }
591
- return params;
592
- }
593
- getChipsContent() {
594
- return this.model
595
- .reduce((acc, i) => {
596
- acc.push(i.name);
597
- return acc;
598
- }, [])
599
- .join(', ');
600
- }
601
- _validateModel() { }
602
- _setModel(value) {
603
- if (Array.isArray(value)) {
604
- value = value.map((val) => {
605
- if (isNaN(val)) {
606
- return val;
607
- }
608
- else {
609
- return +val;
610
- }
611
- });
612
- }
613
- this._model = value;
614
- }
615
- _parseConfig(item) {
616
- this.multiple = item.multiple;
617
- super._parseConfig(item);
618
- }
619
- _init() {
620
- if (!Array.isArray(this.values)) {
621
- this.values = [];
622
- }
623
- if (this.model && Array.isArray(this.model) && this.values.length) {
624
- if (Number.isInteger(this.model[0])) {
625
- this._model = this.model.map((id) => {
626
- return this.values.find((value) => value.value === id);
627
- });
493
+ else if (filterItem.isTypeAutocompleteChips || filterItem.isTypeChips) {
494
+ if (Array.isArray(filterItem.model) && filterItem.model.length) {
495
+ flattenedParams[filterItem.name] = filterItem.model.map((item) => {
496
+ return filterToQueryParam(item.value, item.name);
497
+ }).join(',');
628
498
  }
629
499
  }
630
- if (this.model === undefined) {
631
- this._model = [];
632
- }
633
- }
634
- _clearValue(defaultValue = undefined) {
635
- this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : [];
636
- }
500
+ });
501
+ return flattenedParams;
637
502
  }
638
503
 
639
504
  function getRangeName(configCase, name, range) {
@@ -872,47 +737,444 @@ class DateTimeRangeItem extends BaseDateRangeItem {
872
737
  }
873
738
  }
874
739
 
875
- var ItemDateMode;
876
- (function (ItemDateMode) {
877
- ItemDateMode["Calendar"] = "calendar";
878
- ItemDateMode["ScrollMonthYear"] = "monthyear";
879
- ItemDateMode["ScrollMonthDayYear"] = "monthdayyear";
880
- })(ItemDateMode || (ItemDateMode = {}));
740
+ function tryConvertToNumber(val) {
741
+ return isNaN(val)
742
+ ? val
743
+ : +val;
744
+ }
881
745
 
882
- class BaseDateItem extends BaseItem {
883
- get value() {
884
- const value = clone(this.model);
885
- if (!value || !isValid(value) || !isDate(value)) {
886
- return undefined;
746
+ function parseItemValueFromStored(item, params, paramCase) {
747
+ const param = params[item.name];
748
+ switch (item.type) {
749
+ case ItemType.Range: {
750
+ const min = params[getRangeName(paramCase, item.name, 'min')];
751
+ const max = params[getRangeName(paramCase, item.name, 'max')];
752
+ return { min: min, max: max };
887
753
  }
888
- return value;
889
- }
890
- get queryObject() {
891
- const value = this.value;
892
- const name = this.name;
893
- const params = {};
894
- params[name] = value;
895
- return params;
896
- }
897
- get persistanceObject() {
898
- const value = this.queryObject[this.name];
899
- return {
900
- [this.name]: value ? simpleFormat(value) : undefined,
901
- };
902
- }
903
- _validateModel() {
904
- }
905
- _setModel(value) {
906
- if (value) {
907
- if (!isDate(value) || !isValid(value)) {
908
- value = parseISO(value);
909
- }
754
+ case ItemType.DateRange:
755
+ case ItemType.DateTimeRange: {
756
+ const from = params[getRangeName(item.case, item.name, 'from')];
757
+ const to = params[getRangeName(item.case, item.name, 'to')];
758
+ return { from: from, to: to };
910
759
  }
911
- super._setModel(value);
912
- }
913
- _parseConfig(item) {
914
- this.maxYear = item.maxYear;
915
- this.mode = item.mode || ItemDateMode.Calendar;
760
+ case ItemType.Week: {
761
+ const from = params[getRangeName('camel', item.name, 'from')];
762
+ const to = params[getRangeName('camel', item.name, 'to')];
763
+ const period = params[`${item.name}Period`];
764
+ return { from, to, period };
765
+ }
766
+ case ItemType.Select: {
767
+ if (item.multiple && !!param) {
768
+ const values = param.split(',');
769
+ if (item.isolate) {
770
+ const isolatedValue = Array.isArray(item.isolate.value)
771
+ ? item.isolate.value
772
+ : [item.isolate.value];
773
+ item.isolate.enabled = arraysHaveSameElements(isolatedValue, values);
774
+ return item.isolate.enabled
775
+ ? isolatedValue
776
+ : values;
777
+ }
778
+ return values;
779
+ }
780
+ else {
781
+ return param;
782
+ }
783
+ }
784
+ case ItemType.Checkbox: {
785
+ if (param === 'true') {
786
+ return true === item.checked;
787
+ }
788
+ else {
789
+ return param === item.checked;
790
+ }
791
+ }
792
+ case ItemType.AutoComplete: {
793
+ const filterParts = filterFromQueryParam(param);
794
+ return {
795
+ name: filterParts[1],
796
+ value: tryConvertToNumber(filterParts[0])
797
+ };
798
+ }
799
+ case ItemType.AutoCompleteChips:
800
+ case ItemType.Chips: {
801
+ const filterParts = param.split(',');
802
+ return filterParts.reduce((arry, value) => {
803
+ const chipParts = filterFromQueryParam(value);
804
+ arry.push({
805
+ name: chipParts[1],
806
+ value: tryConvertToNumber(chipParts[0]),
807
+ });
808
+ return arry;
809
+ }, []);
810
+ }
811
+ default: {
812
+ return param;
813
+ }
814
+ }
815
+ }
816
+ function arraysHaveSameElements(arr1, arr2) {
817
+ arr1 = [...arr1].sort();
818
+ arr2 = [...arr2].sort();
819
+ return arr1.some((item) => {
820
+ return arr2.includes(item);
821
+ });
822
+ }
823
+
824
+ function parseDate(value) {
825
+ if (value && (!isDate(value) || !isValid(value))) {
826
+ return parseISO(value);
827
+ }
828
+ return value;
829
+ }
830
+
831
+ class WeekItem extends BaseItem {
832
+ static create(config) {
833
+ return new WeekItem(config, null);
834
+ }
835
+ get value() {
836
+ let value = clone(this.model);
837
+ if (!isObject(this.model) ||
838
+ (isEmpty(this.model.from, { zero: true }) && isEmpty(this.model.to, { zero: true }))) {
839
+ value = undefined;
840
+ }
841
+ if (isEmpty(value, { zero: true })) {
842
+ return undefined;
843
+ }
844
+ let from = value.from;
845
+ let to = value.to;
846
+ const period = value.period;
847
+ value = {};
848
+ if (from) {
849
+ if (isString(from)) {
850
+ from = parseISO(from);
851
+ }
852
+ if (isValid(from) && isDate(from)) {
853
+ value.from = from;
854
+ }
855
+ }
856
+ if (to) {
857
+ if (isString(to)) {
858
+ to = parseISO(to);
859
+ }
860
+ if (isValid(to) && isDate(to)) {
861
+ value.to = to;
862
+ }
863
+ }
864
+ if (period) {
865
+ if (isString(period)) {
866
+ value.period = parseInt(period, 10);
867
+ }
868
+ else {
869
+ value.period = period;
870
+ }
871
+ }
872
+ return value;
873
+ }
874
+ get queryObject() {
875
+ const value = this.value;
876
+ const name = this.name;
877
+ const paramFromName = getRangeName('camel', name, 'from');
878
+ const paramToName = getRangeName('camel', name, 'to');
879
+ const paramPeriodName = `${name}Period`;
880
+ return {
881
+ [paramFromName]: (value === null || value === void 0 ? void 0 : value.from) || undefined,
882
+ [paramToName]: (value === null || value === void 0 ? void 0 : value.to) || undefined,
883
+ [paramPeriodName]: (value === null || value === void 0 ? void 0 : value.period) || undefined,
884
+ };
885
+ }
886
+ get persistanceObject() {
887
+ const query = this.queryObject;
888
+ const name = this.name;
889
+ const paramFromName = getRangeName('camel', name, 'from');
890
+ const paramFromValue = query[paramFromName] && simpleFormat(query[paramFromName]) || query[paramFromName];
891
+ const paramToName = getRangeName('camel', name, 'to');
892
+ const paramToValue = query[paramToName] && simpleFormat(query[paramToName]) || query[paramToName];
893
+ const paramPeriodName = `${name}Period`;
894
+ return {
895
+ [paramFromName]: paramFromValue,
896
+ [paramToName]: paramToValue,
897
+ [paramPeriodName]: query[paramPeriodName],
898
+ };
899
+ }
900
+ getChipsContent(type = null) {
901
+ return formatPeriodObject(this.value);
902
+ }
903
+ _validateModel() { }
904
+ _setModel(value) {
905
+ if (value) {
906
+ value.from = parseDate(value.from);
907
+ value.to = parseDate(value.to);
908
+ value.period = parseInt(value.period, 10) || undefined;
909
+ }
910
+ super._setModel(value);
911
+ }
912
+ _parseConfig(item) {
913
+ super._parseConfig(item);
914
+ this.seedDate = item.seedDate;
915
+ }
916
+ _init() { }
917
+ _clearValue(defaultValue = undefined) {
918
+ this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : undefined;
919
+ }
920
+ }
921
+
922
+ /**
923
+ * We need this function because when we store persisted/query/remote filter values
924
+ * it stores with different format, ex.: Range will be stored as RangeFrom && RangeTo
925
+ * and in this case we don't know how to restroe those values.
926
+ *
927
+ * This function do convertation for those kinds of stored values
928
+ *
929
+ * @param params
930
+ * @param items
931
+ * @param paramsCase
932
+ */
933
+ function restoreItems(params, items, paramsCase) {
934
+ const result = {};
935
+ Object.keys(params)
936
+ .forEach((name) => {
937
+ const item = findItemWidthName(items, name);
938
+ if (item) {
939
+ result[item.name] = parseItemValueFromStored(item, params, paramsCase);
940
+ }
941
+ });
942
+ return result;
943
+ }
944
+ function findItemWidthName(items, name) {
945
+ return items
946
+ .find((filterItem) => {
947
+ if (filterItem instanceof RangeItem) {
948
+ return name === getRangeName(filterItem.case, filterItem.name, 'min') ||
949
+ name === getRangeName(filterItem.case, filterItem.name, 'max') ||
950
+ name === filterItem.name;
951
+ }
952
+ else if (filterItem instanceof DateRangeItem || filterItem instanceof DateTimeRangeItem) {
953
+ return name === getRangeName(filterItem.case, filterItem.name, 'from') ||
954
+ name === getRangeName(filterItem.case, filterItem.name, 'to');
955
+ }
956
+ else if (filterItem instanceof WeekItem) {
957
+ return name === getRangeName('camel', filterItem.name, 'from')
958
+ || name === getRangeName('camel', filterItem.name, 'to')
959
+ || name === `${filterItem.name}Period`;
960
+ }
961
+ return filterItem.name === name;
962
+ });
963
+ }
964
+
965
+ function findValue(values, value, children) {
966
+ for (let i = 0; i < values.length; i++) {
967
+ const val = values[i];
968
+ if (val[children]) {
969
+ return findValue(val[children], value, children);
970
+ }
971
+ if (val.value === value) {
972
+ return val;
973
+ }
974
+ }
975
+ return undefined;
976
+ }
977
+
978
+ class SimpleSelectItem extends BaseSelectItem {
979
+ constructor(itemConfig, _persistedValues) {
980
+ super(itemConfig, _persistedValues);
981
+ }
982
+ get value() {
983
+ let value = this.model;
984
+ if (value == '__all' || value === undefined) {
985
+ value = undefined;
986
+ }
987
+ return value;
988
+ }
989
+ getChipsContent(type = null) {
990
+ if (this.children) {
991
+ const itemValue = findValue(this.values, this.model, this.children);
992
+ return itemValue && itemValue.name;
993
+ }
994
+ else {
995
+ const itemValue = this.values.find((val) => val.value === this.model);
996
+ if (itemValue) {
997
+ return itemValue.name;
998
+ }
999
+ else if (this.isolate) {
1000
+ return this.isolate.label;
1001
+ }
1002
+ }
1003
+ }
1004
+ get isChipVisible() {
1005
+ return this.model !== '__all' && this.model !== undefined;
1006
+ }
1007
+ _init() {
1008
+ super._init();
1009
+ if (this.model === undefined && this.defaultValue === undefined) {
1010
+ this._model = '__all';
1011
+ }
1012
+ }
1013
+ get isolateOptionNotSelected() {
1014
+ const modelValue = this.model;
1015
+ const isolate = this.isolate;
1016
+ return isolate && !isolate.enabled && (modelValue === null || modelValue === void 0 ? void 0 : modelValue.length) === 0;
1017
+ }
1018
+ _setModel(value) {
1019
+ if (value) {
1020
+ if (!isNaN(value)) {
1021
+ value = +value;
1022
+ }
1023
+ }
1024
+ super._setModel(value);
1025
+ }
1026
+ _validateModel() {
1027
+ const item = this.values.find(value => {
1028
+ return value.value == this.model;
1029
+ });
1030
+ const value = item ? item.value : '__all';
1031
+ if (this._model !== value) {
1032
+ this.model = value;
1033
+ }
1034
+ }
1035
+ _clearValue(defaultValue = undefined) {
1036
+ super._clearValue(defaultValue);
1037
+ const value = Array.isArray(this.values) && this.values.some((val) => val.value === '__all')
1038
+ ? '__all'
1039
+ : undefined;
1040
+ this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
1041
+ }
1042
+ }
1043
+
1044
+ class SelectItem {
1045
+ static create(config) {
1046
+ if (config.multiple) {
1047
+ return new MultipleSelectItem(config, null);
1048
+ }
1049
+ else {
1050
+ return new SimpleSelectItem(config, null);
1051
+ }
1052
+ }
1053
+ }
1054
+
1055
+ class ChipsItem extends BaseItem {
1056
+ static create(config) {
1057
+ return new ChipsItem(config, null);
1058
+ }
1059
+ get isTypeChips() {
1060
+ return true;
1061
+ }
1062
+ get value() {
1063
+ const value = clone(this.model);
1064
+ if (Array.isArray(value) && value.length === 0) {
1065
+ return undefined;
1066
+ }
1067
+ return value;
1068
+ }
1069
+ get isChipVisible() {
1070
+ return !!this.value;
1071
+ }
1072
+ get queryObject() {
1073
+ const value = this.value;
1074
+ const name = this.name;
1075
+ return {
1076
+ [name]: value
1077
+ };
1078
+ }
1079
+ get persistanceObject() {
1080
+ const value = this.value;
1081
+ const name = this.name;
1082
+ const params = {};
1083
+ if (Array.isArray(value)) {
1084
+ params[name] = value.join(',');
1085
+ }
1086
+ else {
1087
+ params[name] = undefined;
1088
+ }
1089
+ return params;
1090
+ }
1091
+ getChipsContent() {
1092
+ return this.model
1093
+ .reduce((acc, i) => {
1094
+ acc.push(i.name);
1095
+ return acc;
1096
+ }, [])
1097
+ .join(', ');
1098
+ }
1099
+ _validateModel() { }
1100
+ _setModel(value) {
1101
+ if (Array.isArray(value)) {
1102
+ value = value.map((val) => {
1103
+ if (isNaN(val)) {
1104
+ return val;
1105
+ }
1106
+ else {
1107
+ return +val;
1108
+ }
1109
+ });
1110
+ }
1111
+ this._model = value;
1112
+ }
1113
+ _parseConfig(item) {
1114
+ this.multiple = item.multiple;
1115
+ super._parseConfig(item);
1116
+ }
1117
+ _init() {
1118
+ if (!Array.isArray(this.values)) {
1119
+ this.values = [];
1120
+ }
1121
+ if (this.model && Array.isArray(this.model) && this.values.length) {
1122
+ if (Number.isInteger(this.model[0])) {
1123
+ this._model = this.model.map((id) => {
1124
+ return this.values.find((value) => value.value === id);
1125
+ });
1126
+ }
1127
+ }
1128
+ if (this.model === undefined) {
1129
+ this._model = [];
1130
+ }
1131
+ }
1132
+ _clearValue(defaultValue = undefined) {
1133
+ this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : [];
1134
+ }
1135
+ }
1136
+
1137
+ var ItemDateMode;
1138
+ (function (ItemDateMode) {
1139
+ ItemDateMode["Calendar"] = "calendar";
1140
+ ItemDateMode["ScrollMonthYear"] = "monthyear";
1141
+ ItemDateMode["ScrollMonthDayYear"] = "monthdayyear";
1142
+ })(ItemDateMode || (ItemDateMode = {}));
1143
+
1144
+ class BaseDateItem extends BaseItem {
1145
+ get value() {
1146
+ const value = clone(this.model);
1147
+ if (!value || !isValid(value) || !isDate(value)) {
1148
+ return undefined;
1149
+ }
1150
+ return value;
1151
+ }
1152
+ get queryObject() {
1153
+ const value = this.value;
1154
+ const name = this.name;
1155
+ const params = {};
1156
+ params[name] = value;
1157
+ return params;
1158
+ }
1159
+ get persistanceObject() {
1160
+ const value = this.queryObject[this.name];
1161
+ return {
1162
+ [this.name]: value ? simpleFormat(value) : undefined,
1163
+ };
1164
+ }
1165
+ _validateModel() {
1166
+ }
1167
+ _setModel(value) {
1168
+ if (value) {
1169
+ if (!isDate(value) || !isValid(value)) {
1170
+ value = parseISO(value);
1171
+ }
1172
+ }
1173
+ super._setModel(value);
1174
+ }
1175
+ _parseConfig(item) {
1176
+ this.maxYear = item.maxYear;
1177
+ this.mode = item.mode || ItemDateMode.Calendar;
916
1178
  super._parseConfig(item);
917
1179
  }
918
1180
  _init() {
@@ -1051,174 +1313,76 @@ class AutocompleteChipsItem extends BaseAutocompleteItem {
1051
1313
 
1052
1314
  class CheckboxItem extends BaseItem {
1053
1315
  static create(config) {
1054
- return new CheckboxItem(config, null);
1055
- }
1056
- get isTypeCheckbox() {
1057
- return true;
1058
- }
1059
- get isChipVisible() {
1060
- return this.value === this.checked;
1061
- }
1062
- get value() {
1063
- const value = this.model ? this.checked : this.unchecked;
1064
- if (!value) {
1065
- return undefined;
1066
- }
1067
- return value;
1068
- }
1069
- get queryObject() {
1070
- const value = this.value;
1071
- const name = this.name;
1072
- const params = {};
1073
- params[name] = this.model ? value : undefined;
1074
- return params;
1075
- }
1076
- getChipsContent(type = null) {
1077
- return this.label;
1078
- }
1079
- _validateModel() { }
1080
- _parseConfig(item) {
1081
- this.checked = item.checked;
1082
- this.unchecked = item.unchecked;
1083
- this.checked = item.checked ? toString(item.checked) : true;
1084
- this.unchecked = item.unchecked ? toString(item.unchecked) : false;
1085
- this.defaultValue = item.default === undefined ? this.unchecked : toString(this.defaultValue);
1086
- super._parseConfig(item);
1087
- }
1088
- _init() {
1089
- if (this.model === undefined) {
1090
- this._model = this.checked == this.defaultValue;
1091
- }
1092
- }
1093
- _clearValue(defaultValue = undefined) {
1094
- this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : false;
1095
- }
1096
- }
1097
-
1098
- class TextItem extends BaseItem {
1099
- static create(config) {
1100
- return new TextItem(config, null);
1101
- }
1102
- get value() {
1103
- return !!this.model ? this.model : undefined;
1104
- }
1105
- get queryObject() {
1106
- const value = this.value;
1107
- const name = this.name;
1108
- const params = {};
1109
- params[name] = value;
1110
- return params;
1111
- }
1112
- getChipsContent() {
1113
- return this.model;
1114
- }
1115
- _validateModel() { }
1116
- _parseConfig(item) {
1117
- this.prefix = item.prefix;
1118
- this.suffix = item.suffix;
1119
- super._parseConfig(item);
1120
- }
1121
- _init() { }
1122
- _clearValue(defaultValue = undefined) {
1123
- this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : '';
1124
- }
1125
- }
1126
-
1127
- function parseDate(value) {
1128
- if (value && (!isDate(value) || !isValid(value))) {
1129
- return parseISO(value);
1130
- }
1131
- return value;
1132
- }
1133
-
1134
- class WeekItem extends BaseItem {
1135
- static create(config) {
1136
- return new WeekItem(config, null);
1137
- }
1138
- get value() {
1139
- let value = clone(this.model);
1140
- if (!isObject(this.model) ||
1141
- (isEmpty(this.model.from, { zero: true }) && isEmpty(this.model.to, { zero: true }))) {
1142
- value = undefined;
1143
- }
1144
- if (isEmpty(value, { zero: true })) {
1145
- return undefined;
1146
- }
1147
- let from = value.from;
1148
- let to = value.to;
1149
- const period = value.period;
1150
- value = {};
1151
- if (from) {
1152
- if (isString(from)) {
1153
- from = parseISO(from);
1154
- }
1155
- if (isValid(from) && isDate(from)) {
1156
- value.from = from;
1157
- }
1158
- }
1159
- if (to) {
1160
- if (isString(to)) {
1161
- to = parseISO(to);
1162
- }
1163
- if (isValid(to) && isDate(to)) {
1164
- value.to = to;
1165
- }
1166
- }
1167
- if (period) {
1168
- if (isString(period)) {
1169
- value.period = parseInt(period, 10);
1170
- }
1171
- else {
1172
- value.period = period;
1173
- }
1316
+ return new CheckboxItem(config, null);
1317
+ }
1318
+ get isTypeCheckbox() {
1319
+ return true;
1320
+ }
1321
+ get isChipVisible() {
1322
+ return this.value === this.checked;
1323
+ }
1324
+ get value() {
1325
+ const value = this.model ? this.checked : this.unchecked;
1326
+ if (!value) {
1327
+ return undefined;
1174
1328
  }
1175
1329
  return value;
1176
1330
  }
1177
1331
  get queryObject() {
1178
1332
  const value = this.value;
1179
1333
  const name = this.name;
1180
- const paramFromName = getRangeName('camel', name, 'from');
1181
- const paramToName = getRangeName('camel', name, 'to');
1182
- const paramPeriodName = `${name}Period`;
1183
- return {
1184
- [paramFromName]: (value === null || value === void 0 ? void 0 : value.from) || undefined,
1185
- [paramToName]: (value === null || value === void 0 ? void 0 : value.to) || undefined,
1186
- [paramPeriodName]: (value === null || value === void 0 ? void 0 : value.period) || undefined,
1187
- };
1188
- }
1189
- get persistanceObject() {
1190
- const query = this.queryObject;
1191
- const name = this.name;
1192
- const paramFromName = getRangeName('camel', name, 'from');
1193
- const paramFromValue = query[paramFromName] && simpleFormat(query[paramFromName]) || query[paramFromName];
1194
- const paramToName = getRangeName('camel', name, 'to');
1195
- const paramToValue = query[paramToName] && simpleFormat(query[paramToName]) || query[paramToName];
1196
- const paramPeriodName = `${name}Period`;
1197
- return {
1198
- [paramFromName]: paramFromValue,
1199
- [paramToName]: paramToValue,
1200
- [paramPeriodName]: query[paramPeriodName],
1201
- };
1334
+ const params = {};
1335
+ params[name] = this.model ? value : undefined;
1336
+ return params;
1202
1337
  }
1203
1338
  getChipsContent(type = null) {
1204
- return formatPeriodObject(this.value);
1339
+ return this.label;
1205
1340
  }
1206
1341
  _validateModel() { }
1207
- _setModel(value) {
1208
- if (value) {
1209
- value.from = parseDate(value.from);
1210
- value.to = parseDate(value.to);
1211
- value.period = parseInt(value.period, 10) || undefined;
1342
+ _parseConfig(item) {
1343
+ this.checked = item.checked;
1344
+ this.unchecked = item.unchecked;
1345
+ this.checked = item.checked ? toString(item.checked) : true;
1346
+ this.unchecked = item.unchecked ? toString(item.unchecked) : false;
1347
+ this.defaultValue = item.default === undefined ? this.unchecked : toString(this.defaultValue);
1348
+ super._parseConfig(item);
1349
+ }
1350
+ _init() {
1351
+ if (this.model === undefined) {
1352
+ this._model = this.checked == this.defaultValue;
1212
1353
  }
1213
- super._setModel(value);
1214
1354
  }
1355
+ _clearValue(defaultValue = undefined) {
1356
+ this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : false;
1357
+ }
1358
+ }
1359
+
1360
+ class TextItem extends BaseItem {
1361
+ static create(config) {
1362
+ return new TextItem(config, null);
1363
+ }
1364
+ get value() {
1365
+ return !!this.model ? this.model : undefined;
1366
+ }
1367
+ get queryObject() {
1368
+ const value = this.value;
1369
+ const name = this.name;
1370
+ const params = {};
1371
+ params[name] = value;
1372
+ return params;
1373
+ }
1374
+ getChipsContent() {
1375
+ return this.model;
1376
+ }
1377
+ _validateModel() { }
1215
1378
  _parseConfig(item) {
1379
+ this.prefix = item.prefix;
1380
+ this.suffix = item.suffix;
1216
1381
  super._parseConfig(item);
1217
- this.seedDate = item.seedDate;
1218
1382
  }
1219
1383
  _init() { }
1220
1384
  _clearValue(defaultValue = undefined) {
1221
- this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : undefined;
1385
+ this.model = defaultValue !== null && defaultValue !== void 0 ? defaultValue : '';
1222
1386
  }
1223
1387
  }
1224
1388
 
@@ -1541,7 +1705,7 @@ class FsFilterItemsStore {
1541
1705
  }
1542
1706
  return params;
1543
1707
  }
1544
- initItemValues(p) {
1708
+ init(p) {
1545
1709
  this.items
1546
1710
  .forEach((item) => {
1547
1711
  item.initValues(p[item.name]);
@@ -1549,10 +1713,6 @@ class FsFilterItemsStore {
1549
1713
  this._initSortingItems(p);
1550
1714
  this.loadAsyncDefaults();
1551
1715
  this._subscribeToItemsChanges();
1552
- this.items
1553
- .forEach((item) => {
1554
- item.init(item);
1555
- });
1556
1716
  }
1557
1717
  updateItemsWithValues(values) {
1558
1718
  this.items
@@ -1701,143 +1861,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1701
1861
  type: Injectable
1702
1862
  }], ctorParameters: function () { return []; } });
1703
1863
 
1704
- const QUERY_PARAM_DELIMITER = ':';
1705
-
1706
- function filterToQueryParam(value, name) {
1707
- return `${encodeURIComponent(value)}${QUERY_PARAM_DELIMITER}${encodeURIComponent(name)}`;
1708
- }
1709
- function filterFromQueryParam(param) {
1710
- const parts = param.split(QUERY_PARAM_DELIMITER);
1711
- return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])];
1712
- }
1713
-
1714
- function tryConvertToNumber(val) {
1715
- return isNaN(val)
1716
- ? val
1717
- : +val;
1718
- }
1719
-
1720
- function parseItemValueFromStored(item, params, paramCase) {
1721
- const param = params[item.name];
1722
- switch (item.type) {
1723
- case ItemType.Range: {
1724
- const min = params[getRangeName(paramCase, item.name, 'min')];
1725
- const max = params[getRangeName(paramCase, item.name, 'max')];
1726
- return { min: min, max: max };
1727
- }
1728
- case ItemType.DateRange:
1729
- case ItemType.DateTimeRange: {
1730
- const from = params[getRangeName(item.case, item.name, 'from')];
1731
- const to = params[getRangeName(item.case, item.name, 'to')];
1732
- return { from: from, to: to };
1733
- }
1734
- case ItemType.Week: {
1735
- const from = params[getRangeName('camel', item.name, 'from')];
1736
- const to = params[getRangeName('camel', item.name, 'to')];
1737
- const period = params[`${item.name}Period`];
1738
- return { from, to, period };
1739
- }
1740
- case ItemType.Select: {
1741
- if (item.multiple && !!param) {
1742
- const values = param.split(',');
1743
- if (item.isolate) {
1744
- const isolatedValue = Array.isArray(item.isolate.value)
1745
- ? item.isolate.value
1746
- : [item.isolate.value];
1747
- item.isolate.enabled = arraysHaveSameElements(isolatedValue, values);
1748
- return item.isolate.enabled
1749
- ? isolatedValue
1750
- : values;
1751
- }
1752
- return values;
1753
- }
1754
- else {
1755
- return param;
1756
- }
1757
- }
1758
- case ItemType.Checkbox: {
1759
- if (param === 'true') {
1760
- return true === item.checked;
1761
- }
1762
- else {
1763
- return param === item.checked;
1764
- }
1765
- }
1766
- case ItemType.AutoComplete: {
1767
- const filterParts = filterFromQueryParam(param);
1768
- return {
1769
- name: filterParts[1],
1770
- value: tryConvertToNumber(filterParts[0])
1771
- };
1772
- }
1773
- case ItemType.AutoCompleteChips:
1774
- case ItemType.Chips: {
1775
- const filterParts = param.split(',');
1776
- return filterParts.reduce((arry, value) => {
1777
- const chipParts = filterFromQueryParam(value);
1778
- arry.push({
1779
- name: chipParts[1],
1780
- value: tryConvertToNumber(chipParts[0]),
1781
- });
1782
- return arry;
1783
- }, []);
1784
- }
1785
- default: {
1786
- return param;
1787
- }
1788
- }
1789
- }
1790
- function arraysHaveSameElements(arr1, arr2) {
1791
- arr1 = [...arr1].sort();
1792
- arr2 = [...arr2].sort();
1793
- return arr1.some((item) => {
1794
- return arr2.includes(item);
1795
- });
1796
- }
1797
-
1798
- /**
1799
- * We need this function because when we store persisted/query/remote filter values
1800
- * it stores with different format, ex.: Range will be stored as RangeFrom && RangeTo
1801
- * and in this case we don't know how to restroe those values.
1802
- *
1803
- * This function do convertation for those kinds of stored values
1804
- *
1805
- * @param params
1806
- * @param items
1807
- * @param paramsCase
1808
- */
1809
- function restoreItems(params, items, paramsCase) {
1810
- const result = {};
1811
- Object.keys(params)
1812
- .forEach((name) => {
1813
- const item = findItemWidthName(items, name);
1814
- if (item) {
1815
- result[item.name] = parseItemValueFromStored(item, params, paramsCase);
1816
- }
1817
- });
1818
- return result;
1819
- }
1820
- function findItemWidthName(items, name) {
1821
- return items
1822
- .find((filterItem) => {
1823
- if (filterItem instanceof RangeItem) {
1824
- return name === getRangeName(filterItem.case, filterItem.name, 'min') ||
1825
- name === getRangeName(filterItem.case, filterItem.name, 'max') ||
1826
- name === filterItem.name;
1827
- }
1828
- else if (filterItem instanceof DateRangeItem || filterItem instanceof DateTimeRangeItem) {
1829
- return name === getRangeName(filterItem.case, filterItem.name, 'from') ||
1830
- name === getRangeName(filterItem.case, filterItem.name, 'to');
1831
- }
1832
- else if (filterItem instanceof WeekItem) {
1833
- return name === getRangeName('camel', filterItem.name, 'from')
1834
- || name === getRangeName('camel', filterItem.name, 'to')
1835
- || name === `${filterItem.name}Period`;
1836
- }
1837
- return filterItem.name === name;
1838
- });
1839
- }
1840
-
1841
1864
  const FILTER_STORE_KEY = 'fs-filter-persist';
1842
1865
  class PersistanceParamsController extends FsPersistanceStore {
1843
1866
  constructor(_store, _route, _location, _itemsStore, _dialogRef, _drawerRef) {
@@ -1978,33 +2001,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1978
2001
  args: [MAT_DIALOG_DATA]
1979
2002
  }] }, { type: i1$2.MatDialogRef }]; } });
1980
2003
 
1981
- function buildQueryParams(flattenedParams, items) {
1982
- items.forEach(filterItem => {
1983
- if (filterItem instanceof MultipleSelectItem && filterItem.isolate) {
1984
- if (filterItem.multiple && filterItem.value) {
1985
- const isolated = list(filterItem.values, 'value').sort();
1986
- const value = filterItem.value.sort();
1987
- if (arraysAreEquals(value, isolated)) {
1988
- flattenedParams[filterItem.name] = null;
1989
- }
1990
- }
1991
- }
1992
- if (filterItem.isTypeAutocomplete) {
1993
- if (isObject(filterItem.model)) {
1994
- flattenedParams[filterItem.name] = filterToQueryParam(filterItem.model.value, filterItem.model.name);
1995
- }
1996
- }
1997
- else if (filterItem.isTypeAutocompleteChips || filterItem.isTypeChips) {
1998
- if (Array.isArray(filterItem.model) && filterItem.model.length) {
1999
- flattenedParams[filterItem.name] = filterItem.model.map((item) => {
2000
- return filterToQueryParam(item.value, item.name);
2001
- }).join(',');
2002
- }
2003
- }
2004
- });
2005
- return flattenedParams;
2006
- }
2007
-
2008
2004
  class SavedFiltersController {
2009
2005
  constructor(_itemsStore, _dialog) {
2010
2006
  this._itemsStore = _itemsStore;
@@ -2219,6 +2215,7 @@ class ExternalParamsController {
2219
2215
  this._savePersistedParams();
2220
2216
  }
2221
2217
  initItems() {
2218
+ this._itemsStore.ready$;
2222
2219
  this._pending$.next(true);
2223
2220
  if (this._savedFilters.enabled) {
2224
2221
  this._savedFilters
@@ -2238,7 +2235,7 @@ class ExternalParamsController {
2238
2235
  this._listenItemsChange();
2239
2236
  }
2240
2237
  _initItemsValues() {
2241
- this._itemsStore.initItemValues(this.params);
2238
+ this._itemsStore.init(this.params);
2242
2239
  this._saveQueryParams();
2243
2240
  this._savePersistedParams();
2244
2241
  }
@@ -3785,13 +3782,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
3785
3782
  }] } });
3786
3783
 
3787
3784
  class FilterComponent {
3788
- constructor(_filterOverlay, _zone, _externalParams, _filterItems, _actions, _defaultConfig) {
3785
+ constructor(_defaultConfig, _filterOverlay, _zone, _externalParams, _filterItems, _actions) {
3786
+ this._defaultConfig = _defaultConfig;
3789
3787
  this._filterOverlay = _filterOverlay;
3790
3788
  this._zone = _zone;
3791
3789
  this._externalParams = _externalParams;
3792
3790
  this._filterItems = _filterItems;
3793
3791
  this._actions = _actions;
3794
- this._defaultConfig = _defaultConfig;
3795
3792
  this.showSortBy = true;
3796
3793
  this.showFilterInput = true;
3797
3794
  this.closed = new EventEmitter();
@@ -4079,6 +4076,13 @@ class FilterComponent {
4079
4076
  this.config.init(data, this._sort);
4080
4077
  }
4081
4078
  this._updateChipsVisibility();
4079
+ // Waiting for external ViewChilds
4080
+ setTimeout(() => {
4081
+ this.items
4082
+ .forEach((item) => {
4083
+ item.init(item);
4084
+ });
4085
+ });
4082
4086
  }
4083
4087
  clear(event = null) {
4084
4088
  if (event) {
@@ -4307,7 +4311,7 @@ class FilterComponent {
4307
4311
  this._hasFilterChips$.next(hasFilterChips);
4308
4312
  }
4309
4313
  }
4310
- FilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterComponent, deps: [{ token: FsFilterOverlayService }, { token: i0.NgZone }, { token: ExternalParamsController }, { token: FsFilterItemsStore }, { token: ActionsController }, { token: FS_FILTER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
4314
+ FilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: FilterComponent, deps: [{ token: FS_FILTER_CONFIG, optional: true }, { token: FsFilterOverlayService }, { token: i0.NgZone }, { token: ExternalParamsController }, { token: FsFilterItemsStore }, { token: ActionsController }], target: i0.ɵɵFactoryTarget.Component });
4311
4315
  FilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: FilterComponent, selector: "fs-filter", inputs: { setConfig: ["config", "setConfig"], setFilter: ["filter", "setFilter"], showSortBy: "showSortBy", showFilterInput: "showFilterInput" }, outputs: { closed: "closed", opened: "opened", ready: "ready" }, host: { properties: { "class.filters-open": "this.showFilterMenu", "class.window-desktop": "this.windowDesktop", "class.fs-filter": "this.fsFilterClass", "class.has-keyword": "this.hasKeyword" } }, providers: [
4312
4316
  FsFilterOverlayService,
4313
4317
  ExternalParamsController,
@@ -4337,12 +4341,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
4337
4341
  ],
4338
4342
  changeDetection: ChangeDetectionStrategy.OnPush,
4339
4343
  }]
4340
- }], ctorParameters: function () { return [{ type: FsFilterOverlayService }, { type: i0.NgZone }, { type: ExternalParamsController }, { type: FsFilterItemsStore }, { type: ActionsController }, { type: FsFilterConfig, decorators: [{
4344
+ }], ctorParameters: function () { return [{ type: FsFilterConfig, decorators: [{
4341
4345
  type: Optional
4342
4346
  }, {
4343
4347
  type: Inject,
4344
4348
  args: [FS_FILTER_CONFIG]
4345
- }] }]; }, propDecorators: { setConfig: [{
4349
+ }] }, { type: FsFilterOverlayService }, { type: i0.NgZone }, { type: ExternalParamsController }, { type: FsFilterItemsStore }, { type: ActionsController }]; }, propDecorators: { setConfig: [{
4346
4350
  type: Input,
4347
4351
  args: ['config']
4348
4352
  }], setFilter: [{