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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/cjs/auto-fill/date-tools.js +1 -2
  2. package/cjs/contextmenu/index.js +2 -1
  3. package/cjs/filter/condition-filter.d.ts +12 -2
  4. package/cjs/filter/condition-filter.js +40 -144
  5. package/cjs/filter/condition-filter.js.map +1 -1
  6. package/cjs/filter/constants.d.ts +7 -0
  7. package/cjs/filter/constants.js +124 -0
  8. package/cjs/filter/constants.js.map +1 -0
  9. package/cjs/filter/filter-state-manager.d.ts +14 -0
  10. package/cjs/filter/filter-state-manager.js +35 -1
  11. package/cjs/filter/filter-state-manager.js.map +1 -1
  12. package/cjs/filter/filter-toolbar.d.ts +9 -4
  13. package/cjs/filter/filter-toolbar.js +54 -32
  14. package/cjs/filter/filter-toolbar.js.map +1 -1
  15. package/cjs/filter/filter.d.ts +2 -0
  16. package/cjs/filter/filter.js +30 -14
  17. package/cjs/filter/filter.js.map +1 -1
  18. package/cjs/filter/styles.d.ts +2 -124
  19. package/cjs/filter/styles.js.map +1 -1
  20. package/cjs/filter/types.d.ts +33 -0
  21. package/cjs/filter/types.js.map +1 -1
  22. package/cjs/filter/value-filter.d.ts +23 -15
  23. package/cjs/filter/value-filter.js +247 -116
  24. package/cjs/filter/value-filter.js.map +1 -1
  25. package/cjs/focus-highlight.js +1 -1
  26. package/cjs/focus-highlight.js.map +1 -1
  27. package/cjs/gantt-export-image.js.map +1 -1
  28. package/cjs/master-detail-plugin/checkbox.js +0 -1
  29. package/cjs/master-detail-plugin/config.js +2 -1
  30. package/cjs/master-detail-plugin/config.js.map +1 -1
  31. package/cjs/master-detail-plugin/utils.js +1 -1
  32. package/dist/vtable-plugins.js +10105 -320
  33. package/dist/vtable-plugins.min.js +3 -3
  34. package/es/auto-fill/date-tools.js +1 -2
  35. package/es/contextmenu/index.js +2 -1
  36. package/es/filter/condition-filter.d.ts +12 -2
  37. package/es/filter/condition-filter.js +39 -141
  38. package/es/filter/condition-filter.js.map +1 -1
  39. package/es/filter/constants.d.ts +7 -0
  40. package/es/filter/constants.js +120 -0
  41. package/es/filter/constants.js.map +1 -0
  42. package/es/filter/filter-state-manager.d.ts +14 -0
  43. package/es/filter/filter-state-manager.js +35 -1
  44. package/es/filter/filter-state-manager.js.map +1 -1
  45. package/es/filter/filter-toolbar.d.ts +9 -4
  46. package/es/filter/filter-toolbar.js +57 -31
  47. package/es/filter/filter-toolbar.js.map +1 -1
  48. package/es/filter/filter.d.ts +2 -0
  49. package/es/filter/filter.js +36 -15
  50. package/es/filter/filter.js.map +1 -1
  51. package/es/filter/styles.d.ts +2 -124
  52. package/es/filter/styles.js.map +1 -1
  53. package/es/filter/types.d.ts +33 -0
  54. package/es/filter/types.js.map +1 -1
  55. package/es/filter/value-filter.d.ts +23 -15
  56. package/es/filter/value-filter.js +250 -118
  57. package/es/filter/value-filter.js.map +1 -1
  58. package/es/focus-highlight.js +1 -1
  59. package/es/focus-highlight.js.map +1 -1
  60. package/es/gantt-export-image.js.map +1 -1
  61. package/es/master-detail-plugin/checkbox.js +1 -2
  62. package/es/master-detail-plugin/config.js +2 -1
  63. package/es/master-detail-plugin/config.js.map +1 -1
  64. package/es/master-detail-plugin/utils.js +1 -1
  65. package/package.json +8 -8
