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

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 (69) 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 +4 -3
  4. package/cjs/filter/condition-filter.js +42 -41
  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-engine.d.ts +3 -1
  9. package/cjs/filter/filter-engine.js +5 -3
  10. package/cjs/filter/filter-engine.js.map +1 -1
  11. package/cjs/filter/filter-state-manager.d.ts +0 -14
  12. package/cjs/filter/filter-state-manager.js +9 -37
  13. package/cjs/filter/filter-state-manager.js.map +1 -1
  14. package/cjs/filter/filter-toolbar.d.ts +4 -3
  15. package/cjs/filter/filter-toolbar.js +35 -39
  16. package/cjs/filter/filter-toolbar.js.map +1 -1
  17. package/cjs/filter/filter.js +12 -14
  18. package/cjs/filter/filter.js.map +1 -1
  19. package/cjs/filter/styles.d.ts +124 -2
  20. package/cjs/filter/styles.js +1 -1
  21. package/cjs/filter/styles.js.map +1 -1
  22. package/cjs/filter/types.d.ts +8 -6
  23. package/cjs/filter/types.js.map +1 -1
  24. package/cjs/filter/value-filter.d.ts +14 -14
  25. package/cjs/filter/value-filter.js +140 -222
  26. package/cjs/filter/value-filter.js.map +1 -1
  27. package/cjs/gantt-export-image.js.map +1 -1
  28. package/cjs/master-detail-plugin/checkbox.js +1 -0
  29. package/cjs/master-detail-plugin/config.js.map +1 -1
  30. package/cjs/master-detail-plugin/types.js +1 -1
  31. package/cjs/table-export/index.js +1 -2
  32. package/dist/vtable-plugins.js +346 -471
  33. package/dist/vtable-plugins.min.js +2 -2
  34. package/es/auto-fill/date-tools.js +2 -1
  35. package/es/contextmenu/index.js +1 -2
  36. package/es/filter/condition-filter.d.ts +4 -3
  37. package/es/filter/condition-filter.js +42 -41
  38. package/es/filter/condition-filter.js.map +1 -1
  39. package/es/filter/{constants.js → constant.js} +1 -1
  40. package/es/filter/constant.js.map +1 -0
  41. package/es/filter/filter-engine.d.ts +3 -1
  42. package/es/filter/filter-engine.js +5 -3
  43. package/es/filter/filter-engine.js.map +1 -1
  44. package/es/filter/filter-state-manager.d.ts +0 -14
  45. package/es/filter/filter-state-manager.js +9 -37
  46. package/es/filter/filter-state-manager.js.map +1 -1
  47. package/es/filter/filter-toolbar.d.ts +4 -3
  48. package/es/filter/filter-toolbar.js +38 -42
  49. package/es/filter/filter-toolbar.js.map +1 -1
  50. package/es/filter/filter.js +14 -15
  51. package/es/filter/filter.js.map +1 -1
  52. package/es/filter/styles.d.ts +124 -2
  53. package/es/filter/styles.js +1 -1
  54. package/es/filter/styles.js.map +1 -1
  55. package/es/filter/types.d.ts +8 -6
  56. package/es/filter/types.js.map +1 -1
  57. package/es/filter/value-filter.d.ts +14 -14
  58. package/es/filter/value-filter.js +140 -222
  59. package/es/filter/value-filter.js.map +1 -1
  60. package/es/gantt-export-image.js.map +1 -1
  61. package/es/master-detail-plugin/checkbox.js +2 -1
  62. package/es/master-detail-plugin/config.js.map +1 -1
  63. package/es/master-detail-plugin/types.js +1 -1
  64. package/es/table-export/index.js +1 -2
  65. package/package.json +6 -6
  66. package/cjs/filter/constants.js.map +0 -1
  67. package/es/filter/constants.js.map +0 -1
  68. /package/cjs/filter/{constants.d.ts → constant.d.ts} +0 -0
  69. /package/es/filter/{constants.d.ts → constant.d.ts} +0 -0
@@ -8,7 +8,13 @@ export interface FilterOptions {
8
8
  filterModes?: FilterMode[];
9
9
  styles?: FilterStyles;
10
10
  conditionCategories?: FilterOperatorCategoryOption[];
11
- syncCheckboxCheckedState?: boolean;
11
+ checkboxItemFormat?: (rawValue: any, formatValue: any) => any;
12
+ syncFilterItemsState?: boolean;
13
+ onFilterRecordsEnd?: (records: any[]) => any[];
14
+ }
15
+ export interface FilterOperatorCategoryOption {
16
+ value: FilterOperatorCategory;
17
+ label: string;
12
18
  }
13
19
  export type FilterMode = 'byValue' | 'byCondition';
