@xh/hoist 71.0.0-SNAPSHOT.1735236372248 → 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.
- package/build/types/cmp/grid/GridModel.d.ts +1 -1
- package/build/types/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.d.ts +6 -31
- package/build/types/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.d.ts +7 -0
- package/build/types/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.d.ts +32 -0
- package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRowModel.d.ts +3 -3
- package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTabModel.d.ts +4 -4
- package/build/types/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTabModel.d.ts +3 -3
- package/cmp/grid/GridModel.ts +5 -1
- package/cmp/grid/impl/ColumnHeader.ts +1 -4
- package/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts +6 -75
- package/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts +12 -160
- package/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.ts +88 -0
- package/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.ts +181 -0
- package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRowModel.ts +2 -2
- package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTabModel.ts +3 -3
- package/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTabModel.ts +7 -6
- package/desktop/cmp/viewmanager/dialog/ManageDialogModel.ts +0 -6
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- /package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRow.d.ts +0 -0
- /package/build/types/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.d.ts +0 -0
- /package/build/types/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTab.d.ts +0 -0
- /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomRow.ts +0 -0
- /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.scss +0 -0
- /package/desktop/cmp/grid/impl/filter/{custom → headerfilter/custom}/CustomTab.ts +0 -0
- /package/desktop/cmp/grid/impl/filter/{values → headerfilter/values}/ValuesTab.scss +0 -0
- /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 {
|
|
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:
|
|
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 {
|
|
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:
|
|
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:
|
|
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 {
|
|
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:
|
|
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.
|
|
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:
|
|
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: {
|
|
@@ -263,12 +263,6 @@ export class ManageDialogModel extends HoistModel {
|
|
|
263
263
|
sortBy: 'name',
|
|
264
264
|
showGroupRowCounts: false,
|
|
265
265
|
groupBy: ['group'],
|
|
266
|
-
groupSortFn: (a, b) => {
|
|
267
|
-
// Place ungrouped items at bottom.
|
|
268
|
-
if (a == '') return 1;
|
|
269
|
-
if (b == '') return -1;
|
|
270
|
-
return a.localeCompare(b);
|
|
271
|
-
},
|
|
272
266
|
selModel: 'multiple',
|
|
273
267
|
contextMenu: null,
|
|
274
268
|
sizingMode: 'standard',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "71.0.0-SNAPSHOT.
|
|
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",
|