@@ -7,52 +7,132 @@ Object.defineProperty(exports, "__esModule", {
7
7
  const vutils_1 = require("@visactor/vutils"), types_1 = require("./types"), styles_1 = require("./styles");
8
8
 
9
9
  class ValueFilter {
10
- constructor(table, filterStateManager) {
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;
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);
14
20
  }
15
21
  setSelectedField(fieldId) {
16
- this.selectedField = fieldId;
17
- }
18
- getFormatFnCache(fieldId) {
19
- let formatFn = this.formatFnCache.get(fieldId);
20
- if (null != formatFn) return formatFn;
21
- 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);
22
- 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],
23
- this.formatFnCache.set(fieldId, formatFn), formatFn;
24
- }
25
- collectCandidateKeysForUnfilteredColumn(fieldId) {
26
- const countMap = new Map, records = this.table.internalProps.dataSource.records, formatFn = this.getFormatFnCache(fieldId), toUnformatted = new Map;
27
- records.forEach((record => {
28
- const originalValue = record[fieldId], formattedValue = formatFn(record);
29
- if (null != formattedValue) {
30
- countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
31
- const unformattedSet = toUnformatted.get(formattedValue);
32
- null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
22
+ this.selectedField = fieldId, this.collectUniqueColumnValues(fieldId);
23
+ }
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
+ }
33
36
  }
34
- })), this.candidateKeys.set(fieldId, countMap), this.toUnformattedCache.set(fieldId, toUnformatted);
35
- }
36
- collectCandidateKeysForFilteredColumn(candidateField) {
37
- const filteredFields = this.filterStateManager.getActiveFilterFields().filter((field => field !== candidateField)), toUnformatted = new Map, formatFn = this.getFormatFnCache(candidateField), countMap = new Map;
38
- this.table.internalProps.records.filter((record => filteredFields.every((field => this.selectedKeys.get(field).has(record[field]))))).forEach((record => {
39
- const originalValue = record[candidateField], formattedValue = formatFn(record);
40
- if (countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1), null != formattedValue) {
41
- const unformattedSet = toUnformatted.get(formattedValue);
42
- null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
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);
61
+ }
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;
73
+ }
43
74
  }
44
- })), this.candidateKeys.set(candidateField, countMap), this.toUnformattedCache.set(candidateField, toUnformatted);
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;
88
+ }));
45
89
  }
46
- toggleSelectAll(fieldId, selected) {
47
- this.valueFilterOptionList.get(fieldId).forEach((option => {
48
- option.checkbox.checked = selected;
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
+ }
49
107
  }));
50
108
  }
51
- syncSelectAllCheckbox(fieldId) {
52
- const options = this.valueFilterOptionList.get(fieldId) || [], allChecked = options.every((o => o.checkbox.checked)), noneChecked = options.every((o => !o.checkbox.checked));
53
- this.selectAllCheckbox.checked = allChecked, this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
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)));
113
+ }
114
+ 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
+ });
54
133
  }