14
20
  export interface FilterState {
@@ -56,10 +62,7 @@ export declare enum FilterOperatorCategory {
56
62
  CHECKBOX = "checkbox",
57
63
  RADIO = "radio"
58
64
  }
59
- export interface FilterOperatorCategoryOption {
60
- value: FilterOperatorCategory;
61
- label: string;
62
- }
65
+ export type FilterListener = (state: FilterState, action?: FilterAction) => void;
63
66
  interface StaticStyles {
64
67
  filterMenu?: Record<string, string>;
65
68
  filterPanel?: Record<string, string>;
@@ -85,5 +88,4 @@ interface FunctionStyles {
85
88
  buttonStyle?: (isPrimary?: boolean) => Record<string, string>;
86
89
  }
87
90
  export type FilterStyles = StaticStyles & FunctionStyles;
88
- export type FilterListener = (state: FilterState, action?: FilterAction) => void;
89
91
  export {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filter/types.ts"],"names":[],"mappings":";;;AA2CA,IAAY,gBAQX;AARD,WAAY,gBAAgB;IAC1B,mEAAU,CAAA;IACV,yEAAa,CAAA;IACb,yEAAa,CAAA;IACb,yEAAa,CAAA;IACb,2EAAc,CAAA;IACd,iFAAiB,CAAA;IACjB,yEAAa,CAAA;AACf,CAAC,EARW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAQ3B;AA2CD,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IAChC,qCAAW,CAAA;IACX,uCAAa,CAAA;IACb,2CAAiB,CAAA;IACjB,yCAAe,CAAA;IACf,+CAAqB,CAAA;IACrB,yCAAe,CAAA;AACjB,CAAC,EAPW,sBAAsB,GAAtB,8BAAsB,KAAtB,8BAAsB,QAOjC","file":"types.js","sourcesContent":["import type { TYPES } from '@visactor/vtable';\n\nexport interface FilterOptions {\n /** 筛选器 ID,用于唯一标识筛选器 */\n id?: string;\n /** 筛选器图标 */\n filterIcon?: TYPES.ColumnIconOption;\n /** 筛选器激活图标 */\n filteringIcon?: TYPES.ColumnIconOption;\n /** 筛选功能启用钩子函数,返回指定列是否启用筛选功能 */\n enableFilter?: (field: number | string, column: TYPES.ColumnDefine) => boolean;\n /** 默认是否启用筛选(当 enableFilter 未定义时使用) */\n defaultEnabled?: boolean;\n /** 是否展示按条件筛选,按值筛选 UI */\n filterModes?: FilterMode[];\n /** 筛选器样式 */\n styles?: FilterStyles;\n /** 筛选器操作符分类 */\n conditionCategories?: FilterOperatorCategoryOption[];\n // /** 参与筛选的数据 */\n // customFilterData?: (dataSource: any[]) => boolean;\n /** 多个筛选器之间是否联动\n * @default true\n */\n syncCheckboxCheckedState?: boolean;\n}\n\nexport type FilterMode = 'byValue' | 'byCondition';\n\nexport interface FilterState {\n filters: Map<string | number, FilterConfig>;\n // activeFilters: string[]; // 激活的筛选器的 ID 列表\n}\n\nexport interface FilterConfig {\n enable: boolean; // 是否启用筛选\n field: string | number; // 对应表格列,同时作为筛选配置的唯一标识\n type: 'byValue' | 'byCondition'; // 筛选类型\n values?: any[]; // 按值筛选时的值列表\n operator?: FilterOperator; // 按条件筛选时的操作符\n condition?: any; // 按条件筛选时的具体条件\n}\n\nexport enum FilterActionType {\n ADD_FILTER,\n REMOVE_FILTER,\n UPDATE_FILTER,\n ENABLE_FILTER,\n DISABLE_FILTER,\n CLEAR_ALL_FILTERS,\n APPLY_FILTERS\n}\n\nexport interface FilterAction {\n type: FilterActionType;\n payload: any;\n}\n\nexport interface ValueFilterOptionDom {\n id: string;\n originalValue: any[];\n itemContainer: HTMLDivElement;\n checkbox: HTMLInputElement;\n countSpan: HTMLSpanElement;\n}\n\nexport type FilterOperator =\n // 通用\n | 'equals'\n | 'notEquals'\n // 数值\n | 'greaterThan'\n | 'lessThan'\n | 'greaterThanOrEqual'\n | 'lessThanOrEqual'\n | 'between'\n | 'notBetween'\n // 文本\n | 'contains'\n | 'notContains'\n | 'startsWith'\n | 'notStartsWith'\n | 'endsWith'\n | 'notEndsWith'\n // 复选框 | 单选框\n | 'isChecked'\n | 'isUnchecked';\n\nexport interface OperatorOption {\n value: FilterOperator;\n label: string;\n category: FilterOperatorCategory;\n}\n\nexport enum FilterOperatorCategory {\n ALL = 'all',\n TEXT = 'text',\n NUMBER = 'number',\n COLOR = 'color',\n CHECKBOX = 'checkbox',\n RADIO = 'radio'\n}\n\nexport interface FilterOperatorCategoryOption {\n value: FilterOperatorCategory;\n label: string;\n}\n\n/**\n * 筛选组件样式类型定义\n */\n\n// 静态样式类型\ninterface StaticStyles {\n filterMenu?: Record<string, string>;\n filterPanel?: Record<string, string>;\n searchContainer?: Record<string, string>;\n searchInput?: Record<string, string>;\n optionsContainer?: Record<string, string>;\n optionItem?: Record<string, string>;\n optionLabel?: Record<string, string>;\n checkbox?: Record<string, string>;\n countSpan?: Record<string, string>;\n tabsContainer?: Record<string, string>;\n footerContainer?: Record<string, string>;\n clearLink?: Record<string, string>;\n conditionContainer?: Record<string, string>;\n formLabel?: Record<string, string>;\n operatorSelect?: Record<string, string>;\n rangeInputContainer?: Record<string, string>;\n addLabel?: Record<string, string>;\n}\n\n// 函数样式类型\ninterface FunctionStyles {\n tabStyle?: (isActive: boolean) => Record<string, string>;\n footerButton?: (isPrimary: boolean) => Record<string, string>;\n buttonStyle?: (isPrimary?: boolean) => Record<string, string>;\n}\n\n// 完整的筛选样式类型\nexport type FilterStyles = StaticStyles & FunctionStyles;\n\n// 事件监听类型\nexport type FilterListener = (state: FilterState, action?: FilterAction) => void;\n"]}
1
+ {"version":3,"sources":["../src/filter/types.ts"],"names":[],"mappings":";;;AAkDA,IAAY,gBAQX;AARD,WAAY,gBAAgB;IAC1B,mEAAU,CAAA;IACV,yEAAa,CAAA;IACb,yEAAa,CAAA;IACb,yEAAa,CAAA;IACb,2EAAc,CAAA;IACd,iFAAiB,CAAA;IACjB,yEAAa,CAAA;AACf,CAAC,EARW,gBAAgB,GAAhB,wBAAgB,KAAhB,wBAAgB,QAQ3B;AA2CD,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IAChC,qCAAW,CAAA;IACX,uCAAa,CAAA;IACb,2CAAiB,CAAA;IACjB,yCAAe,CAAA;IACf,+CAAqB,CAAA;IACrB,yCAAe,CAAA;AACjB,CAAC,EAPW,sBAAsB,GAAtB,8BAAsB,KAAtB,8BAAsB,QAOjC","file":"types.js","sourcesContent":["import type { TYPES } from '@visactor/vtable';\n\nexport interface FilterOptions {\n /** 筛选器 ID,用于唯一标识筛选器 */\n id?: string;\n /** 筛选器图标 */\n filterIcon?: TYPES.ColumnIconOption;\n /** 筛选器激活图标 */\n filteringIcon?: TYPES.ColumnIconOption;\n /** 筛选功能启用钩子函数,返回指定列是否启用筛选功能 */\n enableFilter?: (field: number | string, column: TYPES.ColumnDefine) => boolean;\n /** 默认是否启用筛选(当 enableFilter 未定义时使用) */\n defaultEnabled?: boolean;\n /** 是否展示按条件筛选,按值筛选 UI */\n filterModes?: FilterMode[];\n /** 筛选器样式 */\n styles?: FilterStyles;\n /** 自定义筛选分类 */\n conditionCategories?: FilterOperatorCategoryOption[];\n /** 筛选选项是否展示为原始值 */\n checkboxItemFormat?: (rawValue: any, formatValue: any) => any;\n /** 多个筛选器之间是否联动\n * @default true\n */\n syncFilterItemsState?: boolean;\n /** 筛选记录结束回调 */\n onFilterRecordsEnd?: (records: any[]) => any[];\n}\n\nexport interface FilterOperatorCategoryOption {\n value: FilterOperatorCategory;\n label: string;\n}\n\nexport type FilterMode = 'byValue' | 'byCondition';\n\nexport interface FilterState {\n filters: Map<string | number, FilterConfig>;\n // activeFilters: string[]; // 激活的筛选器的 ID 列表\n}\n\nexport interface FilterConfig {\n enable: boolean; // 是否启用筛选\n field: string | number; // 对应表格列,同时作为筛选配置的唯一标识\n type: 'byValue' | 'byCondition'; // 筛选类型\n values?: any[]; // 按值筛选时的值列表\n operator?: FilterOperator; // 按条件筛选时的操作符\n condition?: any; // 按条件筛选时的具体条件\n}\n\nexport enum FilterActionType {\n ADD_FILTER,\n REMOVE_FILTER,\n UPDATE_FILTER,\n ENABLE_FILTER,\n DISABLE_FILTER,\n CLEAR_ALL_FILTERS,\n APPLY_FILTERS\n}\n\nexport interface FilterAction {\n type: FilterActionType;\n payload: any;\n}\n\nexport interface ValueFilterOptionDom {\n id: string;\n originalValue: any[];\n itemContainer: HTMLDivElement;\n checkbox: HTMLInputElement;\n countSpan: HTMLSpanElement;\n}\n\nexport type FilterOperator =\n // 通用\n | 'equals'\n | 'notEquals'\n // 数值\n | 'greaterThan'\n | 'lessThan'\n | 'greaterThanOrEqual'\n | 'lessThanOrEqual'\n | 'between'\n | 'notBetween'\n // 文本\n | 'contains'\n | 'notContains'\n | 'startsWith'\n | 'notStartsWith'\n | 'endsWith'\n | 'notEndsWith'\n // 复选框 | 单选框\n | 'isChecked'\n | 'isUnchecked';\n\nexport interface OperatorOption {\n value: FilterOperator;\n label: string;\n category: FilterOperatorCategory;\n}\n\nexport enum FilterOperatorCategory {\n ALL = 'all',\n TEXT = 'text',\n NUMBER = 'number',\n COLOR = 'color',\n CHECKBOX = 'checkbox',\n RADIO = 'radio'\n}\n\nexport type FilterListener = (state: FilterState, action?: FilterAction) => void;\n\n/**\n * 筛选组件样式类型定义\n */\n\n// 静态样式类型\ninterface StaticStyles {\n filterMenu?: Record<string, string>;\n filterPanel?: Record<string, string>;\n searchContainer?: Record<string, string>;\n searchInput?: Record<string, string>;\n optionsContainer?: Record<string, string>;\n optionItem?: Record<string, string>;\n optionLabel?: Record<string, string>;\n checkbox?: Record<string, string>;\n countSpan?: Record<string, string>;\n tabsContainer?: Record<string, string>;\n footerContainer?: Record<string, string>;\n clearLink?: Record<string, string>;\n conditionContainer?: Record<string, string>;\n formLabel?: Record<string, string>;\n operatorSelect?: Record<string, string>;\n rangeInputContainer?: Record<string, string>;\n addLabel?: Record<string, string>;\n}\n\n// 函数样式类型\ninterface FunctionStyles {\n tabStyle?: (isActive: boolean) => Record<string, string>;\n footerButton?: (isPrimary: boolean) => Record<string, string>;\n buttonStyle?: (isPrimary?: boolean) => Record<string, string>;\n}\n\n// 完整的筛选样式类型\nexport type FilterStyles = StaticStyles & FunctionStyles;\n"]}
@@ -1,14 +1,16 @@
1
1
  import type { ListTable, PivotTable } from '@visactor/vtable';
2
- import type { FilterConfig, FilterStyles, FilterOptions } from './types';
2
+ import type { FilterOptions, FilterStyles } from './types';
3
3
  import type { FilterStateManager } from './filter-state-manager';
4
4
  export declare class ValueFilter {
5
5
  private table;
6
6
  private filterStateManager;
7
7
  private pluginOptions;
8
8
  private styles;
9
- private uniqueKeys;
10
- private displayToRawValueMap;
11
9
  private selectedField;
10
+ private selectedKeys;
11
+ private candidateKeys;
12
+ private formatFnCache;
13
+ private toUnformattedCache;
12
14
  private valueFilterOptionList;
13
15
  private filterByValuePanel;
14
16
  private searchContainer;
@@ -17,29 +19,27 @@ export declare class ValueFilter {
17
19
  private selectAllLabel;
18
20
  private filterByValueSearchInput;
19
21
  private selectAllCheckbox;
22
+ private totalCountSpan;
20
23
  private filterItemsContainer;
24
+ private _onInputKeyUpHandler;
25
+ private _onCheckboxChangeHandler;
21
26
  constructor(table: ListTable | PivotTable, filterStateManager: FilterStateManager, pluginOptions: FilterOptions);
22
- updateUI(filterState: FilterConfig): void;
23
27
  setSelectedField(fieldId: string | number): void;
24
- collectUniqueColumnValues(fieldId: string | number, forceCollect?: boolean): void;
25
- private updateCandidateCounts;
26
- private onValueSelect;
27
- private isValueVisible;
28
+ private getFormatFnCache;
29
+ private collectCandidateKeysForUnfilteredColumn;
30
+ private collectCandidateKeysForFilteredColumn;
28
31
  private toggleSelectAll;
32
+ private syncSelectAllCheckbox;
29
33
  private onSearch;
30
34
  private initFilterStateFromTableData;
31
- private syncCheckboxesWithFilterState;
32
- private syncSelectAllWithFilterState;
33
35
  applyFilter(fieldId?: string | number): void;
34
36
  clearFilter(fieldId: string | number): void;
35
37
  render(container: HTMLElement): void;
36
- updatePluginOptions(pluginOptions: FilterOptions): void;
37
38
  updateStyles(styles: FilterStyles): void;
38
39
  private renderFilterOptions;
39
- bindEventForFilterByValue(): void;
40
- updateCheckboxUI(field: string | number): void;
41
- updateCheckboxState(field: string | number): void;
40
+ private bindEventForFilterByValue;
42
41
  show(): void;
43
42
  hide(): void;
44
43
  clearSearchInputValue(): void;
44
+ destroy(): void;
45
45
  }
@@ -8,131 +8,65 @@ const vutils_1 = require("@visactor/vutils"), types_1 = require("./types"), styl
8
8
 
9
9
  class ValueFilter {
10
10
  constructor(table, filterStateManager, pluginOptions) {
11
- this.uniqueKeys = new Map, this.displayToRawValueMap = new Map, this.valueFilterOptionList = new Map,
12
- this.table = table, this.filterStateManager = filterStateManager, this.pluginOptions = pluginOptions,
13
- this.styles = pluginOptions.styles, this.filterStateManager.subscribe((state => {
14
- const filterState = state.filters.get(this.selectedField);
15
- filterState && "byValue" === filterState.type && this.updateUI(filterState);
16
- }));
17
- }
18
- updateUI(filterState) {
19
- this.syncCheckboxesWithFilterState(filterState), this.syncSelectAllWithFilterState(filterState);
11
+ this.selectedKeys = new Map, this.candidateKeys = new Map, this.formatFnCache = new Map,
12
+ this.toUnformattedCache = new Map, this.valueFilterOptionList = new Map, this.table = table,
13
+ this.filterStateManager = filterStateManager, this.pluginOptions = pluginOptions,
14
+ this.styles = pluginOptions.styles || {};
20
15
  }
21
16
  setSelectedField(fieldId) {
22
- this.selectedField = fieldId, this.collectUniqueColumnValues(fieldId);
17
+ this.selectedField = fieldId;
23
18
  }
24
- collectUniqueColumnValues(fieldId, forceCollect = !1) {
25
- var _a, _b, _c;
26
- if (this.uniqueKeys.has(fieldId) && !forceCollect) return;
27
- const displayToRawMap = new Map;
28
- let targetCol = -1;
29
- for (let col = 0; col < this.table.colCount; col++) {
30
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
31
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
32
- if (bodyInfo && bodyInfo.field === fieldId) {
33
- targetCol = col;
34
- break;
19
+ getFormatFnCache(fieldId) {
20
+ let formatFn = this.formatFnCache.get(fieldId);
21
+ if (null != formatFn) return formatFn;
22
+ const headerAddress = this.table.internalProps.layoutMap.getHeaderCellAddressByField(String(fieldId)), bodyInfo = this.table.internalProps.layoutMap.getBody(null == headerAddress ? void 0 : headerAddress.col, null == headerAddress ? void 0 : headerAddress.row);
23
+ return formatFn = bodyInfo && "fieldFormat" in bodyInfo && "function" == typeof bodyInfo.fieldFormat ? bodyInfo.fieldFormat : bodyInfo && "format" in bodyInfo && "function" == typeof bodyInfo.format ? bodyInfo.format : record => record[fieldId],
24
+ this.formatFnCache.set(fieldId, formatFn), formatFn;
25
+ }
26
+ collectCandidateKeysForUnfilteredColumn(fieldId) {
27
+ var _a, _b;
28
+ const syncFilterItemsState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncFilterItemsState) || void 0 === _b || _b, countMap = new Map;
29
+ let records = [];
30
+ records = syncFilterItemsState ? this.table.internalProps.dataSource.records : this.table.internalProps.records;
31
+ const formatFn = this.getFormatFnCache(fieldId), toUnformatted = new Map;
32
+ records.forEach((record => {
33
+ if ((0, vutils_1.isValid)(record)) {
34
+ const originalValue = record[fieldId], formattedValue = formatFn(record);
35
+ if (null != formattedValue) {
36
+ countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1);
37
+ const unformattedSet = toUnformatted.get(formattedValue);
38
+ null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
35
39
  }
36
40
  }
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);
41
+ })), this.candidateKeys.set(fieldId, countMap), this.toUnformattedCache.set(fieldId, toUnformatted);
61
42
  }
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;
43
+ collectCandidateKeysForFilteredColumn(candidateField) {
44
+ var _a, _b;
45
+ const syncFilterItemsState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncFilterItemsState) || void 0 === _b || _b, filteredFields = this.filterStateManager.getActiveFilterFields().filter((field => field !== candidateField)), toUnformatted = new Map, formatFn = this.getFormatFnCache(candidateField), countMap = new Map;
46
+ let records = [];
47
+ if (syncFilterItemsState) {
48
+ records = this.table.internalProps.records.filter((record => filteredFields.every((field => this.selectedKeys.get(field).has(record[field])))));
49
+ } else records = this.table.internalProps.records;
50
+ records.forEach((record => {
51
+ if ((0, vutils_1.isValid)(record)) {
52
+ const originalValue = record[candidateField], formattedValue = formatFn(record);
53
+ if (countMap.set(formattedValue, (countMap.get(formattedValue) || 0) + 1), null != formattedValue) {
54
+ const unformattedSet = toUnformatted.get(formattedValue);
55
+ null != unformattedSet ? unformattedSet.add(originalValue) : toUnformatted.set(formattedValue, new Set([ originalValue ]));
73
56
  }
74
57
  }
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
- }));
58
+ })), this.candidateKeys.set(candidateField, countMap), this.toUnformattedCache.set(candidateField, toUnformatted);
89
59
  }
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
- }
60
+ toggleSelectAll(fieldId, selected) {
61
+ this.valueFilterOptionList.get(fieldId).forEach((option => {
62
+ option.checkbox.checked = selected;
107
63
  }));
108
64
  }
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
- });
65
+ syncSelectAllCheckbox(fieldId) {
66
+ const options = this.valueFilterOptionList.get(fieldId) || [], allChecked = options.every((o => o.checkbox.checked)), noneChecked = options.every((o => !o.checkbox.checked));
67
+ this.selectAllCheckbox.checked = allChecked, this.selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
133
68
  }
