@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
@@ -1,56 +1,136 @@
1
- import { arrayEqual } from "@visactor/vutils";
1
+ import { arrayEqual, isValid } from "@visactor/vutils";
2
2
 
3
3
  import { FilterActionType } from "./types";
4
4
 
5
- import { applyStyles, filterStyles } from "./styles";
5
+ import { applyStyles } from "./styles";
6
6
 
7
7
  export class ValueFilter {
8
- constructor(table, filterStateManager) {
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;
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);
12
18
  }
13
19
  setSelectedField(fieldId) {
14
- this.selectedField = fieldId;
15
- }
16
- getFormatFnCache(fieldId) {
17
- let formatFn = this.formatFnCache.get(fieldId);
18
- if (null != formatFn) return formatFn;
19
- 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);
20
- 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],
21
- this.formatFnCache.set(fieldId, formatFn), formatFn;
22
- }
23
- collectCandidateKeysForUnfilteredColumn(fieldId) {
24
- const countMap = new Map, records = this.table.internalProps.dataSource.records, formatFn = this.getFormatFnCache(fieldId), toUnformatted = new Map;
25
- records.forEach((record => {
26
- const originalValue = record[fieldId], formattedValue = formatFn(record);
27
- if (null != formattedValue) {
28
- countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
29
- const unformattedSet = toUnformatted.get(formattedValue);
30
- null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
20
+ this.selectedField = fieldId, this.collectUniqueColumnValues(fieldId);
21
+ }
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
+ }
31
34
  }
32
- })), this.candidateKeys.set(fieldId, countMap), this.toUnformattedCache.set(fieldId, toUnformatted);
33
- }
34
- collectCandidateKeysForFilteredColumn(candidateField) {
35
- const filteredFields = this.filterStateManager.getActiveFilterFields().filter((field => field !== candidateField)), toUnformatted = new Map, formatFn = this.getFormatFnCache(candidateField), countMap = new Map;
36
- this.table.internalProps.records.filter((record => filteredFields.every((field => this.selectedKeys.get(field).has(record[field]))))).forEach((record => {
37
- const originalValue = record[candidateField], formattedValue = formatFn(record);
38
- if (countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1), null != formattedValue) {
39
- const unformattedSet = toUnformatted.get(formattedValue);
40
- null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
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);
59
+ }
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;
71
+ }
41
72
  }
42
- })), this.candidateKeys.set(candidateField, countMap), this.toUnformattedCache.set(candidateField, toUnformatted);
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;
86
+ }));
43
87
  }
44
- toggleSelectAll(fieldId, selected) {
45
- this.valueFilterOptionList.get(fieldId).forEach((option => {
46
- option.checkbox.checked = selected;
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
+ }
47
105
  }));
48
106
  }
49
- syncSelectAllCheckbox(fieldId) {
50
- const options = this.valueFilterOptionList.get(fieldId) || [], allChecked = options.every((o => o.checkbox.checked)), noneChecked = options.every((o => !o.checkbox.checked));
51
- this.selectAllCheckbox.checked = allChecked, this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
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)));
111
+ }
112
+ 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
+ });
52
131
  }
53
132
  onSearch(fieldId, value) {
133
+ this.filterStateManager.updateSearchKeyword(fieldId, value);
54
134
  const items = this.valueFilterOptionList.get(fieldId), filterKeywords = value.toUpperCase().split(" ").filter((s => s));
55
135
  for (const item of items) {
56
136
  const txtValue = item.id.toUpperCase() || "", match = filterKeywords.some((keyword => txtValue.includes(keyword))), isVisible = 0 === filterKeywords.length || match;
@@ -58,35 +138,78 @@ export class ValueFilter {
58
138
  }
59
139
  }
60
140
  initFilterStateFromTableData(fieldId) {
61
- if (this.filterStateManager.getActiveFilterFields()) return;
62
- const selectedValues = new Set, originalValues = new Set;
63
- this.table.internalProps.dataSource.records.forEach((record => {
64
- selectedValues.add(record[fieldId]);
65
- }));
66
- this.table.internalProps.records.forEach((record => {
67
- originalValues.add(record[fieldId]);
68
- }));
69
- !arrayEqual(Array.from(originalValues), Array.from(selectedValues)) && (this.selectedKeys.set(fieldId, selectedValues),
70
- this.filterStateManager.dispatch({
71
- type: FilterActionType.ADD_FILTER,
72
- payload: {
73
- field: fieldId,
74
- type: "byValue",
75
- values: Array.from(selectedValues),
76
- enable: !0
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;
77
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);
166
+ }
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));
78
193
  }));