55
134
  onSearch(fieldId, value) {
135
+ this.filterStateManager.updateSearchKeyword(fieldId, value);
56
136
  const items = this.valueFilterOptionList.get(fieldId), filterKeywords = value.toUpperCase().split(" ").filter((s => s));
57
137
  for (const item of items) {
58
138
  const txtValue = item.id.toUpperCase() || "", match = filterKeywords.some((keyword => txtValue.includes(keyword))), isVisible = 0 === filterKeywords.length || match;
@@ -60,35 +140,78 @@ class ValueFilter {
60
140
  }
61
141
  }
62
142
  initFilterStateFromTableData(fieldId) {
63
- if (this.filterStateManager.getActiveFilterFields()) return;
64
- const selectedValues = new Set, originalValues = new Set;
65
- this.table.internalProps.dataSource.records.forEach((record => {
66
- selectedValues.add(record[fieldId]);
67
- }));
68
- this.table.internalProps.records.forEach((record => {
69
- originalValues.add(record[fieldId]);
70
- }));
71
- !(0, vutils_1.arrayEqual)(Array.from(originalValues), Array.from(selectedValues)) && (this.selectedKeys.set(fieldId, selectedValues),
72
- this.filterStateManager.dispatch({
73
- type: types_1.FilterActionType.ADD_FILTER,
74
- payload: {
75
- field: fieldId,
76
- type: "byValue",
77
- values: Array.from(selectedValues),
78
- enable: !0
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;
79
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);
168
+ }
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));
80
195
  }));
81
196
  }
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
+ }
82
206
  applyFilter(fieldId = this.selectedField) {
83
- const options = this.valueFilterOptionList.get(fieldId);
84
- if (!options || 0 === options.length) return;
85
- const selections = options.map((option => option.checkbox.checked ? option.originalValue : null)).filter((key => null !== key)).flat();
86
- this.selectedKeys.set(fieldId, new Set(selections)), selections.length > 0 && selections.length < this.valueFilterOptionList.get(fieldId).length ? this.filterStateManager.dispatch({
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({
87
210
  type: types_1.FilterActionType.APPLY_FILTERS,
88
211
  payload: {
89
212
  field: fieldId,
90
213
  type: "byValue",
91
- values: selections,
214
+ values: allSelectedValues,
92
215
  enable: !0
93
216
  }
94
217
  }) : this.filterStateManager.dispatch({
@@ -107,75 +230,97 @@ class ValueFilter {
107
230
  }), this.hide();
108
231
  }
109
232
  render(container) {
110
- this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, styles_1.filterStyles.filterPanel);
111
- const searchContainer = document.createElement("div");
112
- (0, styles_1.applyStyles)(searchContainer, styles_1.filterStyles.searchContainer),
233
+ var _a;
234
+ this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, this.styles.filterPanel),
235
+ this.searchContainer = document.createElement("div"), (0, styles_1.applyStyles)(this.searchContainer, this.styles.searchContainer),
113
236
  this.filterByValueSearchInput = document.createElement("input"), this.filterByValueSearchInput.type = "text",
114
- this.filterByValueSearchInput.placeholder = "可使用空格分隔多个关键词", (0, styles_1.applyStyles)(this.filterByValueSearchInput, styles_1.filterStyles.searchInput),
115
- searchContainer.appendChild(this.filterByValueSearchInput);
116
- const optionsContainer = document.createElement("div");
117
- (0, styles_1.applyStyles)(optionsContainer, styles_1.filterStyles.optionsContainer);
118
- const selectAllItemDiv = document.createElement("div");
119
- (0, styles_1.applyStyles)(selectAllItemDiv, styles_1.filterStyles.optionItem);
120
- const selectAllLabel = document.createElement("label");
121
- (0, styles_1.applyStyles)(selectAllLabel, styles_1.filterStyles.optionLabel), this.selectAllCheckbox = document.createElement("input"),
122
- this.selectAllCheckbox.type = "checkbox", this.selectAllCheckbox.checked = !0, (0,
123
- styles_1.applyStyles)(this.selectAllCheckbox, styles_1.filterStyles.checkbox), this.totalCountSpan = document.createElement("span"),
124
- this.totalCountSpan.textContent = "", (0, styles_1.applyStyles)(this.totalCountSpan, styles_1.filterStyles.countSpan),
125
- selectAllLabel.append(this.selectAllCheckbox, " 全选"), selectAllItemDiv.append(selectAllLabel, this.totalCountSpan),
126
- this.filterItemsContainer = document.createElement("div"), optionsContainer.append(selectAllItemDiv, this.filterItemsContainer),
127
- this.filterByValuePanel.append(searchContainer, optionsContainer), container.appendChild(this.filterByValuePanel),
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),
239
+ this.searchContainer.appendChild(this.filterByValueSearchInput), this.optionsContainer = document.createElement("div"),
240
+ (0, styles_1.applyStyles)(this.optionsContainer, this.styles.optionsContainer),
241
+ this.selectAllItemDiv = document.createElement("div"), (0, styles_1.applyStyles)(this.selectAllItemDiv, this.styles.optionItem),
242
+ this.selectAllLabel = document.createElement("label"), (0, styles_1.applyStyles)(this.selectAllLabel, this.styles.optionLabel),
243
+ 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),
247
+ this.filterByValuePanel.append(this.searchContainer, this.optionsContainer), container.appendChild(this.filterByValuePanel),
128
248
  this.bindEventForFilterByValue();
