@xh/hoist 74.1.2 → 75.0.0-SNAPSHOT.1749666833237
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/CHANGELOG.md +5 -41
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +4 -8
- package/build/types/cmp/viewmanager/ViewInfo.d.ts +3 -7
- package/build/types/core/types/Interfaces.d.ts +1 -1
- package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +6 -17
- package/build/types/desktop/cmp/panel/Panel.d.ts +1 -1
- package/build/types/desktop/cmp/viewmanager/ViewManager.d.ts +10 -26
- package/build/types/mobile/cmp/grouping/GroupingChooser.d.ts +6 -2
- package/build/types/utils/impl/index.d.ts +0 -1
- package/cmp/grouping/GroupingChooserModel.ts +12 -25
- package/cmp/viewmanager/ViewInfo.ts +3 -7
- package/core/HoistAppModel.ts +0 -1
- package/core/exception/ExceptionHandler.ts +1 -1
- package/core/types/Interfaces.ts +2 -2
- package/desktop/cmp/button/AppMenuButton.ts +46 -3
- package/desktop/cmp/grouping/GroupingChooser.scss +40 -45
- package/desktop/cmp/grouping/GroupingChooser.ts +89 -159
- package/desktop/cmp/panel/Panel.ts +1 -1
- package/desktop/cmp/viewmanager/ViewManager.ts +16 -58
- package/desktop/cmp/viewmanager/ViewMenu.ts +2 -9
- package/mobile/appcontainer/FeedbackDialog.ts +0 -4
- package/mobile/appcontainer/OptionsDialog.ts +1 -3
- package/mobile/cmp/grid/impl/ColChooser.ts +2 -3
- package/mobile/cmp/grouping/GroupingChooser.scss +20 -41
- package/mobile/cmp/grouping/GroupingChooser.ts +89 -60
- package/mobile/cmp/panel/DialogPanel.scss +0 -5
- package/package.json +1 -1
- package/svc/TrackService.ts +3 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/utils/impl/index.ts +0 -1
- package/utils/js/LangUtils.ts +1 -1
- package/build/types/utils/impl/MenuItems.d.ts +0 -13
- package/utils/impl/MenuItems.ts +0 -57
|
@@ -16,23 +16,18 @@
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
&__editor {
|
|
20
|
-
.xh-panel__content {
|
|
21
|
-
padding: var(--xh-pad-px);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
19
|
&__row {
|
|
26
20
|
display: flex;
|
|
27
21
|
align-items: center;
|
|
28
22
|
background-color: var(--xh-bg);
|
|
29
|
-
height:
|
|
23
|
+
height: 35px;
|
|
30
24
|
flex-shrink: 0;
|
|
31
25
|
|
|
32
26
|
&__grabber {
|
|
33
27
|
display: flex;
|
|
34
28
|
align-items: center;
|
|
35
29
|
justify-content: center;
|
|
30
|
+
height: 30px;
|
|
36
31
|
width: 30px;
|
|
37
32
|
}
|
|
38
33
|
|
|
@@ -54,46 +49,30 @@
|
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
&__add-control {
|
|
57
|
-
|
|
58
|
-
padding: 5px 40px 5px 30px;
|
|
52
|
+
padding: var(--xh-pad-half-px);
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
&
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
height: 50%;
|
|
65
|
-
|
|
66
|
-
// Section heading style for internal title (like colChooser)
|
|
67
|
-
.xh-panel-header {
|
|
68
|
-
background-color: var(--xh-appbar-bg);
|
|
69
|
-
color: var(--xh-appbar-title-color);
|
|
70
|
-
padding-left: var(--xh-pad-px);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.xh-panel__content {
|
|
74
|
-
padding: var(--xh-pad-px);
|
|
75
|
-
}
|
|
55
|
+
&__favorite {
|
|
56
|
+
height: 35px;
|
|
57
|
+
align-items: center;
|
|
76
58
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
flex: none;
|
|
80
|
-
margin: var(--xh-pad-px);
|
|
59
|
+
.xh-button {
|
|
60
|
+
justify-content: left;
|
|
81
61
|
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
align-items: center;
|
|
65
|
+
.xh-grouping-chooser-popover {
|
|
66
|
+
.dialog {
|
|
67
|
+
min-width: unset;
|
|
68
|
+
}
|
|
88
69
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
70
|
+
.xh-dialog__inner {
|
|
71
|
+
padding: 0;
|
|
72
|
+
}
|
|
93
73
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
74
|
+
&__content {
|
|
75
|
+
padding: 3px var(--xh-pad-half-px);
|
|
76
|
+
min-width: 240px; // Required to allow for toolbars
|
|
98
77
|
}
|
|
99
78
|
}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {GroupingChooserModel} from '@xh/hoist/cmp/grouping';
|
|
8
|
-
import {box, div, filler, hbox, placeholder, span} from '@xh/hoist/cmp/layout';
|
|
8
|
+
import {box, div, filler, hbox, placeholder, span, vbox, vframe} from '@xh/hoist/cmp/layout';
|
|
9
9
|
import {hoistCmp, uses} from '@xh/hoist/core';
|
|
10
10
|
import {Icon} from '@xh/hoist/icon';
|
|
11
11
|
import {dragDropContext, draggable, droppable} from '@xh/hoist/kit/react-beautiful-dnd';
|
|
12
12
|
import {button, ButtonProps} from '@xh/hoist/mobile/cmp/button';
|
|
13
|
+
import {dialog} from '@xh/hoist/mobile/cmp/dialog';
|
|
13
14
|
import {select} from '@xh/hoist/mobile/cmp/input';
|
|
14
15
|
import '@xh/hoist/mobile/register';
|
|
15
|
-
import {dialogPanel, panel} from '@xh/hoist/mobile/cmp/panel';
|
|
16
16
|
import {splitLayoutProps} from '@xh/hoist/utils/react';
|
|
17
17
|
import classNames from 'classnames';
|
|
18
18
|
import {compact, isEmpty, sortBy} from 'lodash';
|
|
@@ -20,10 +20,14 @@ import {compact, isEmpty, sortBy} from 'lodash';
|
|
|
20
20
|
import './GroupingChooser.scss';
|
|
21
21
|
|
|
22
22
|
export interface GroupingChooserProps extends ButtonProps<GroupingChooserModel> {
|
|
23
|
-
/** Custom title for editor dialog, or null to suppress. */
|
|
24
|
-
dialogTitle?: string;
|
|
25
23
|
/** Text to represent empty state (i.e. value = null or [])*/
|
|
26
24
|
emptyText?: string;
|
|
25
|
+
/** Title for popover (default "GROUP BY") or null to suppress. */
|
|
26
|
+
popoverTitle?: string;
|
|
27
|
+
/** Min height in pixels of the popover inner content (excl. header & toolbar). */
|
|
28
|
+
popoverMinHeight?: number;
|
|
29
|
+
/** Width in pixels of the popover menu itself. */
|
|
30
|
+
popoverWidth?: number;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
/**
|
|
@@ -36,7 +40,15 @@ export const [GroupingChooser, groupingChooser] = hoistCmp.withFactory<GroupingC
|
|
|
36
40
|
className: 'xh-grouping-chooser',
|
|
37
41
|
|
|
38
42
|
render(
|
|
39
|
-
{
|
|
43
|
+
{
|
|
44
|
+
model,
|
|
45
|
+
className,
|
|
46
|
+
emptyText = 'Ungrouped',
|
|
47
|
+
popoverWidth = 270,
|
|
48
|
+
popoverMinHeight,
|
|
49
|
+
popoverTitle = 'Group By',
|
|
50
|
+
...rest
|
|
51
|
+
},
|
|
40
52
|
ref
|
|
41
53
|
) {
|
|
42
54
|
const {value, allowEmpty} = model,
|
|
@@ -48,55 +60,74 @@ export const [GroupingChooser, groupingChooser] = hoistCmp.withFactory<GroupingC
|
|
|
48
60
|
className,
|
|
49
61
|
...layoutProps,
|
|
50
62
|
items: [
|
|
63
|
+
popoverCmp({popoverTitle, popoverWidth, popoverMinHeight, emptyText}),
|
|
51
64
|
button({
|
|
52
65
|
className: 'xh-grouping-chooser-button',
|
|
53
66
|
item: span(label),
|
|
54
67
|
...buttonProps,
|
|
55
68
|
onClick: () => model.toggleEditor()
|
|
56
69
|
}),
|
|
57
|
-
|
|
70
|
+
favoritesButton()
|
|
58
71
|
]
|
|
59
72
|
});
|
|
60
73
|
}
|
|
61
74
|
});
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
//---------------------------
|
|
77
|
+
// Popover
|
|
78
|
+
//---------------------------
|
|
79
|
+
const popoverCmp = hoistCmp.factory<GroupingChooserModel>(
|
|
80
|
+
({model, popoverTitle, popoverWidth, popoverMinHeight, emptyText}) => {
|
|
81
|
+
const {editorIsOpen, favoritesIsOpen, isValid, value} = model,
|
|
82
|
+
isOpen = editorIsOpen || favoritesIsOpen,
|
|
83
|
+
addFavoriteDisabled = isEmpty(value) || !!model.isFavorite(value);
|
|
84
|
+
|
|
85
|
+
return dialog({
|
|
86
|
+
isOpen,
|
|
87
|
+
title: favoritesIsOpen ? 'Favorites' : popoverTitle,
|
|
88
|
+
icon: favoritesIsOpen ? Icon.favorite({prefix: 'fas'}) : Icon.treeList(),
|
|
89
|
+
className: 'xh-grouping-chooser-popover',
|
|
90
|
+
content: vframe({
|
|
91
|
+
className: 'xh-grouping-chooser-popover__content',
|
|
92
|
+
width: popoverWidth,
|
|
93
|
+
minHeight: popoverMinHeight,
|
|
94
|
+
item: favoritesIsOpen ? favoritesMenu() : editor({emptyText})
|
|
95
|
+
}),
|
|
96
|
+
onCancel: () => model.closePopover(),
|
|
97
|
+
buttons: favoritesIsOpen
|
|
98
|
+
? [
|
|
99
|
+
button({
|
|
100
|
+
icon: Icon.add(),
|
|
101
|
+
flex: 1,
|
|
102
|
+
text: 'Add current',
|
|
103
|
+
disabled: addFavoriteDisabled,
|
|
104
|
+
onClick: () => model.addFavorite(model.value)
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
: [
|
|
108
|
+
filler(),
|
|
109
|
+
button({
|
|
110
|
+
text: 'Cancel',
|
|
111
|
+
minimal: true,
|
|
112
|
+
onClick: () => model.closePopover()
|
|
113
|
+
}),
|
|
114
|
+
button({
|
|
115
|
+
icon: Icon.check(),
|
|
116
|
+
text: 'Apply',
|
|
117
|
+
disabled: !isValid,
|
|
118
|
+
onClick: () => model.commitPendingValueAndClose()
|
|
119
|
+
})
|
|
120
|
+
]
|
|
86
121
|
});
|
|
87
122
|
}
|
|
88
|
-
|
|
123
|
+
);
|
|
89
124
|
|
|
90
125
|
//------------------
|
|
91
126
|
// Editor
|
|
92
127
|
//------------------
|
|
93
128
|
const editor = hoistCmp.factory({
|
|
94
129
|
render({emptyText}) {
|
|
95
|
-
return
|
|
96
|
-
className: 'xh-grouping-chooser__editor',
|
|
97
|
-
scrollable: true,
|
|
98
|
-
items: [dimensionList({emptyText}), addDimensionControl()]
|
|
99
|
-
});
|
|
130
|
+
return vbox(dimensionList({emptyText}), addDimensionControl());
|
|
100
131
|
}
|
|
101
132
|
});
|
|
102
133
|
|
|
@@ -191,7 +222,7 @@ const addDimensionControl = hoistCmp.factory<GroupingChooserModel>({
|
|
|
191
222
|
// ensure the Select loses its internal input state.
|
|
192
223
|
key: JSON.stringify(options),
|
|
193
224
|
options,
|
|
194
|
-
placeholder: 'Add
|
|
225
|
+
placeholder: 'Add...',
|
|
195
226
|
flex: 1,
|
|
196
227
|
width: null,
|
|
197
228
|
hideDropdownIndicator: true,
|
|
@@ -216,37 +247,35 @@ function getDimOptions(dims, model) {
|
|
|
216
247
|
//------------------
|
|
217
248
|
// Favorites
|
|
218
249
|
//------------------
|
|
219
|
-
const
|
|
250
|
+
const favoritesButton = hoistCmp.factory<GroupingChooserModel>({
|
|
220
251
|
render({model}) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
? [placeholder('No favorites saved.')]
|
|
224
|
-
: options.map(it => favoriteItem(it));
|
|
225
|
-
|
|
226
|
-
return panel({
|
|
227
|
-
title: 'Favorites',
|
|
252
|
+
if (!model.persistFavorites) return null;
|
|
253
|
+
return button({
|
|
228
254
|
icon: Icon.favorite(),
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
...items,
|
|
233
|
-
button({
|
|
234
|
-
text: 'Add current',
|
|
235
|
-
icon: Icon.add({intent: 'success'}),
|
|
236
|
-
className: 'xh-grouping-chooser__favorites__add-btn',
|
|
237
|
-
outlined: true,
|
|
238
|
-
omit: !isAddFavoriteEnabled,
|
|
239
|
-
onClick: () => model.addPendingAsFavorite()
|
|
240
|
-
})
|
|
241
|
-
]
|
|
255
|
+
minimal: true,
|
|
256
|
+
className: 'xh-grouping-chooser__favorite-button',
|
|
257
|
+
onClick: () => model.toggleFavoritesMenu()
|
|
242
258
|
});
|
|
243
259
|
}
|
|
244
260
|
});
|
|
245
261
|
|
|
246
|
-
const
|
|
262
|
+
const favoritesMenu = hoistCmp.factory<GroupingChooserModel>({
|
|
263
|
+
render({model}) {
|
|
264
|
+
const options = model.favoritesOptions;
|
|
265
|
+
|
|
266
|
+
if (isEmpty(options)) {
|
|
267
|
+
return placeholder('No favorites saved...');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const items = options.map(it => favoriteMenuItem(it));
|
|
271
|
+
return div({items});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const favoriteMenuItem = hoistCmp.factory<GroupingChooserModel>({
|
|
247
276
|
render({model, value, label}) {
|
|
248
277
|
return hbox({
|
|
249
|
-
className: 'xh-grouping-
|
|
278
|
+
className: 'xh-grouping-chooser__favorite',
|
|
250
279
|
items: [
|
|
251
280
|
button({
|
|
252
281
|
text: label,
|
|
@@ -254,7 +283,7 @@ const favoriteItem = hoistCmp.factory<GroupingChooserModel>({
|
|
|
254
283
|
flex: 1,
|
|
255
284
|
onClick: () => {
|
|
256
285
|
model.setValue(value);
|
|
257
|
-
model.
|
|
286
|
+
model.closePopover();
|
|
258
287
|
}
|
|
259
288
|
}),
|
|
260
289
|
button({
|
package/package.json
CHANGED
package/svc/TrackService.ts
CHANGED
|
@@ -132,11 +132,10 @@ export class TrackService extends HoistService {
|
|
|
132
132
|
if (options.logData !== undefined) ret.logData = options.logData;
|
|
133
133
|
if (options.elapsed !== undefined) ret.elapsed = options.elapsed;
|
|
134
134
|
|
|
135
|
-
const {maxDataLength} = this.conf
|
|
136
|
-
|
|
137
|
-
if (dataLength > maxDataLength) {
|
|
135
|
+
const {maxDataLength} = this.conf;
|
|
136
|
+
if (ret.data?.length > maxDataLength) {
|
|
138
137
|
this.logWarn(
|
|
139
|
-
`Track log includes ${
|
|
138
|
+
`Track log includes ${ret.data.length} chars of JSON data`,
|
|
140
139
|
`exceeds limit of ${maxDataLength}`,
|
|
141
140
|
'data will not be persisted',
|
|
142
141
|
options.data
|