@xh/hoist 71.0.0-SNAPSHOT.1735247152243 → 71.0.0-SNAPSHOT.1735310060928

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 (24) hide show
  1. package/build/types/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.d.ts +6 -31
  2. package/build/types/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.d.ts +7 -0
  3. package/build/types/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.d.ts +32 -0
  4. package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRowModel.d.ts +3 -3
  5. package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTabModel.d.ts +4 -4
  6. package/build/types/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTabModel.d.ts +3 -3
  7. package/cmp/grid/impl/ColumnHeader.ts +1 -4
  8. package/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts +6 -75
  9. package/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts +12 -160
  10. package/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.ts +88 -0
  11. package/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.ts +181 -0
  12. package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRowModel.ts +2 -2
  13. package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTabModel.ts +3 -3
  14. package/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTabModel.ts +7 -6
  15. package/package.json +1 -1
  16. package/tsconfig.tsbuildinfo +1 -1
  17. /package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRow.d.ts +0 -0
  18. /package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.d.ts +0 -0
  19. /package/build/types/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTab.d.ts +0 -0
  20. /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRow.ts +0 -0
  21. /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.scss +0 -0
  22. /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.ts +0 -0
  23. /package/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTab.scss +0 -0
  24. /package/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTab.ts +0 -0
