@visactor/vtable-plugins 1.22.7-alpha.1 → 1.22.7-alpha.3

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.
Files changed (55) hide show
  1. package/cjs/auto-fill/date-tools.js +2 -1
  2. package/cjs/contextmenu/index.js +1 -2
  3. package/cjs/filter/condition-filter.d.ts +2 -2
  4. package/cjs/filter/condition-filter.js +10 -12
  5. package/cjs/filter/condition-filter.js.map +1 -1
  6. package/cjs/filter/{constants.js → constant.js} +1 -1
  7. package/cjs/filter/constant.js.map +1 -0
  8. package/cjs/filter/filter-state-manager.d.ts +0 -14
  9. package/cjs/filter/filter-state-manager.js +1 -35
  10. package/cjs/filter/filter-state-manager.js.map +1 -1
  11. package/cjs/filter/filter-toolbar.d.ts +1 -2
  12. package/cjs/filter/filter-toolbar.js +16 -23
  13. package/cjs/filter/filter-toolbar.js.map +1 -1
  14. package/cjs/filter/filter.js +13 -13
  15. package/cjs/filter/filter.js.map +1 -1
  16. package/cjs/filter/styles.d.ts +124 -2
  17. package/cjs/filter/styles.js.map +1 -1
  18. package/cjs/filter/types.d.ts +6 -5
  19. package/cjs/filter/types.js.map +1 -1
  20. package/cjs/filter/value-filter.d.ts +16 -14
  21. package/cjs/filter/value-filter.js +146 -225
  22. package/cjs/filter/value-filter.js.map +1 -1
  23. package/cjs/gantt-export-image.js.map +1 -1
  24. package/cjs/master-detail-plugin/config.js.map +1 -1
  25. package/dist/vtable-plugins.js +292 -443
  26. package/dist/vtable-plugins.min.js +1 -1
  27. package/es/auto-fill/date-tools.js +2 -1
  28. package/es/contextmenu/index.js +1 -2
  29. package/es/filter/condition-filter.d.ts +2 -2
  30. package/es/filter/condition-filter.js +10 -12
  31. package/es/filter/condition-filter.js.map +1 -1
  32. package/es/filter/{constants.js → constant.js} +1 -1
  33. package/es/filter/constant.js.map +1 -0
  34. package/es/filter/filter-state-manager.d.ts +0 -14
  35. package/es/filter/filter-state-manager.js +1 -35
  36. package/es/filter/filter-state-manager.js.map +1 -1
  37. package/es/filter/filter-toolbar.d.ts +1 -2
  38. package/es/filter/filter-toolbar.js +16 -23
  39. package/es/filter/filter-toolbar.js.map +1 -1
  40. package/es/filter/filter.js +15 -14
  41. package/es/filter/filter.js.map +1 -1
  42. package/es/filter/styles.d.ts +124 -2
  43. package/es/filter/styles.js.map +1 -1
  44. package/es/filter/types.d.ts +6 -5
  45. package/es/filter/types.js.map +1 -1
  46. package/es/filter/value-filter.d.ts +16 -14
  47. package/es/filter/value-filter.js +146 -225
  48. package/es/filter/value-filter.js.map +1 -1
  49. package/es/gantt-export-image.js.map +1 -1
  50. package/es/master-detail-plugin/config.js.map +1 -1
  51. package/package.json +6 -6
  52. package/cjs/filter/constants.js.map +0 -1
  53. package/es/filter/constants.js.map +0 -1
  54. /package/cjs/filter/{constants.d.ts → constant.d.ts} +0 -0
  55. /package/es/filter/{constants.d.ts → constant.d.ts} +0 -0
@@ -8,131 +8,92 @@ const vutils_1 = require("@visactor/vutils"), types_1 = require("./types"), styl
8
8
 