79
194
  }
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
+ }
80
204
  applyFilter(fieldId = this.selectedField) {
81
- const options = this.valueFilterOptionList.get(fieldId);
82
- if (!options || 0 === options.length) return;
83
- const selections = options.map((option => option.checkbox.checked ? option.originalValue : null)).filter((key => null !== key)).flat();
84
- this.selectedKeys.set(fieldId, new Set(selections)), selections.length > 0 && selections.length < this.valueFilterOptionList.get(fieldId).length ? this.filterStateManager.dispatch({
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({
85
208
  type: FilterActionType.APPLY_FILTERS,
86
209
  payload: {
87
210
  field: fieldId,
88
211
  type: "byValue",
89
- values: selections,
212
+ values: allSelectedValues,
90
213
  enable: !0
91
214
  }
92
215
  }) : this.filterStateManager.dispatch({
@@ -105,73 +228,96 @@ export class ValueFilter {
105
228
  }), this.hide();
106
229
  }
107
230
  render(container) {
108
- this.filterByValuePanel = document.createElement("div"), applyStyles(this.filterByValuePanel, filterStyles.filterPanel);
109
- const searchContainer = document.createElement("div");
110
- applyStyles(searchContainer, filterStyles.searchContainer), this.filterByValueSearchInput = document.createElement("input"),
111
- this.filterByValueSearchInput.type = "text", this.filterByValueSearchInput.placeholder = "可使用空格分隔多个关键词",
112
- applyStyles(this.filterByValueSearchInput, filterStyles.searchInput), searchContainer.appendChild(this.filterByValueSearchInput);
113
- const optionsContainer = document.createElement("div");
114
- applyStyles(optionsContainer, filterStyles.optionsContainer);
115
- const selectAllItemDiv = document.createElement("div");
116
- applyStyles(selectAllItemDiv, filterStyles.optionItem);
117
- const selectAllLabel = document.createElement("label");
118
- applyStyles(selectAllLabel, filterStyles.optionLabel), this.selectAllCheckbox = document.createElement("input"),
119
- this.selectAllCheckbox.type = "checkbox", this.selectAllCheckbox.checked = !0, applyStyles(this.selectAllCheckbox, filterStyles.checkbox),
120
- this.totalCountSpan = document.createElement("span"), this.totalCountSpan.textContent = "",
121
- applyStyles(this.totalCountSpan, filterStyles.countSpan), selectAllLabel.append(this.selectAllCheckbox, " 全选"),
122
- selectAllItemDiv.append(selectAllLabel, this.totalCountSpan), this.filterItemsContainer = document.createElement("div"),
123
- optionsContainer.append(selectAllItemDiv, this.filterItemsContainer), this.filterByValuePanel.append(searchContainer, optionsContainer),
124
- container.appendChild(this.filterByValuePanel), this.bindEventForFilterByValue();
231
+ var _a;
232
+ this.filterByValuePanel = document.createElement("div"), applyStyles(this.filterByValuePanel, this.styles.filterPanel),
233
+ this.searchContainer = document.createElement("div"), applyStyles(this.searchContainer, this.styles.searchContainer),
234
+ 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),
237
+ this.optionsContainer = document.createElement("div"), applyStyles(this.optionsContainer, this.styles.optionsContainer),
238
+ this.selectAllItemDiv = document.createElement("div"), applyStyles(this.selectAllItemDiv, this.styles.optionItem),
239
+ this.selectAllLabel = document.createElement("label"), applyStyles(this.selectAllLabel, this.styles.optionLabel),
240
+ 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),
244
+ this.filterByValuePanel.append(this.searchContainer, this.optionsContainer), container.appendChild(this.filterByValuePanel),
245
+ this.bindEventForFilterByValue();
246
+ }
247
+ updatePluginOptions(pluginOptions) {
248
+ this.pluginOptions = pluginOptions, this.styles = pluginOptions.styles, this.updateStyles(pluginOptions.styles);
249
+ }
250
+ updateStyles(styles) {
251
+ var _a;
252
+ applyStyles(this.filterByValuePanel, styles.filterPanel), applyStyles(this.searchContainer, styles.searchContainer),
253
+ this.filterByValueSearchInput.placeholder = (null === (_a = styles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
254
+ applyStyles(this.filterByValueSearchInput, styles.searchInput), applyStyles(this.optionsContainer, styles.optionsContainer),
255
+ applyStyles(this.selectAllItemDiv, styles.optionItem), applyStyles(this.selectAllLabel, styles.optionLabel),
256
+ applyStyles(this.selectAllCheckbox, styles.checkbox);
125
257
  }
126
258
  renderFilterOptions(field) {
127
- var _a, _b, _c;
259
+ var _a, _b;
128
260
  this.filterItemsContainer.innerHTML = "", this.valueFilterOptionList.delete(field),
129
261
  this.valueFilterOptionList.set(field, []);
130
- let totalCount = 0, allChecked = !0, noneChecked = !0;
131
- 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);
132
- if (!candidates || 0 === candidates.size) return;
133
- 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))));
134
- null == sortedCandidatesArr || sortedCandidatesArr.forEach((([val, count]) => {
135
- totalCount += count;
136
- const unformattedArr = Array.from(toUnformatted.get(val) || new Set), itemDiv = document.createElement("div");
137
- applyStyles(itemDiv, filterStyles.optionItem), itemDiv.style.display = "flex";
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";
138
266
  const label = document.createElement("label");
139
- applyStyles(label, filterStyles.optionLabel);
267
+ applyStyles(label, this.styles.optionLabel);
140
268
  const checkbox = document.createElement("input");
141
- checkbox.type = "checkbox", checkbox.value = String(val), checkbox.checked = !isFiltered || unformattedArr.some((v => null == selectedKeysSet ? void 0 : selectedKeysSet.has(v))),
142
- applyStyles(checkbox, filterStyles.checkbox), checkbox.checked ? noneChecked = !1 : allChecked = !1;
269
+ checkbox.type = "checkbox", checkbox.value = String(value), checkbox.checked = selectedRawValueSet.has(rawValue),
270
+ applyStyles(checkbox, this.styles.checkbox);
143
271
  const countSpan = document.createElement("span");
144
- countSpan.textContent = String(count), applyStyles(countSpan, filterStyles.countSpan),
145
- label.append(checkbox, ` ${val}`), itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
272
+ countSpan.textContent = String(count), applyStyles(countSpan, this.styles.countSpan),
273
+ label.append(checkbox, ` ${rawValue}`), itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
146
274
  const itemDom = {
147
- id: String(val),
148
- originalValue: unformattedArr,
275
+ id: String(value),
276
+ originalValue: value,
149
277
  itemContainer: itemDiv,
150
278
  checkbox: checkbox,
151
279
  countSpan: countSpan
152
280
  };
153
281
  itemDomList.push(itemDom);
154
- })), this.valueFilterOptionList.set(field, itemDomList), this.selectAllCheckbox.checked = allChecked,
155
- this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked, this.totalCountSpan.textContent = String(totalCount);
282
+ })), this.valueFilterOptionList.set(field, itemDomList);
156
283
  }