@@ -0,0 +1,181 @@
1
+ /*
2
+ * This file belongs to Hoist, an application development toolkit
3
+ * developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
4
+ *
5
+ * Copyright © 2024 Extremely Heavy Industries Inc.
6
+ */
7
+
8
+ import {TabContainerModel} from '@xh/hoist/cmp/tab';
9
+ import {HoistModel, managed, lookup} from '@xh/hoist/core';
10
+ import {action, computed} from '@xh/hoist/mobx';
11
+ import {wait} from '@xh/hoist/promise';
12
+ import {isEmpty} from 'lodash';
13
+ import {GridFilterFieldSpec} from '@xh/hoist/cmp/grid';
14
+ import {customTab} from './custom/CustomTab';
15
+ import {CustomTabModel} from './custom/CustomTabModel';
16
+ import {valuesTab} from './values/ValuesTab';
17
+ import {ValuesTabModel} from './values/ValuesTabModel';
18
+ import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel';
19
+
20
+ export class HeaderFilterModel extends HoistModel {
21
+ override xhImpl = true;
22
+
23
+ fieldSpec: GridFilterFieldSpec;
24
+
25
+ @lookup(ColumnHeaderFilterModel)
26
+ parent: ColumnHeaderFilterModel;
27
+
28
+ @managed tabContainerModel: TabContainerModel;
29
+ @managed valuesTabModel: ValuesTabModel;
30
+ @managed customTabModel: CustomTabModel;
31
+
32
+ get filterModel() {
33
+ return this.parent.filterModel;
34
+ }
35
+
36
+ get field() {
37
+ return this.fieldSpec.field;
38
+ }
39
+
40
+ get store() {
41
+ return this.filterModel.gridModel.store;
42
+ }
43
+
44
+ get fieldType() {
45
+ return this.store.getField(this.field).type;
46
+ }
47
+
48
+ get currentGridFilter() {
49
+ return this.filterModel.filter;
50
+ }
51
+
52
+ get columnFilters() {
53
+ return this.filterModel.getColumnFilters(this.field);
54
+ }
55
+
56
+ get columnCompoundFilter() {
57
+ return this.filterModel.getColumnCompoundFilter(this.field);
58
+ }
59
+
60
+ get hasFilter() {
61
+ return !isEmpty(this.columnFilters);
62
+ }
63
+
64
+ get hasPendingFilter() {
65
+ const {activeTabId} = this.tabContainerModel;
66
+ return activeTabId === 'valuesFilter'
67
+ ? !!this.valuesTabModel.filter
68
+ : !!this.customTabModel.filter;
69
+ }
70
+
71
+ @computed
72
+ get isCustomFilter() {
73
+ const {columnCompoundFilter, columnFilters} = this;
74
+ if (columnCompoundFilter) return true;
75
+ if (isEmpty(columnFilters)) return false;
76
+ return columnFilters.some(it => !['=', '!=', 'includes'].includes(it.op));
77
+ }
78
+
79
+ get commitOnChange() {
80
+ return this.filterModel.commitOnChange;
81
+ }
82
+
83
+ override onLinked() {
84
+ super.onLinked();
85
+ this.fieldSpec = this.filterModel.getFieldSpec(this.parent.column.field);
86
+
87
+ const {enableValues} = this.fieldSpec;
88
+ this.valuesTabModel = enableValues ? new ValuesTabModel(this) : null;
89
+ this.customTabModel = new CustomTabModel(this);
90
+ this.tabContainerModel = new TabContainerModel({
91
+ switcher: false,
92
+ tabs: [
93
+ {
94
+ id: 'valuesFilter',
95
+ title: 'Values',
96
+ content: valuesTab,
97
+ omit: !enableValues
98
+ },
99
+ {
100
+ id: 'customFilter',
101
+ title: 'Custom',
102
+ content: customTab
103
+ }
104
+ ],
105
+ xhImpl: true
106
+ });
107
+
108
+ this.addReaction({
109
+ track: () => this.valuesTabModel?.filter,
110
+ run: () => this.doCommitOnChange('valuesFilter'),
111
+ debounce: 100
112
+ });
113
+
114
+ this.addReaction({
115
+ track: () => this.customTabModel.filter,
116
+ run: () => this.doCommitOnChange('customFilter'),
117
+ debounce: 100
118
+ });
119
+
120
+ this.syncWithFilter();
121
+ }
122
+
123
+ @action
124
+ commit(close: boolean = true) {
125
+ const {tabContainerModel, customTabModel, valuesTabModel} = this,
126
+ {activeTabId} = tabContainerModel,
127
+ valuesIsActive = activeTabId === 'valuesFilter',
128
+ activeTabModel = valuesIsActive ? valuesTabModel : customTabModel,
129
+ otherTabModel = valuesIsActive ? customTabModel : valuesTabModel;
130
+
131
+ this.setColumnFilters(activeTabModel.filter);
132
+ if (close) {
133
+ this.parent.close();
134
+ } else {
135
+ // We must wait before resetting as GridFilterModel.setFilter() is async
136
+ wait().then(() => otherTabModel?.reset());
137
+ }
138
+ }
139
+
140
+ @action
141
+ clear(close: boolean = true) {
142
+ this.setColumnFilters(null);
143
+ if (close) {
144
+ this.parent.close();
145
+ } else {
146
+ // We must wait before resetting as GridFilterModel.setFilter() is async
147
+ wait().then(() => this.resetTabModels());
148
+ }
149
+ }
150
+
151
+ //-------------------
152
+ // Implementation
153
+ //-------------------
154
+ @action
155
+ private syncWithFilter() {
156
+ const {isCustomFilter, valuesTabModel, customTabModel, tabContainerModel} = this,
157
+ useCustomTab = isCustomFilter || !valuesTabModel,
158
+ toTab = useCustomTab ? customTabModel : valuesTabModel,
159
+ toTabId = useCustomTab ? 'customFilter' : 'valuesFilter';
160
+
161
+ this.resetTabModels();
162
+ toTab.syncWithFilter();
163
+
164
+ tabContainerModel.activateTab(toTabId);
165
+ }
166
+
167
+ private setColumnFilters(filters) {
168
+ this.filterModel.setColumnFilters(this.field, filters);
169
+ }
170
+
171
+ private doCommitOnChange(tab) {
172
+ if (!this.commitOnChange) return;
173
+ if (this.tabContainerModel.activeTabId !== tab) return;
174
+ this.commit(false);
175
+ }
176
+
177
+ private resetTabModels() {
178
+ this.customTabModel.reset();
179
+ this.valuesTabModel?.reset();
180
+ }
181
+ }
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import {HoistModel} from '@xh/hoist/core';
8
8
  import {FieldFilterOperator, FieldFilterSpec} from '@xh/hoist/data';
9
- import {ColumnHeaderFilterModel} from '@xh/hoist/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel';
9
+ import {HeaderFilterModel} from '../HeaderFilterModel';
10
10
  import {bindable, computed, makeObservable} from '@xh/hoist/mobx';
11
11
  import {isArray, isNil} from 'lodash';
12
12
  import {CustomTabModel} from './CustomTabModel';