129
249
  }
250
+ updatePluginOptions(pluginOptions) {
251
+ this.pluginOptions = pluginOptions, this.styles = pluginOptions.styles, this.updateStyles(pluginOptions.styles);
252
+ }
253
+ updateStyles(styles) {
254
+ var _a;
255
+ (0, styles_1.applyStyles)(this.filterByValuePanel, styles.filterPanel), (0, styles_1.applyStyles)(this.searchContainer, styles.searchContainer),
256
+ this.filterByValueSearchInput.placeholder = (null === (_a = styles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
257
+ (0, styles_1.applyStyles)(this.filterByValueSearchInput, styles.searchInput), (0,
258
+ styles_1.applyStyles)(this.optionsContainer, styles.optionsContainer), (0, styles_1.applyStyles)(this.selectAllItemDiv, styles.optionItem),
259
+ (0, styles_1.applyStyles)(this.selectAllLabel, styles.optionLabel), (0, styles_1.applyStyles)(this.selectAllCheckbox, styles.checkbox);
260
+ }
130
261
  renderFilterOptions(field) {
131
- var _a, _b, _c;
262
+ var _a, _b;
132
263
  this.filterItemsContainer.innerHTML = "", this.valueFilterOptionList.delete(field),
133
264
  this.valueFilterOptionList.set(field, []);
134
- let totalCount = 0, allChecked = !0, noneChecked = !0;
135
- 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);
136
- if (!candidates || 0 === candidates.size) return;
137
- 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))));
138
- null == sortedCandidatesArr || sortedCandidatesArr.forEach((([val, count]) => {
139
- totalCount += count;
140
- const unformattedArr = Array.from(toUnformatted.get(val) || new Set), itemDiv = document.createElement("div");
141
- (0, styles_1.applyStyles)(itemDiv, styles_1.filterStyles.optionItem), itemDiv.style.display = "flex";
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";
142
269
  const label = document.createElement("label");
143
- (0, styles_1.applyStyles)(label, styles_1.filterStyles.optionLabel);
270
+ (0, styles_1.applyStyles)(label, this.styles.optionLabel);
144
271
  const checkbox = document.createElement("input");
145
- checkbox.type = "checkbox", checkbox.value = String(val), checkbox.checked = !isFiltered || unformattedArr.some((v => null == selectedKeysSet ? void 0 : selectedKeysSet.has(v))),
146
- (0, styles_1.applyStyles)(checkbox, styles_1.filterStyles.checkbox), checkbox.checked ? noneChecked = !1 : allChecked = !1;
272
+ checkbox.type = "checkbox", checkbox.value = String(value), checkbox.checked = selectedRawValueSet.has(rawValue),
273
+ (0, styles_1.applyStyles)(checkbox, this.styles.checkbox);
147
274
  const countSpan = document.createElement("span");
148
- countSpan.textContent = String(count), (0, styles_1.applyStyles)(countSpan, styles_1.filterStyles.countSpan),
149
- label.append(checkbox, ` ${val}`), itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
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);
150
277
  const itemDom = {
151
- id: String(val),
152
- originalValue: unformattedArr,
278
+ id: String(value),
279
+ originalValue: value,
153
280
  itemContainer: itemDiv,
154
281
  checkbox: checkbox,
155
282
  countSpan: countSpan
156
283
  };
157
284
  itemDomList.push(itemDom);
158
- })), this.valueFilterOptionList.set(field, itemDomList), this.selectAllCheckbox.checked = allChecked,
159
- this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked, this.totalCountSpan.textContent = String(totalCount);
285
+ })), this.valueFilterOptionList.set(field, itemDomList);
160
286
  }