157
284
  bindEventForFilterByValue() {
158
- this._onInputKeyUpHandler = event => {
285
+ this.filterByValuePanel.addEventListener("keyup", (event => {
159
286
  const target = event.target;
160
287
  if (target instanceof HTMLInputElement && "text" === target.type) {
161
288
  const value = target.value;
162
289
  this.onSearch(this.selectedField, value);
163
290
  }
164
- }, this._onCheckboxChangeHandler = event => {
291
+ })), this.filterByValuePanel.addEventListener("change", (event => {
165
292
  const target = event.target;
166
- target instanceof HTMLInputElement && "checkbox" === target.type && (target === this.selectAllCheckbox ? this.toggleSelectAll(this.selectedField, this.selectAllCheckbox.checked) : this.syncSelectAllCheckbox(this.selectedField));
167
- }, this.filterByValuePanel.addEventListener("keyup", this._onInputKeyUpHandler),
168
- this.filterByValuePanel.addEventListener("change", this._onCheckboxChangeHandler);
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
+ }));
169
295
  }
170
- show() {
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) {
171
303
  var _a;
172
- (null === (_a = this.filterStateManager.getFilterState(this.selectedField)) || void 0 === _a ? void 0 : _a.enable) ? this.collectCandidateKeysForFilteredColumn(this.selectedField) : this.collectCandidateKeysForUnfilteredColumn(this.selectedField),
173
- this.initFilterStateFromTableData(this.selectedField), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
174
- this.renderFilterOptions(this.selectedField), this.filterByValuePanel.style.display = "block";
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
+ });
313
+ }
314
+ 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";
175
321
  }
176
322
  hide() {
177
323
  this.filterByValuePanel.style.display = "none";
@@ -179,19 +325,5 @@ export class ValueFilter {
179
325
  clearSearchInputValue() {
180
326
  this.filterByValueSearchInput.value = "";
181
327
  }
182
- destroy() {
183
- if (this.filterByValuePanel && (this._onInputKeyUpHandler && this.filterByValuePanel.removeEventListener("keyup", this._onInputKeyUpHandler),
184
- this._onCheckboxChangeHandler && this.filterByValuePanel.removeEventListener("change", this._onCheckboxChangeHandler)),
185
- this._onInputKeyUpHandler = void 0, this._onCheckboxChangeHandler = void 0, this.filterByValuePanel) {
186
- const parent = this.filterByValuePanel.parentElement;
187
- parent ? parent.removeChild(this.filterByValuePanel) : this.filterByValuePanel.remove();
188
- }
189
- this.filterItemsContainer && (this.filterItemsContainer.innerHTML = ""), this.filterByValueSearchInput && (this.filterByValueSearchInput.value = ""),
190
- this.selectedKeys && this.selectedKeys.clear(), this.candidateKeys && this.candidateKeys.clear(),
191
- this.formatFnCache && this.formatFnCache.clear(), this.toUnformattedCache && this.toUnformattedCache.clear(),
192
- this.valueFilterOptionList && this.valueFilterOptionList.clear(), this.filterByValuePanel = void 0,
193
- this.filterByValueSearchInput = void 0, this.selectAllCheckbox = void 0, this.totalCountSpan = void 0,
194
- this.filterItemsContainer = void 0;
195
- }
196
328
  }
197
329
  //# sourceMappingURL=value-filter.js.map