134
69
  onSearch(fieldId, value) {
135
- this.filterStateManager.updateSearchKeyword(fieldId, value);
136
70
  const items = this.valueFilterOptionList.get(fieldId), filterKeywords = value.toUpperCase().split(" ").filter((s => s));
137
71
  for (const item of items) {
138
72
  const txtValue = item.id.toUpperCase() || "", match = filterKeywords.some((keyword => txtValue.includes(keyword))), isVisible = 0 === filterKeywords.length || match;
@@ -141,83 +75,64 @@ class ValueFilter {
141
75
  }
142
76
  initFilterStateFromTableData(fieldId) {
143
77
  var _a, _b, _c, _d;
144
- const filter = this.filterStateManager.getFilterState(fieldId), isEnable = null == filter ? void 0 : filter.enable, syncCheckboxCheckedState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncCheckboxCheckedState) || void 0 === _b || _b;
145
- if (isEnable) {
146
- const selectedRawValues = new Set, displayToRawMap = this.displayToRawValueMap.get(fieldId);
147
- let targetCol = -1;
148
- for (let col = 0; col < this.table.colCount; col++) {
149
- for (let row = this.table.columnHeaderLevelCount; row < this.table.rowCount; row++) if (!this.table.internalProps.layoutMap.isHeader(col, row)) {
150
- const bodyInfo = this.table.internalProps.layoutMap.getBody(col, row);
151
- if (bodyInfo && bodyInfo.field === fieldId) {
152
- targetCol = col;
153
- break;
154
- }
155
- }
156
- if (-1 !== targetCol) break;
157
- }
158
- const currentLength = this.table.internalProps.dataSource.length;
159
- for (let i = 0; i < currentLength; i++) {
160
- let displayValue, rawValue;
161
- if (-1 !== targetCol) {
162
- const row = this.table.columnHeaderLevelCount + i;
163
- row < this.table.rowCount && (displayValue = this.table.getCellValue(targetCol, row),
164
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue);
165
- } else displayValue = this.table.getFieldData(String(fieldId), -1 !== targetCol ? targetCol : 0, this.table.columnHeaderLevelCount + i),
166
- rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
167
- null != rawValue && selectedRawValues.add(rawValue);
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))) || [];
78
+ const isHasFilteredState = this.filterStateManager.getActiveFilterFields(), isValueFilter = "byValue" === (null === (_a = this.filterStateManager.getFilterState(fieldId)) || void 0 === _a ? void 0 : _a.type);
79
+ if (isHasFilteredState && isValueFilter) return;
80
+ const selectedValues = new Set, originalValues = new Set;
81
+ this.table.internalProps.records.forEach((record => {
82
+ (0, vutils_1.isValid)(record) && originalValues.add(record[fieldId]);
83
+ }));
84
+ if (null === (_c = null === (_b = this.pluginOptions) || void 0 === _b ? void 0 : _b.syncFilterItemsState) || void 0 === _c || _c) {
85
+ this.table.internalProps.dataSource.records.forEach((record => {
86
+ (0, vutils_1.isValid)(record) && selectedValues.add(record[fieldId]);
87
+ }));
88
+ !(0, vutils_1.arrayEqual)(Array.from(originalValues), Array.from(selectedValues)) && (this.selectedKeys.set(fieldId, selectedValues),
178
89
  this.filterStateManager.dispatch({
179
90
  type: types_1.FilterActionType.ADD_FILTER,
180
91
  payload: {
181
92
  field: fieldId,
182
93
  type: "byValue",
183
- values: availableRawValues,
184
- enable: !1
94
+ values: Array.from(selectedValues),
95
+ enable: !0
185
96
  }
186
- });
97
+ }));
98
+ } else {
99
+ const selectedRules = null === (_d = this.filterStateManager.getFilterState(fieldId)) || void 0 === _d ? void 0 : _d.values;
100
+ if (selectedRules) {
101
+ !(0, vutils_1.arrayEqual)(Array.from(originalValues), selectedRules) && (this.selectedKeys.set(fieldId, new Set(selectedRules)),
102
+ this.filterStateManager.dispatch({
103
+ type: types_1.FilterActionType.ADD_FILTER,
104
+ payload: {
105
+ field: fieldId,
106
+ type: "byValue",
107
+ values: selectedRules,
108
+ enable: !0,
109
+ shouldKeepUnrelatedState: !0
110
+ }
111
+ }));
112
+ } else this.selectedKeys.set(fieldId, originalValues);
187
113
  }