@@ -20,7 +20,7 @@ export class CustomRowModel extends HoistModel {
20
20
  override xhImpl = true;
21
21
 
22
22
  parentModel: CustomTabModel;
23
- headerFilterModel: ColumnHeaderFilterModel;
23
+ headerFilterModel: HeaderFilterModel;
24
24
 
25
25
  @bindable op: OperatorOptionValue;
26
26
  @bindable inputVal: any;
@@ -8,14 +8,14 @@ import {HoistModel, XH} from '@xh/hoist/core';
8
8
  import {CompoundFilterOperator, FilterLike} from '@xh/hoist/data';
9
9
  import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx';
10
10
  import {compact, isEmpty} from 'lodash';
11
- import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel';
11
+ import {HeaderFilterModel} from '../HeaderFilterModel';
12
12
 
13
13
  import {CustomRowModel} from './CustomRowModel';
14
14
 
15
15
  export class CustomTabModel extends HoistModel {
16
16
  override xhImpl = true;
17
17
 
18
- headerFilterModel: ColumnHeaderFilterModel;
18
+ headerFilterModel: HeaderFilterModel;
19
19
 
20
20
  @bindable op: CompoundFilterOperator = 'AND';
21
21
  @observable.ref rowModels: CustomRowModel[] = [];
@@ -42,7 +42,7 @@ export class CustomTabModel extends HoistModel {
42
42
  return this.headerFilterModel.columnFilters;
43
43
  }
44
44
 
45
- constructor(headerFilterModel: ColumnHeaderFilterModel) {
45
+ constructor(headerFilterModel: HeaderFilterModel) {
46
46
  super();
47
47
  makeObservable(this);
48
48
  this.headerFilterModel = headerFilterModel;
@@ -7,7 +7,7 @@
7
7
  import {GridFilterModel, GridModel} from '@xh/hoist/cmp/grid';
8
8
  import {HoistModel, managed} from '@xh/hoist/core';
9
9
  import {FieldFilterSpec} from '@xh/hoist/data';
10
- import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel';
10
+ import {HeaderFilterModel} from '../HeaderFilterModel';
11
11
  import {checkbox} from '@xh/hoist/desktop/cmp/input';
12
12
  import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx';
13
13
  import {castArray, difference, isEmpty, partition, uniq, without} from 'lodash';
@@ -15,7 +15,7 @@ import {castArray, difference, isEmpty, partition, uniq, without} from 'lodash';
15
15
  export class ValuesTabModel extends HoistModel {
16
16
  override xhImpl = true;
17
17
 
18
- headerFilterModel: ColumnHeaderFilterModel;
18
+ headerFilterModel: HeaderFilterModel;
19
19
 
20
20
  /** Checkbox grid to display enumerated set of values */
21
21
  @managed @observable.ref gridModel: GridModel;
@@ -59,7 +59,7 @@ export class ValuesTabModel extends HoistModel {
59
59
  }
60
60
 
61
61
  get gridFilterModel() {
62
- return this.headerFilterModel.gridFilterModel;
62
+ return this.headerFilterModel.filterModel;
63
63
  }
64
64
 
65
65
  get values() {
@@ -74,7 +74,7 @@ export class ValuesTabModel extends HoistModel {
74
74
  return this.values.length < this.valueCount;
75
75
  }
76
76
 
77
- constructor(headerFilterModel: ColumnHeaderFilterModel) {
77
+ constructor(headerFilterModel: HeaderFilterModel) {
78
78
  super();
79
79
  makeObservable(this);
80
80
 
@@ -83,7 +83,8 @@ export class ValuesTabModel extends HoistModel {
83
83
 
84
84
  this.addReaction({
85
85
  track: () => this.pendingValues,
86
- run: () => this.syncGrid()
86
+ run: () => this.syncGrid(),
87
+ fireImmediately: true
87
88
  });
88
89
  }
89
90
 
@@ -193,7 +194,7 @@ export class ValuesTabModel extends HoistModel {
193
194
  {fieldType} = headerFilterModel,
194
195
  renderer =
195
196
  fieldSpec.renderer ??
196
- (fieldType !== 'tags' ? this.headerFilterModel.column.renderer : null);
197
+ (fieldType !== 'tags' ? this.headerFilterModel.parent.column.renderer : null);
197
198
 
198
199
  return new GridModel({
199
200
  store: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "71.0.0-SNAPSHOT.1735247152243",
3
+ "version": "71.0.0-SNAPSHOT.1735310060928",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": "github:xh/hoist-react",
6
6
  "homepage": "https://xh.io",