@xh/hoist 75.0.0-SNAPSHOT.1752777363110 → 75.0.0-SNAPSHOT.1752860174147
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 +6 -0
- package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +2 -0
- package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +1 -4
- package/admin/tabs/cluster/objects/ClusterObjectsModel.ts +1 -0
- package/admin/tabs/cluster/objects/ClusterObjectsPanel.ts +1 -1
- package/build/types/cmp/grid/GridContextMenu.d.ts +2 -2
- package/build/types/cmp/grid/GridModel.d.ts +24 -3
- package/build/types/cmp/grid/Types.d.ts +2 -0
- package/build/types/cmp/grid/impl/InitPersist.d.ts +1 -1
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +1 -0
- package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +9 -1
- package/build/types/core/exception/ExceptionHandler.d.ts +8 -4
- package/build/types/data/RecordAction.d.ts +2 -7
- package/cmp/grid/Grid.ts +1 -2
- package/cmp/grid/GridContextMenu.ts +2 -1
- package/cmp/grid/GridModel.ts +60 -23
- package/cmp/grid/Types.ts +2 -0
- package/cmp/grid/impl/InitPersist.ts +18 -0
- package/cmp/grid/impl/MenuSupport.ts +54 -15
- package/cmp/grouping/GroupingChooserModel.ts +4 -0
- package/cmp/zoneGrid/ZoneGridModel.ts +12 -1
- package/core/exception/Exception.ts +6 -1
- package/core/exception/ExceptionHandler.ts +12 -13
- package/data/RecordAction.ts +2 -7
- package/desktop/cmp/leftrightchooser/LeftRightChooser.ts +9 -17
- package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +2 -0
- package/package.json +1 -1
- package/promise/Promise.ts +12 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
managed,
|
|
40
40
|
PlainObject,
|
|
41
41
|
Some,
|
|
42
|
+
Thunkable,
|
|
42
43
|
VSide,
|
|
43
44
|
XH
|
|
44
45
|
} from '@xh/hoist/core';
|
|
@@ -146,6 +147,9 @@ export interface ZoneGridConfig {
|
|
|
146
147
|
/** Column ID(s) by which to do full-width grouping. */
|
|
147
148
|
groupBy?: Some<string>;
|
|
148
149
|
|
|
150
|
+
/** Group level to expand to on initial load. 0 = all collapsed, 1 = only top level expanded. */
|
|
151
|
+
expandToLevel?: number;
|
|
152
|
+
|
|
149
153
|
/** True (default) to show a count of group member rows within each full-width group row. */
|
|
150
154
|
showGroupRowCounts?: boolean;
|
|
151
155
|
|
|
@@ -231,6 +235,13 @@ export interface ZoneGridConfig {
|
|
|
231
235
|
*/
|
|
232
236
|
onCellContextMenu?: (e: CellContextMenuEvent) => void;
|
|
233
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Array of labels (or a function returning one) that describes the individual depth
|
|
240
|
+
* levels in a tree or grouped grid. If provided, will be used to construct expand/collapse
|
|
241
|
+
* options in the default context menu.
|
|
242
|
+
*/
|
|
243
|
+
levelLabels?: Thunkable<string[]>;
|
|
244
|
+
|
|
234
245
|
/**
|
|
235
246
|
* Number of clicks required to expand / collapse a parent row in a tree grid. Defaults
|
|
236
247
|
* to 2 for desktop, 1 for mobile. Any other value prevents clicks on row body from
|
|
@@ -419,7 +430,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
419
430
|
'copyWithHeaders',
|
|
420
431
|
'copyCell',
|
|
421
432
|
'-',
|
|
422
|
-
'
|
|
433
|
+
'expandCollapse',
|
|
423
434
|
'-',
|
|
424
435
|
'restoreDefaults',
|
|
425
436
|
'-',
|
|
@@ -210,7 +210,7 @@ export class Exception {
|
|
|
210
210
|
|
|
211
211
|
private static createInternal(attributes: PlainObject, baseError?: Error) {
|
|
212
212
|
const {message, ...rest} = attributes;
|
|
213
|
-
|
|
213
|
+
const ret = Object.assign(
|
|
214
214
|
baseError ?? new Error(message),
|
|
215
215
|
{
|
|
216
216
|
isRoutine: false,
|
|
@@ -218,6 +218,11 @@ export class Exception {
|
|
|
218
218
|
},
|
|
219
219
|
rest
|
|
220
220
|
) as HoistException;
|
|
221
|
+
|
|
222
|
+
// statuses of 0, 4XX, 5XX are server errors, so stack irrelevant and potentially misleading
|
|
223
|
+
if (ret.stack == null || /^[045]/.test(ret.httpStatus)) delete ret.stack;
|
|
224
|
+
|
|
225
|
+
return ret;
|
|
221
226
|
}
|
|
222
227
|
}
|
|
223
228
|
|
|
@@ -185,8 +185,7 @@ export class ExceptionHandler {
|
|
|
185
185
|
async logOnServerAsync(options: ExceptionHandlerLoggingOptions): Promise<boolean> {
|
|
186
186
|
const {exception, userAlerted, userMessage} = options;
|
|
187
187
|
try {
|
|
188
|
-
const
|
|
189
|
-
username = XH.getUsername();
|
|
188
|
+
const username = XH.getUsername();
|
|
190
189
|
|
|
191
190
|
if (!username) {
|
|
192
191
|
logWarn('Error report cannot be submitted to UI server - user unknown', this);
|
|
@@ -194,7 +193,7 @@ export class ExceptionHandler {
|
|
|
194
193
|
}
|
|
195
194
|
|
|
196
195
|
const data: PlainObject = {
|
|
197
|
-
error:
|
|
196
|
+
error: this.sanitizeException(exception),
|
|
198
197
|
userAlerted
|
|
199
198
|
};
|
|
200
199
|
if (userMessage) data.userMessage = stripTags(userMessage);
|
|
@@ -216,8 +215,16 @@ export class ExceptionHandler {
|
|
|
216
215
|
}
|
|
217
216
|
|
|
218
217
|
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
218
|
+
* Sanitize an exception for submission to server. This method will avoid circular references
|
|
219
|
+
* trim the depth of the object, and redact sensitive info (e.g. passwords).
|
|
220
|
+
*/
|
|
221
|
+
sanitizeException(exception: HoistException): PlainObject {
|
|
222
|
+
return JSON.parse(this.stringifyErrorSafely(exception));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Serialize an error object safely for user display. This method will avoid circular
|
|
227
|
+
* references, trim the depth of the object, and redact sensitive info (e.g. passwords).
|
|
221
228
|
*/
|
|
222
229
|
stringifyErrorSafely(exception: HoistException): string {
|
|
223
230
|
try {
|
|
@@ -287,8 +294,6 @@ export class ExceptionHandler {
|
|
|
287
294
|
this.hideParams(e, opts);
|
|
288
295
|
}
|
|
289
296
|
|
|
290
|
-
this.cleanStack(e);
|
|
291
|
-
|
|
292
297
|
return {e, opts};
|
|
293
298
|
}
|
|
294
299
|
|
|
@@ -342,12 +347,6 @@ export class ExceptionHandler {
|
|
|
342
347
|
return e.name === 'SessionMismatchException';
|
|
343
348
|
}
|
|
344
349
|
|
|
345
|
-
private cleanStack(e: HoistException) {
|
|
346
|
-
// statuses of 0, 4XX, 5XX are server errors, so the javascript stack
|
|
347
|
-
// is irrelevant and potentially misleading
|
|
348
|
-
if (/^[045]/.test(e.httpStatus)) delete e.stack;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
350
|
private cloneAndTrim(obj, depth = 5) {
|
|
352
351
|
// Create a depth-constrained, deep copy of an object for safe-use in stringify
|
|
353
352
|
// - Skip private _XXXX properties.
|
package/data/RecordAction.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface RecordActionSpec extends TestSupportProps {
|
|
|
34
34
|
actionFn?: (data: ActionFnData) => void;
|
|
35
35
|
|
|
36
36
|
/** Function called prior to showing this item. */
|
|
37
|
-
displayFn?: (data:
|
|
37
|
+
displayFn?: (data: ActionFnData) => RecordActionSpec;
|
|
38
38
|
|
|
39
39
|
/** Sub-actions for this action. */
|
|
40
40
|
items?: RecordActionLike[];
|
|
@@ -107,7 +107,7 @@ export class RecordAction {
|
|
|
107
107
|
className: string;
|
|
108
108
|
tooltip: string;
|
|
109
109
|
actionFn: (data: ActionFnData) => void;
|
|
110
|
-
displayFn: (data:
|
|
110
|
+
displayFn: (data: ActionFnData) => PlainObject;
|
|
111
111
|
items: Array<RecordAction | string>;
|
|
112
112
|
disabled: boolean;
|
|
113
113
|
hidden: boolean;
|
|
@@ -207,8 +207,3 @@ export class RecordAction {
|
|
|
207
207
|
);
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
|
|
211
|
-
interface DisplayFnData extends ActionFnData {
|
|
212
|
-
/** Default display config for the action */
|
|
213
|
-
defaultConfig?: PlainObject;
|
|
214
|
-
}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import {GridOptions} from '@ag-grid-community/core';
|
|
8
|
+
import {grid} from '@xh/hoist/cmp/grid';
|
|
8
9
|
import {hframe, vbox} from '@xh/hoist/cmp/layout';
|
|
9
10
|
import {BoxProps, hoistCmp, HoistProps, uses} from '@xh/hoist/core';
|
|
10
11
|
import '@xh/hoist/desktop/register';
|
|
@@ -12,7 +13,6 @@ import {chooserToolbar} from './impl/ChooserToolbar';
|
|
|
12
13
|
import {description} from './impl/Description';
|
|
13
14
|
import './LeftRightChooser.scss';
|
|
14
15
|
import {LeftRightChooserModel} from './LeftRightChooserModel';
|
|
15
|
-
import {cloneDeep} from 'lodash';
|
|
16
16
|
|
|
17
17
|
export interface LeftRightChooserProps extends HoistProps<LeftRightChooserModel>, BoxProps {}
|
|
18
18
|
|
|
@@ -28,19 +28,11 @@ export const [LeftRightChooser, leftRightChooser] = hoistCmp.withFactory<LeftRig
|
|
|
28
28
|
className: 'xh-lr-chooser',
|
|
29
29
|
|
|
30
30
|
render({model, ...props}, ref) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
leftGridOptions = cloneDeep(gridOptions),
|
|
40
|
-
rightGridOptions = cloneDeep(gridOptions);
|
|
41
|
-
|
|
42
|
-
if (!leftGroupingExpanded) leftGridOptions.agOptions.groupDefaultExpanded = 0;
|
|
43
|
-
if (!rightGroupingExpanded) rightGridOptions.agOptions.groupDefaultExpanded = 0;
|
|
31
|
+
const agOptions: GridOptions = {
|
|
32
|
+
defaultColDef: {
|
|
33
|
+
resizable: false
|
|
34
|
+
}
|
|
35
|
+
};
|
|
44
36
|
|
|
45
37
|
return vbox({
|
|
46
38
|
ref,
|
|
@@ -48,9 +40,9 @@ export const [LeftRightChooser, leftRightChooser] = hoistCmp.withFactory<LeftRig
|
|
|
48
40
|
hframe({
|
|
49
41
|
className: 'xh-lr-chooser__grid-frame',
|
|
50
42
|
items: [
|
|
51
|
-
grid({model: leftModel,
|
|
43
|
+
grid({model: model.leftModel, agOptions}),
|
|
52
44
|
chooserToolbar(),
|
|
53
|
-
grid({model: rightModel,
|
|
45
|
+
grid({model: model.rightModel, agOptions})
|
|
54
46
|
]
|
|
55
47
|
}),
|
|
56
48
|
description()
|
|
@@ -186,6 +186,7 @@ export class LeftRightChooserModel extends HoistModel {
|
|
|
186
186
|
onRowDoubleClicked: e => this.onRowDoubleClicked(e),
|
|
187
187
|
columns: [leftTextCol, groupCol],
|
|
188
188
|
contextMenu: false,
|
|
189
|
+
expandToLevel: leftGroupingExpanded ? 1 : 0,
|
|
189
190
|
xhImpl: true
|
|
190
191
|
});
|
|
191
192
|
|
|
@@ -197,6 +198,7 @@ export class LeftRightChooserModel extends HoistModel {
|
|
|
197
198
|
onRowDoubleClicked: e => this.onRowDoubleClicked(e),
|
|
198
199
|
columns: [rightTextCol, groupCol],
|
|
199
200
|
contextMenu: false,
|
|
201
|
+
expandToLevel: rightGroupingExpanded ? 1 : 0,
|
|
200
202
|
xhImpl: true
|
|
201
203
|
});
|
|
202
204
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "75.0.0-SNAPSHOT.
|
|
3
|
+
"version": "75.0.0-SNAPSHOT.1752860174147",
|
|
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",
|
package/promise/Promise.ts
CHANGED
|
@@ -202,8 +202,10 @@ const enhancePromise = promisePrototype => {
|
|
|
202
202
|
if (!options) return this;
|
|
203
203
|
|
|
204
204
|
const startTime = Date.now(),
|
|
205
|
-
doTrack = (
|
|
206
|
-
|
|
205
|
+
doTrack = (rejectReason: unknown = null) => {
|
|
206
|
+
const exception = rejectReason != null ? Exception.create(rejectReason) : null;
|
|
207
|
+
|
|
208
|
+
if (exception?.isRoutine) return;
|
|
207
209
|
|
|
208
210
|
const endTime = Date.now(),
|
|
209
211
|
opts: TrackOptions = isString(options) ? {message: options} : {...options};
|
|
@@ -222,7 +224,14 @@ const enhancePromise = promisePrototype => {
|
|
|
222
224
|
) {
|
|
223
225
|
opts.elapsed = null;
|
|
224
226
|
}
|
|
225
|
-
if (exception)
|
|
227
|
+
if (exception) {
|
|
228
|
+
opts.severity = 'ERROR';
|
|
229
|
+
opts.data = {
|
|
230
|
+
error: XH.exceptionHandler.sanitizeException(exception),
|
|
231
|
+
data: opts.data
|
|
232
|
+
};
|
|
233
|
+
opts.correlationId = opts.correlationId ?? exception.correlationId;
|
|
234
|
+
}
|
|
226
235
|
|
|
227
236
|
XH.track(opts);
|
|
228
237
|
};
|