188
114
  }
189
- syncCheckboxesWithFilterState(filter) {
190
- if (!filter) return;
191
- const selectedRawValues = filter.values || [], displayToRawMap = this.displayToRawValueMap.get(filter.field), optionDomList = this.valueFilterOptionList.get(filter.field);
192
- null == optionDomList || optionDomList.forEach((optionDom => {
193
- const displayValue = optionDom.originalValue, rawValue = displayToRawMap ? displayToRawMap.get(displayValue) : displayValue;
194
- optionDom.checkbox.checked = selectedRawValues.some((v => v === rawValue));
195
- }));
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
- }
206
115
  applyFilter(fieldId = this.selectedField) {
207
- var _a;
208
- const allSelectedValues = this.filterStateManager.getFilterState(fieldId).values;
209
- allSelectedValues.length >= 0 && allSelectedValues.length < (null === (_a = this.uniqueKeys.get(fieldId)) || void 0 === _a ? void 0 : _a.length) ? this.filterStateManager.dispatch({
116
+ var _a, _b;
117
+ const options = this.valueFilterOptionList.get(fieldId);
118
+ if (!options || 0 === options.length) return;
119
+ const selections = options.map((option => option.checkbox.checked ? option.originalValue : null)).filter((key => null !== key)).flat();
120
+ this.selectedKeys.set(fieldId, new Set(selections));
121
+ const syncFilterItemsState = null === (_b = null === (_a = this.pluginOptions) || void 0 === _a ? void 0 : _a.syncFilterItemsState) || void 0 === _b || _b;
122
+ selections.length >= 0 && selections.length < this.valueFilterOptionList.get(fieldId).length || !syncFilterItemsState ? this.filterStateManager.dispatch({
210
123
  type: types_1.FilterActionType.APPLY_FILTERS,
211
124
  payload: {
212
125
  field: fieldId,
213
126
  type: "byValue",
214
- values: allSelectedValues,
215
- enable: !0
127
+ values: selections,
128
+ enable: !0,
129
+ shouldKeepUnrelatedState: !syncFilterItemsState
216
130
  }
217
131
  }) : this.filterStateManager.dispatch({
218
132
  type: types_1.FilterActionType.REMOVE_FILTER,
219
133
  payload: {
220
- field: fieldId
134
+ field: fieldId,
135
+ type: "byValue"
221
136
  }
222
137
  });
223
138
  }
@@ -231,25 +146,25 @@ class ValueFilter {
231
146
  }
232
147
  render(container) {
233
148
  var _a;
234
- this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, this.styles.filterPanel),
149
+ const filterStyles = this.styles;
150
+ this.filterByValuePanel = document.createElement("div"), (0, styles_1.applyStyles)(this.filterByValuePanel, filterStyles.filterPanel),
235
151
  this.searchContainer = document.createElement("div"), (0, styles_1.applyStyles)(this.searchContainer, this.styles.searchContainer),
236
152
  this.filterByValueSearchInput = document.createElement("input"), this.filterByValueSearchInput.type = "text",
237
- this.filterByValueSearchInput.placeholder = (null === (_a = this.styles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
238
- (0, styles_1.applyStyles)(this.filterByValueSearchInput, this.styles.searchInput),
153
+ this.filterByValueSearchInput.placeholder = (null === (_a = filterStyles.searchInput) || void 0 === _a ? void 0 : _a.placeholder) || "可使用空格分隔多个关键词",
154
+ (0, styles_1.applyStyles)(this.filterByValueSearchInput, filterStyles.searchInput),
239
155
  this.searchContainer.appendChild(this.filterByValueSearchInput), this.optionsContainer = document.createElement("div"),
240
156
  (0, styles_1.applyStyles)(this.optionsContainer, this.styles.optionsContainer),
241
157
  this.selectAllItemDiv = document.createElement("div"), (0, styles_1.applyStyles)(this.selectAllItemDiv, this.styles.optionItem),
242
158
  this.selectAllLabel = document.createElement("label"), (0, styles_1.applyStyles)(this.selectAllLabel, this.styles.optionLabel),
243
159
  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),
160
+ this.selectAllCheckbox.checked = !0, (0, styles_1.applyStyles)(this.selectAllCheckbox, filterStyles.checkbox),
161
+ this.totalCountSpan = document.createElement("span"), this.totalCountSpan.textContent = "",
162
+ (0, styles_1.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),
247
165
  this.filterByValuePanel.append(this.searchContainer, this.optionsContainer), container.appendChild(this.filterByValuePanel),
248
166
  this.bindEventForFilterByValue();
249
167
  }
250
- updatePluginOptions(pluginOptions) {
251
- this.pluginOptions = pluginOptions, this.styles = pluginOptions.styles, this.updateStyles(pluginOptions.styles);
252
- }
253
168
  updateStyles(styles) {
254
169
  var _a;
255
170
  (0, styles_1.applyStyles)(this.filterByValuePanel, styles.filterPanel), (0, styles_1.applyStyles)(this.searchContainer, styles.searchContainer),
@@ -259,68 +174,57 @@ class ValueFilter {
259
174
  (0, styles_1.applyStyles)(this.selectAllLabel, styles.optionLabel), (0, styles_1.applyStyles)(this.selectAllCheckbox, styles.checkbox);
260
175
  }
261
176
  renderFilterOptions(field) {
262
- var _a, _b;
177
+ var _a, _b, _c;
178
+ const filterStyles = this.styles;
263
179
  this.filterItemsContainer.innerHTML = "", this.valueFilterOptionList.delete(field),
264
180
  this.valueFilterOptionList.set(field, []);
265
- const selectedRawValues = (null === (_a = this.filterStateManager.getFilterState(field)) || void 0 === _a ? void 0 : _a.values) || [], selectedRawValueSet = new Set(selectedRawValues), itemDomList = [];
266
- null === (_b = this.uniqueKeys.get(field)) || void 0 === _b || _b.forEach((({value: value, count: count, rawValue: rawValue}) => {
267
- const itemDiv = document.createElement("div");
268
- (0, styles_1.applyStyles)(itemDiv, this.styles.optionItem), itemDiv.style.display = "flex";
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
+ (0, styles_1.applyStyles)(itemDiv, filterStyles.optionItem), itemDiv.style.display = "flex";
269
190
  const label = document.createElement("label");
270
- (0, styles_1.applyStyles)(label, this.styles.optionLabel);
191
+ (0, styles_1.applyStyles)(label, filterStyles.optionLabel);
271
192
  const checkbox = document.createElement("input");
272
- checkbox.type = "checkbox", checkbox.value = String(value), checkbox.checked = selectedRawValueSet.has(rawValue),
273
- (0, styles_1.applyStyles)(checkbox, this.styles.checkbox);
193
+ checkbox.type = "checkbox", checkbox.value = String(val), checkbox.checked = !isFiltered || unformattedArr.some((v => null == selectedKeysSet ? void 0 : selectedKeysSet.has(v))),
194
+ (0, styles_1.applyStyles)(checkbox, filterStyles.checkbox), checkbox.checked ? noneChecked = !1 : allChecked = !1;
274
195
  const countSpan = document.createElement("span");
275
- countSpan.textContent = String(count), (0, styles_1.applyStyles)(countSpan, this.styles.countSpan),
276
- label.append(checkbox, ` ${rawValue}`), itemDiv.append(label, countSpan), this.filterItemsContainer.appendChild(itemDiv);
196
+ countSpan.textContent = String(count), (0, styles_1.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);
277
199
  const itemDom = {
278
- id: String(value),
279
- originalValue: value,
200
+ id: String(val),
201
+ originalValue: unformattedArr,
280
202
  itemContainer: itemDiv,
281
203
  checkbox: checkbox,
282
204
  countSpan: countSpan
283
205
  };
284
206
  itemDomList.push(itemDom);
285
- })), 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);
286
209
  }
287
210
  bindEventForFilterByValue() {
288
- this.filterByValuePanel.addEventListener("keyup", (event => {
211
+ this._onInputKeyUpHandler = event => {
289
212
  const target = event.target;
290
213
  if (target instanceof HTMLInputElement && "text" === target.type) {
291
214
  const value = target.value;
292
215
  this.onSearch(this.selectedField, value);
293
216
  }
294
- })), this.filterByValuePanel.addEventListener("change", (event => {
217
+ }, this._onCheckboxChangeHandler = event => {
295
218
  const target = event.target;
296
- target instanceof HTMLInputElement && "checkbox" === target.type && (target === this.selectAllCheckbox ? this.valueFilterOptionList.get(this.selectedField).forEach((item => item.checkbox.checked = target.checked)) : this.updateCheckboxUI(this.selectedField));
297
- }));
298
- }
299
- updateCheckboxUI(field) {
300
- var _a, _b;
301
- const checkedItem = null === (_a = this.valueFilterOptionList.get(field)) || void 0 === _a ? void 0 : _a.filter((item => item.checkbox.checked)), uncheckedItem = null === (_b = this.valueFilterOptionList.get(field)) || void 0 === _b ? void 0 : _b.filter((item => !item.checkbox.checked));
302
- (0, vutils_1.isValid)(checkedItem) && (0, vutils_1.isValid)(uncheckedItem) && (0 !== checkedItem.length && 0 !== uncheckedItem.length ? this.selectAllCheckbox.indeterminate = !0 : (this.selectAllCheckbox.indeterminate = !1,
303
- this.selectAllCheckbox.checked = 0 === uncheckedItem.length));
304
- }
305
- updateCheckboxState(field) {
306
- var _a;
307
- const originalValues = null === (_a = this.valueFilterOptionList.get(field)) || void 0 === _a ? void 0 : _a.filter((item => item.checkbox.checked)).map((item => item.originalValue)), displayToRawMap = this.displayToRawValueMap.get(field), rawValues = originalValues.map((displayValue => displayToRawMap ? displayToRawMap.get(displayValue) : displayValue));
308
- this.filterStateManager.dispatch({
309
- type: types_1.FilterActionType.ADD_FILTER,
310
- payload: {
311
- field: field,
312
- type: "byValue",
313
- values: rawValues
314
- }
315
- });
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);
316
222
  }
317
223
  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";
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";
324
228
  }
325
229
  hide() {
326
230
  this.filterByValuePanel.style.display = "none";
@@ -328,6 +232,20 @@ class ValueFilter {
328
232
  clearSearchInputValue() {
329
233
  this.filterByValueSearchInput.value = "";
330
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
+ }
331
249
  }
332
250
 
333
251
  exports.ValueFilter = ValueFilter;