9
9
  class ValueFilter {
10
10
  constructor(table, filterStateManager, pluginOptions) {
11
- this.uniqueKeys = new Map, this.displayToRawValueMap = new Map, this.valueFilterOptionList = new Map,
12
- this.table = table, this.filterStateManager = filterStateManager, this.pluginOptions = pluginOptions,
13
- this.styles = pluginOptions.styles, this.filterStateManager.subscribe((state => {
14
- const filterState = state.filters.get(this.selectedField);
15
- filterState && "byValue" === filterState.type && this.updateUI(filterState);
16
- }));
17
- }
18
- updateUI(filterState) {
19
- this.syncCheckboxesWithFilterState(filterState), this.syncSelectAllWithFilterState(filterState);
11
+ this.selectedKeys = new Map, this.candidateKeys = new Map, this.formatFnCache = new Map,
12
+ this.toUnformattedCache = new Map, this.valueFilterOptionList = new Map, this.table = table,
13
+ this.filterStateManager = filterStateManager, this.pluginOptions = pluginOptions,
14
+ this.styles = pluginOptions.styles || {};
20
15
  }
21
16
  setSelectedField(fieldId) {
22
- this.selectedField = fieldId, this.collectUniqueColumnValues(fieldId);
17
+ this.selectedField = fieldId;
23
18
  }
24
- collectUniqueColumnValues(fieldId, forceCollect = !1) {
25
- var _a, _b, _c;
26
- if (this.uniqueKeys.has(fieldId) && !forceCollect) return;
27
- const displayToRawMap = new Map;
28
- let targetCol = -1;
29
- for (let col = 0; col < this.table.colCount; col++) {
30
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
31
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
32
- if (bodyInfo && bodyInfo.field === fieldId) {
33
- targetCol = col;
34
- break;
35
- }
36
- }
37
- if (-1 !== targetCol) break;
38
- }
39
- const records = this.table.internalProps.records, recordsLength = records.length;
40
- for (let i = 0; i < recordsLength; i++) {
41
- let rawValue, displayValue;
42
- if (-1 !== targetCol) {
43
- const row = this.table.columnHeaderLevelCount + i, currentRecord = records[i];
44
- if (null == currentRecord) continue;
45
- rawValue = currentRecord[fieldId];
46
- const bodyInfo = this.table.internalProps.layoutMap.getBody(targetCol, row);
47
- displayValue = bodyInfo && "fieldFormat" in bodyInfo && bodyInfo.fieldFormat && "function" == typeof bodyInfo.fieldFormat ? bodyInfo.fieldFormat({
48
- [fieldId]: rawValue
49
- }) : rawValue;
50
- } else rawValue = records[i][fieldId], displayValue = rawValue;
51
- null == rawValue || displayToRawMap.has(displayValue) || (displayToRawMap.set(displayValue, rawValue),
52
- this.displayToRawValueMap.has(fieldId) && !(null === (_a = this.displayToRawValueMap.get(fieldId)) || void 0 === _a ? void 0 : _a.has(displayValue)) && (null === (_c = null === (_b = this.filterStateManager.getFilterState(fieldId)) || void 0 === _b ? void 0 : _b.values) || void 0 === _c ? void 0 : _c.length) > 0 && this.filterStateManager.getFilterState(fieldId).values.push(rawValue));
53
- }
54
- this.displayToRawValueMap.set(fieldId, displayToRawMap);
55
- const uniqueValues = Array.from(displayToRawMap.entries()).map((([displayValue, rawValue]) => ({
56
- value: displayValue,
57
- count: 0,
58
- rawValue: rawValue
59
- })));
60
- this.uniqueKeys.set(fieldId, uniqueValues);
19
+ getFormatFnCache(fieldId) {
20
+ let formatFn = this.formatFnCache.get(fieldId);
21
+ if (null != formatFn) return formatFn;
22
+ const headerAddress = this.table.internalProps.layoutMap.getHeaderCellAddressByField(String(fieldId)), bodyInfo = this.table.internalProps.layoutMap.getBody(null == headerAddress ? void 0 : headerAddress.col, null == headerAddress ? void 0 : headerAddress.row);
23
+ return formatFn = bodyInfo && "fieldFormat" in bodyInfo && "function" == typeof bodyInfo.fieldFormat ? bodyInfo.fieldFormat : bodyInfo && "format" in bodyInfo && "function" == typeof bodyInfo.format ? bodyInfo.format : record => record[fieldId],
24
+ this.formatFnCache.set(fieldId, formatFn), formatFn;
61
25
  }
62
- updateCandidateCounts(fieldId) {
63
- const uniqueValues = this.uniqueKeys.get(fieldId);
64
- if (!uniqueValues) return;
65
- const filter = this.filterStateManager.getFilterState(fieldId), dataSource = (null == filter ? void 0 : filter.enable) ? this.table.internalProps.records : this.table.internalProps.dataSource;
66
- let targetCol = -1;
67
- for (let col = 0; col < this.table.colCount; col++) {
68
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
69
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
70
- if (bodyInfo && bodyInfo.field === fieldId) {
71
- targetCol = col;
72
- break;
26
+ collectCandidateKeysForUnfilteredColumn(fieldId) {
27
+ var _a, _b;
28
+ const syncCheckboxCheckedState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncCheckboxCheckedState) || void 0 === _b || _b, countMap = new Map;
29
+ let records = [];
30
+ records = syncCheckboxCheckedState ? this.table.internalProps.dataSource.records : this.table.internalProps.records;
31
+ const formatFn = this.getFormatFnCache(fieldId), toUnformatted = new Map;
32
+ records.forEach((record => {
33
+ if ((0, vutils_1.isValid)(record)) {
34
+ const originalValue = record[fieldId], formattedValue = formatFn(record);
35
+ if (null != formattedValue) {
36
+ countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
37
+ const unformattedSet = toUnformatted.get(formattedValue);
38
+ null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
73
39
  }
74
40
  }
75
- if (-1 !== targetCol) break;
76
- }
77
- const dataLength = dataSource.length, countMap = new Map;
78
- for (let i = 0; i < dataLength; i++) {
79
- let displayValue;
80
- if (-1 !== targetCol) {
81
- const row = this.table.columnHeaderLevelCount + i;
82
- row < this.table.rowCount && (displayValue = this.table.getCellValue(targetCol, row));
83
- } else displayValue = this.table.getFieldData(String(fieldId), -1 !== targetCol ? targetCol : 0, this.table.columnHeaderLevelCount + i);
84
- null != displayValue && countMap.set(displayValue, (countMap.get(displayValue) || 0) + 1);
85
- }
86
- uniqueValues.forEach((item => {
87
- item.count = countMap.get(item.value) || 0;
41
+ })), this.candidateKeys.set(fieldId, countMap), this.toUnformattedCache.set(fieldId, toUnformatted);
42
+ }
43
+ updateBeforeFilter() {
44
+ const currentRecords = this.table.internalProps.dataSource.records, filteredFields = this.filterStateManager.getActiveFilterFields();
45
+ currentRecords.forEach((record => {
46
+ filteredFields.forEach((candidateField => {
47
+ var _a, _b;
48
+ const formatFn = this.getFormatFnCache(candidateField);
49
+ if ((0, vutils_1.isValid)(record)) {
50
+ const originalValue = record[candidateField], formattedValue = formatFn(record);
51
+ !(this.toUnformattedCache.get(candidateField) || new Map).has(formattedValue) && (null === (_b = null === (_a = this.filterStateManager.getFilterState(candidateField)) || void 0 === _a ? void 0 : _a.values) || void 0 === _b ? void 0 : _b.length) > 0 && (this.filterStateManager.getFilterState(candidateField).values.push(originalValue),
52
+ this.selectedKeys.get(candidateField).add(originalValue));
53
+ }
54
+ }));
88
55
  }));
89
56
  }
90
- onValueSelect(fieldId, displayValue, selected) {
91
- const displayToRawMap = this.displayToRawValueMap.get(fieldId), rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue, filter = this.filterStateManager.getFilterState(fieldId);
92
- let updatedValues;
93
- filter ? (updatedValues = selected ? [ ...filter.values || [], rawValue ] : (filter.values || []).filter((v => v !== rawValue)),
94
- this.filterStateManager.dispatch({
95
- type: types_1.FilterActionType.UPDATE_FILTER,
96
- payload: {
97
- field: fieldId,
98
- values: updatedValues
99
- }
100
- })) : (updatedValues = selected ? [ rawValue ] : [], this.filterStateManager.dispatch({
101
- type: types_1.FilterActionType.ADD_FILTER,
102
- payload: {
103
- field: fieldId,
104
- type: "byValue",
105
- values: updatedValues
106
- }
57
+ updateAfterFilter() {
58
+ const currentRecords = this.table.internalProps.dataSource.records, filteredFields = this.filterStateManager.getActiveFilterFields();
59
+ currentRecords.forEach((record => {
60
+ filteredFields.forEach((candidateField => {
61
+ var _a;
62
+ if ((0, vutils_1.isValid)(record)) {
63
+ const originalValue = record[candidateField];
64
+ "byCondition" === (null === (_a = this.filterStateManager.getFilterState(candidateField)) || void 0 === _a ? void 0 : _a.type) && (this.selectedKeys.get(candidateField) || this.selectedKeys.set(candidateField, new Set),
65
+ this.selectedKeys.get(candidateField).add(originalValue));
66
+ }
67
+ }));
107
68
  }));
108
69
  }
109
- isValueVisible(displayValue, keyword) {
110
- if (!keyword) return !0;
111
- const filterKeywords = keyword.toUpperCase().split(" ").filter((s => s)), txtValue = String(displayValue).toUpperCase();
112
- return filterKeywords.some((keyword => txtValue.includes(keyword)));
70
+ collectCandidateKeysForFilteredColumn(candidateField) {
71
+ var _a, _b;
72
+ const syncCheckboxCheckedState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncCheckboxCheckedState) || void 0 === _b || _b, filteredFields = this.filterStateManager.getActiveFilterFields().filter((field => field !== candidateField)), toUnformatted = new Map, formatFn = this.getFormatFnCache(candidateField), countMap = new Map;
73
+ let records = [];
74
+ if (syncCheckboxCheckedState) {
75
+ records = this.table.internalProps.records.filter((record => filteredFields.every((field => this.selectedKeys.get(field).has(record[field])))));
76
+ } else records = this.table.internalProps.records;
77
+ records.forEach((record => {
78
+ if ((0, vutils_1.isValid)(record)) {
79
+ const originalValue = record[candidateField], formattedValue = formatFn(record);
80
+ if (countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1), null != formattedValue) {
81
+ const unformattedSet = toUnformatted.get(formattedValue);
82
+ null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
83
+ }
84
+ }
85
+ })), this.candidateKeys.set(candidateField, countMap), this.toUnformattedCache.set(candidateField, toUnformatted);
113
86
  }
114
87
  toggleSelectAll(fieldId, selected) {
115
- const currentKeyword = this.filterStateManager.getCurrentSearchKeyword(fieldId), stableCandidates = this.filterStateManager.getStableCandidateValues(fieldId), displayToRawMap = this.displayToRawValueMap.get(fieldId), visibleRawValues = stableCandidates.filter((candidate => this.isValueVisible(candidate.value, currentKeyword))).map((candidate => displayToRawMap ? displayToRawMap.get(candidate.value) : candidate.value)), filter = this.filterStateManager.getFilterState(fieldId), currentValues = new Set((null == filter ? void 0 : filter.values) || []);
116
- let updatedValues;
117
- updatedValues = selected ? Array.from(new Set([ ...currentValues, ...visibleRawValues ])) : Array.from(currentValues).filter((value => !visibleRawValues.includes(value))),
118
- filter ? this.filterStateManager.dispatch({
119
- type: types_1.FilterActionType.UPDATE_FILTER,
120
- payload: {
121
- field: fieldId,
122
- values: updatedValues
123
- }
124
- }) : this.filterStateManager.dispatch({
125
- type: types_1.FilterActionType.ADD_FILTER,
126
- payload: {
127
- field: fieldId,
128
- type: "byValue",
129
- values: updatedValues,
130
- enable: !0
131
- }
132
- });
88
+ this.valueFilterOptionList.get(fieldId).forEach((option => {
89
+ option.checkbox.checked = selected;
90
+ }));
91
+ }
92
+ syncSelectAllCheckbox(fieldId) {
93
+ const options = this.valueFilterOptionList.get(fieldId) || [], allChecked = options.every((o => o.checkbox.checked)), noneChecked = options.every((o => !o.checkbox.checked));
94
+ this.selectAllCheckbox.checked = allChecked, this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
133
95
  }
134
96
  onSearch(fieldId, value) {
135
- this.filterStateManager.updateSearchKeyword(fieldId, value);
136
97
  const items = this.valueFilterOptionList.get(fieldId), filterKeywords = value.toUpperCase().split(" ").filter((s => s));
137
98
  for (const item of items) {
138
99
  const txtValue = item.id.toUpperCase() || "", match = filterKeywords.some((keyword => txtValue.includes(keyword))), isVisible = 0 === filterKeywords.length || match;
@@ -140,78 +101,35 @@ class ValueFilter {
140
101
  }
141
102
  }
142
103
  initFilterStateFromTableData(fieldId) {
143
- var _a, _b, _c, _d;
144
- const filter = this.filterStateManager.getFilterState(fieldId), isEnable = null == filter ? void 0 : filter.enable, syncCheckboxCheckedState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncCheckboxCheckedState) || void 0 === _b || _b;
145
- if (isEnable) {
146
- const selectedRawValues = new Set, displayToRawMap = this.displayToRawValueMap.get(fieldId);
147
- let targetCol = -1;
148
- for (let col = 0; col < this.table.colCount; col++) {
149
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
150
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
151
- if (bodyInfo && bodyInfo.field === fieldId) {
152
- targetCol = col;
153
- break;
154
- }
155
- }
156
- if (-1 !== targetCol) break;
157
- }
158
- const currentLength = this.table.internalProps.dataSource.length;
159
- for (let i = 0; i < currentLength; i++) {
160
- let displayValue, rawValue;
161
- if (-1 !== targetCol) {
162
- const row = this.table.columnHeaderLevelCount + i;
163
- row < this.table.rowCount && (displayValue = this.table.getCellValue(targetCol, row),
164
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue);
165
- } else displayValue = this.table.getFieldData(String(fieldId), -1 !== targetCol ? targetCol : 0, this.table.columnHeaderLevelCount + i),
166
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
167
- null != rawValue && selectedRawValues.add(rawValue);
104
+ if (this.filterStateManager.getActiveFilterFields()) return;
105
+ const selectedValues = new Set, originalValues = new Set;
106
+ this.table.internalProps.dataSource.records.forEach((record => {
107
+ (0, vutils_1.isValid)(record) && selectedValues.add(record[fieldId]);
108
+ }));
109
+ this.table.internalProps.records.forEach((record => {
110
+ (0, vutils_1.isValid)(record) && originalValues.add(record[fieldId]);
111
+ }));
112
+ !(0, vutils_1.arrayEqual)(Array.from(originalValues), Array.from(selectedValues)) && (this.selectedKeys.set(fieldId, selectedValues),
113
+ this.filterStateManager.dispatch({
114
+ type: types_1.FilterActionType.ADD_FILTER,
115
+ payload: {
116
+ field: fieldId,
117
+ type: "byValue",
118
+ values: Array.from(selectedValues),
119
+ enable: !0
168
120
  }
169
- !(0, vutils_1.arrayEqual)(filter.values, Array.from(selectedRawValues)) && syncCheckboxCheckedState && this.filterStateManager.dispatch({
170
- type: types_1.FilterActionType.UPDATE_FILTER,
171
- payload: {
172
- field: fieldId,
173
- values: Array.from(selectedRawValues)
174
- }
175
- });
176
- } else {
177
- const availableRawValues = (null === (_d = null === (_c = this.uniqueKeys.get(fieldId)) || void 0 === _c ? void 0 : _c.filter((item => !syncCheckboxCheckedState || item.count > 0))) || void 0 === _d ? void 0 : _d.map((item => item.rawValue)).filter((v => null != v))) || [];
178
- this.filterStateManager.dispatch({
179
- type: types_1.FilterActionType.ADD_FILTER,
180
- payload: {
181
- field: fieldId,
182
- type: "byValue",
183
- values: availableRawValues,
184
- enable: !1
185
- }
186
- });
187
- }
188
- }
189
- syncCheckboxesWithFilterState(filter) {
190
- if (!filter) return;
191
- const selectedRawValues = filter.values || [], displayToRawMap = this.displayToRawValueMap.get(filter.field), optionDomList = this.valueFilterOptionList.get(filter.field);
192
- null == optionDomList || optionDomList.forEach((optionDom => {
193
- const displayValue = optionDom.originalValue, rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
194
- optionDom.checkbox.checked = selectedRawValues.some((v => v === rawValue));
195
121
  }));
196
122
  }
197
- syncSelectAllWithFilterState(filter) {
198
- var _a;
199
- if (!filter || !filter.values) return this.selectAllCheckbox.checked = !1, void (this.selectAllCheckbox.indeterminate = !1);
200
- const uniqueValuesCount = (null === (_a = this.uniqueKeys.get(filter.field)) || void 0 === _a ? void 0 : _a.length) || 0;
201
- 0 === uniqueValuesCount || 0 === filter.values.length ? (this.selectAllCheckbox.checked = !1,
202
- this.selectAllCheckbox.indeterminate = !1) : filter.values.length === uniqueValuesCount ? (this.selectAllCheckbox.checked = !0,
203
- this.selectAllCheckbox.indeterminate = !1) : (this.selectAllCheckbox.checked = !1,
204
- this.selectAllCheckbox.indeterminate = !0);
205
- }
206
123
  applyFilter(fieldId = this.selectedField) {
207
- var _a;
208
- const allSelectedValues = this.filterStateManager.getFilterState(fieldId).values;
209
- allSelectedValues.length >= 0 && allSelectedValues.length < (null === (_a = this.uniqueKeys.get(fieldId)) || void 0 === _a ? void 0 : _a.length) ? this.filterStateManager.dispatch({
124
+ const options = this.valueFilterOptionList.get(fieldId);
125
+ if (!options || 0 === options.length) return;
126
+ const selections = options.map((option => option.checkbox.checked ? option.originalValue : null)).filter((key => null !== key)).flat();
127
+ this.selectedKeys.set(fieldId, new Set(selections)), selections.length >= 0 && selections.length < this.valueFilterOptionList.get(fieldId).length ? this.filterStateManager.dispatch({
210
128
  type: types_1.FilterActionType.APPLY_FILTERS,
211
129
  payload: {
212
130
  field: fieldId,
213
131
  type: "byValue",
214
- values: allSelectedValues,
132
+ values: selections,
215
133
  enable: !0
216
134
  }
217
135
  }) : this.filterStateManager.dispatch({
@@ -231,25 +149,25 @@ class ValueFilter {
231
149
  }
232
150
  render(container) {
233
151
  var _a;
234
- this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, this.styles.filterPanel),
152
+ const filterStyles = this.styles;
153
+ this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, filterStyles.filterPanel),
235
154
  this.searchContainer = document.createElement("div"), (0, styles_1.applyStyles)(this.searchContainer, this.styles.searchContainer),
236
155
  this.filterByValueSearchInput = document.createElement("input"), this.filterByValueSearchInput.type = "text",
237
- this.filterByValueSearchInput.placeholder = (null === (_a = this.styles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
238
- (0, styles_1.applyStyles)(this.filterByValueSearchInput, this.styles.searchInput),
156
+ this.filterByValueSearchInput.placeholder = (null === (_a = filterStyles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
157
+ (0, styles_1.applyStyles)(this.filterByValueSearchInput, filterStyles.searchInput),
239
158
  this.searchContainer.appendChild(this.filterByValueSearchInput), this.optionsContainer = document.createElement("div"),
240
159
  (0, styles_1.applyStyles)(this.optionsContainer, this.styles.optionsContainer),
241
160
  this.selectAllItemDiv = document.createElement("div"), (0, styles_1.applyStyles)(this.selectAllItemDiv, this.styles.optionItem),
242
161
  this.selectAllLabel = document.createElement("label"), (0, styles_1.applyStyles)(this.selectAllLabel, this.styles.optionLabel),
243
162
  this.selectAllCheckbox = document.createElement("input"), this.selectAllCheckbox.type = "checkbox",
244
- this.selectAllCheckbox.checked = !0, (0, styles_1.applyStyles)(this.selectAllCheckbox, this.styles.checkbox),
245
- this.selectAllLabel.append(this.selectAllCheckbox, " 全选"), this.selectAllItemDiv.appendChild(this.selectAllLabel),
246
- this.filterItemsContainer = document.createElement("div"), this.optionsContainer.append(this.selectAllItemDiv, this.filterItemsContainer),
163
+ this.selectAllCheckbox.checked = !0, (0, styles_1.applyStyles)(this.selectAllCheckbox, filterStyles.checkbox),
164
+ this.totalCountSpan = document.createElement("span"), this.totalCountSpan.textContent = "",
165
+ (0, styles_1.applyStyles)(this.totalCountSpan, filterStyles.countSpan), this.selectAllLabel.append(this.selectAllCheckbox, " 全选"),
166
+ this.selectAllItemDiv.appendChild(this.selectAllLabel), this.filterItemsContainer = document.createElement("div"),
167
+ this.optionsContainer.append(this.selectAllItemDiv, this.filterItemsContainer),
247
168
  this.filterByValuePanel.append(this.searchContainer, this.optionsContainer), container.appendChild(this.filterByValuePanel),
248
169
  this.bindEventForFilterByValue();
249
170
  }
250
- updatePluginOptions(pluginOptions) {
251
- this.pluginOptions = pluginOptions, this.styles = pluginOptions.styles, this.updateStyles(pluginOptions.styles);
252
- }
253
171
  updateStyles(styles) {
254
172
  var _a;
255
173
  (0, styles_1.applyStyles)(this.filterByValuePanel, styles.filterPanel), (0, styles_1.applyStyles)(this.searchContainer, styles.searchContainer),
@@ -259,68 +177,57 @@ class ValueFilter {
259
177
  (0, styles_1.applyStyles)(this.selectAllLabel, styles.optionLabel), (0, styles_1.applyStyles)(this.selectAllCheckbox, styles.checkbox);
260
178
  }
261
179
  renderFilterOptions(field) {
262
- var _a, _b;
180
+ var _a, _b, _c;
181
+ const filterStyles = this.styles;
263
182
  this.filterItemsContainer.innerHTML = "", this.valueFilterOptionList.delete(field),
264
183
  this.valueFilterOptionList.set(field, []);
265
- const selectedRawValues = (null === (_a = this.filterStateManager.getFilterState(field)) || void 0 === _a ? void 0 : _a.values) || [], selectedRawValueSet = new Set(selectedRawValues), itemDomList = [];
266
- null === (_b = this.uniqueKeys.get(field)) || void 0 === _b || _b.forEach((({value: value, count: count, rawValue: rawValue}) => {
267
- const itemDiv = document.createElement("div");
268
- (0, styles_1.applyStyles)(itemDiv, this.styles.optionItem), itemDiv.style.display = "flex";
184
+ let totalCount = 0, allChecked = !0, noneChecked = !0;
185
+ const selectedKeysSet = this.selectedKeys.get(field), itemDomList = [], isFiltered = null === (_a = this.filterStateManager.getFilterState(field)) || void 0 === _a ? void 0 : _a.enable, toUnformatted = this.toUnformattedCache.get(field), candidates = this.candidateKeys.get(field);
186
+ if (!candidates || 0 === candidates.size) return;
187
+ const candidatesArr = [ ...candidates.entries() ], sortedCandidatesArr = "number" == typeof candidatesArr[0][0] ? null === (_b = [ ...candidatesArr ]) || void 0 === _b ? void 0 : _b.sort((([a], [b]) => Number(a) - Number(b))) : null === (_c = [ ...candidatesArr ]) || void 0 === _c ? void 0 : _c.sort((([a], [b]) => String(a).localeCompare(String(b))));
188
+ null == sortedCandidatesArr || sortedCandidatesArr.forEach((([val, count]) => {
189
+ var _a, _b;
190
+ totalCount += count;
191
+ const unformattedArr = Array.from(toUnformatted.get(val) || new Set), itemDiv = document.createElement("div");
192
+ (0, styles_1.applyStyles)(itemDiv, filterStyles.optionItem), itemDiv.style.display = "flex";
269
193
  const label = document.createElement("label");
270
- (0, styles_1.applyStyles)(label, this.styles.optionLabel);
194
+ (0, styles_1.applyStyles)(label, filterStyles.optionLabel);
271
195
  const checkbox = document.createElement("input");
272
- checkbox.type = "checkbox", checkbox.value = String(value), checkbox.checked = selectedRawValueSet.has(rawValue),
273
- (0, styles_1.applyStyles)(checkbox, this.styles.checkbox);
196
+ checkbox.type = "checkbox", checkbox.value = String(val), checkbox.checked = !isFiltered || unformattedArr.some((v => null == selectedKeysSet ? void 0 : selectedKeysSet.has(v))),
197
+ (0, styles_1.applyStyles)(checkbox, filterStyles.checkbox), checkbox.checked ? noneChecked = !1 : allChecked = !1;
274
198
  const countSpan = document.createElement("span");
275
- countSpan.textContent = String(count), (0, styles_1.applyStyles)(countSpan, this.styles.countSpan),
276
- label.append(checkbox, ` ${rawValue}`), itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
199
+ countSpan.textContent = String(count), (0, styles_1.applyStyles)(countSpan, filterStyles.countSpan),
200
+ label.append(checkbox, ` ${(null === (_b = (_a = this.pluginOptions).checkboxItemFormat) || void 0 === _b ? void 0 : _b.call(_a, val, unformattedArr)) || val}`),
201
+ itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
277
202
  const itemDom = {
278
- id: String(value),
279
- originalValue: value,
203
+ id: String(val),
204
+ originalValue: unformattedArr,
280
205
  itemContainer: itemDiv,
281
206
  checkbox: checkbox,
282
207
  countSpan: countSpan
283
208
  };
284
209
  itemDomList.push(itemDom);
285
- })), this.valueFilterOptionList.set(field, itemDomList);
210
+ })), this.valueFilterOptionList.set(field, itemDomList), this.selectAllCheckbox.checked = allChecked,
211
+ this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked, this.totalCountSpan.textContent = String(totalCount);
286
212
  }
287
213
  bindEventForFilterByValue() {
288
- this.filterByValuePanel.addEventListener("keyup", (event => {
214
+ this._onInputKeyUpHandler = event => {
289
215
  const target = event.target;
290
216
  if (target instanceof HTMLInputElement && "text" === target.type) {
291
217
  const value = target.value;
292
218
  this.onSearch(this.selectedField, value);
293
219
  }
294
- })), this.filterByValuePanel.addEventListener("change", (event => {
220
+ }, this._onCheckboxChangeHandler = event => {
295
221
  const target = event.target;
296
- target instanceof HTMLInputElement && "checkbox" === target.type && (target === this.selectAllCheckbox ? this.valueFilterOptionList.get(this.selectedField).forEach((item => item.checkbox.checked = target.checked)) : this.updateCheckboxUI(this.selectedField));
297
- }));
298
- }
299
- updateCheckboxUI(field) {
300
- var _a, _b;
301
- const checkedItem = null === (_a = this.valueFilterOptionList.get(field)) || void 0 === _a ? void 0 : _a.filter((item => item.checkbox.checked)), uncheckedItem = null === (_b = this.valueFilterOptionList.get(field)) || void 0 === _b ? void 0 : _b.filter((item => !item.checkbox.checked));
302
- (0, vutils_1.isValid)(checkedItem) && (0, vutils_1.isValid)(uncheckedItem) && (0 !== checkedItem.length && 0 !== uncheckedItem.length ? this.selectAllCheckbox.indeterminate = !0 : (this.selectAllCheckbox.indeterminate = !1,
303
- this.selectAllCheckbox.checked = 0 === uncheckedItem.length));
304
- }
305
- updateCheckboxState(field) {
306
- var _a;
307
- const originalValues = null === (_a = this.valueFilterOptionList.get(field)) || void 0 === _a ? void 0 : _a.filter((item => item.checkbox.checked)).map((item => item.originalValue)), displayToRawMap = this.displayToRawValueMap.get(field), rawValues = originalValues.map((displayValue => displayToRawMap ? displayToRawMap.get(displayValue) : displayValue));
308
- this.filterStateManager.dispatch({
309
- type: types_1.FilterActionType.ADD_FILTER,
310
- payload: {
311
- field: field,
312
- type: "byValue",
313
- values: rawValues
314
- }
315
- });
222
+ target instanceof HTMLInputElement && "checkbox" === target.type && (target === this.selectAllCheckbox ? this.toggleSelectAll(this.selectedField, this.selectAllCheckbox.checked) : this.syncSelectAllCheckbox(this.selectedField));
223
+ }, this.filterByValuePanel.addEventListener("keyup", this._onInputKeyUpHandler),
224
+ this.filterByValuePanel.addEventListener("change", this._onCheckboxChangeHandler);
316
225
  }
317
226
  show() {
318
- this.collectUniqueColumnValues(this.selectedField), this.updateCandidateCounts(this.selectedField),
319
- this.initFilterStateFromTableData(this.selectedField);
320
- const uniqueValues = this.uniqueKeys.get(this.selectedField), displayToRawMap = this.displayToRawValueMap.get(this.selectedField);
321
- uniqueValues && displayToRawMap && this.filterStateManager.initializeFilterMenuState(this.selectedField, uniqueValues, displayToRawMap),
322
- this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""), this.renderFilterOptions(this.selectedField),
323
- this.updateCheckboxUI(this.selectedField), this.filterByValuePanel.style.display = "block";
227
+ var _a;
228
+ (null === (_a = this.filterStateManager.getFilterState(this.selectedField)) || void 0 === _a ? void 0 : _a.enable) ? this.collectCandidateKeysForFilteredColumn(this.selectedField) : this.collectCandidateKeysForUnfilteredColumn(this.selectedField),
229
+ this.initFilterStateFromTableData(this.selectedField), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
230
+ this.renderFilterOptions(this.selectedField), this.filterByValuePanel.style.display = "block";
324
231
  }
325
232
  hide() {
326
233
  this.filterByValuePanel.style.display = "none";
@@ -328,6 +235,20 @@ class ValueFilter {
328
235
  clearSearchInputValue() {
329
236
  this.filterByValueSearchInput.value = "";
330
237
  }
238
+ destroy() {
239
+ if (this.filterByValuePanel && (this._onInputKeyUpHandler && this.filterByValuePanel.removeEventListener("keyup", this._onInputKeyUpHandler),
240
+ this._onCheckboxChangeHandler && this.filterByValuePanel.removeEventListener("change", this._onCheckboxChangeHandler)),
241
+ this._onInputKeyUpHandler = void 0, this._onCheckboxChangeHandler = void 0, this.filterByValuePanel) {
242
+ const parent = this.filterByValuePanel.parentElement;
243
+ parent ? parent.removeChild(this.filterByValuePanel) : this.filterByValuePanel.remove();
244
+ }
245
+ this.filterItemsContainer && (this.filterItemsContainer.innerHTML = ""), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
246
+ this.selectedKeys && this.selectedKeys.clear(), this.candidateKeys && this.candidateKeys.clear(),
247
+ this.formatFnCache && this.formatFnCache.clear(), this.toUnformattedCache && this.toUnformattedCache.clear(),
248
+ this.valueFilterOptionList && this.valueFilterOptionList.clear(), this.filterByValuePanel = void 0,
249
+ this.filterByValueSearchInput = void 0, this.selectAllCheckbox = void 0, this.totalCountSpan = void 0,
250
+ this.filterItemsContainer = void 0;
251
+ }
331
252
  }
332
253
 
333
254
  exports.ValueFilter = ValueFilter;