161
287
  bindEventForFilterByValue() {
162
- this._onInputKeyUpHandler = event => {
288
+ this.filterByValuePanel.addEventListener("keyup", (event => {
163
289
  const target = event.target;
164
290
  if (target instanceof HTMLInputElement && "text" === target.type) {
165
291
  const value = target.value;
166
292
  this.onSearch(this.selectedField, value);
167
293
  }
168
- }, this._onCheckboxChangeHandler = event => {
294
+ })), this.filterByValuePanel.addEventListener("change", (event => {
169
295
  const target = event.target;
170
- target instanceof HTMLInputElement && "checkbox" === target.type && (target === this.selectAllCheckbox ? this.toggleSelectAll(this.selectedField, this.selectAllCheckbox.checked) : this.syncSelectAllCheckbox(this.selectedField));
171
- }, this.filterByValuePanel.addEventListener("keyup", this._onInputKeyUpHandler),
172
- this.filterByValuePanel.addEventListener("change", this._onCheckboxChangeHandler);
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
+ }));
173
298
  }
174
- show() {
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) {
175
306
  var _a;
176
- (null === (_a = this.filterStateManager.getFilterState(this.selectedField)) || void 0 === _a ? void 0 : _a.enable) ? this.collectCandidateKeysForFilteredColumn(this.selectedField) : this.collectCandidateKeysForUnfilteredColumn(this.selectedField),
177
- this.initFilterStateFromTableData(this.selectedField), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
178
- this.renderFilterOptions(this.selectedField), this.filterByValuePanel.style.display = "block";
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
+ });
316
+ }
317
+ 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";
179
324
  }
180
325
  hide() {
181
326
  this.filterByValuePanel.style.display = "none";
@@ -183,20 +328,6 @@ class ValueFilter {
183
328
  clearSearchInputValue() {
184
329
  this.filterByValueSearchInput.value = "";
185
330
  }
186
- destroy() {
187
- if (this.filterByValuePanel && (this._onInputKeyUpHandler && this.filterByValuePanel.removeEventListener("keyup", this._onInputKeyUpHandler),
188
- this._onCheckboxChangeHandler && this.filterByValuePanel.removeEventListener("change", this._onCheckboxChangeHandler)),
189
- this._onInputKeyUpHandler = void 0, this._onCheckboxChangeHandler = void 0, this.filterByValuePanel) {
190
- const parent = this.filterByValuePanel.parentElement;
191
- parent ? parent.removeChild(this.filterByValuePanel) : this.filterByValuePanel.remove();
192
- }
193
- this.filterItemsContainer && (this.filterItemsContainer.innerHTML = ""), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
194
- this.selectedKeys && this.selectedKeys.clear(), this.candidateKeys && this.candidateKeys.clear(),
195
- this.formatFnCache && this.formatFnCache.clear(), this.toUnformattedCache && this.toUnformattedCache.clear(),
196
- this.valueFilterOptionList && this.valueFilterOptionList.clear(), this.filterByValuePanel = void 0,
197
- this.filterByValueSearchInput = void 0, this.selectAllCheckbox = void 0, this.totalCountSpan = void 0,
198
- this.filterItemsContainer = void 0;
199
- }
200
331
  }
201
332
 
202
333
  exports.ValueFilter = ValueFilter;