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