@xh/hoist 68.0.0-SNAPSHOT.1726615045723 → 68.0.0-SNAPSHOT.1726671325631
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 +4 -0
- package/admin/AppComponent.ts +9 -7
- package/admin/AppModel.ts +12 -1
- package/admin/columns/Tracking.ts +26 -5
- package/admin/tabs/activity/clienterrors/ClientErrorDetail.ts +14 -7
- package/admin/tabs/activity/clienterrors/ClientErrorsModel.ts +4 -4
- package/admin/tabs/activity/tracking/detail/ActivityDetailModel.ts +7 -7
- package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +15 -8
- package/build/types/admin/AppModel.d.ts +3 -0
- package/cmp/grid/GridModel.ts +2 -0
- package/cmp/grid/columns/Column.ts +1 -1
- package/cmp/zoneGrid/ZoneGridModel.ts +4 -2
- package/desktop/cmp/button/RestoreDefaultsButton.ts +1 -0
- package/mobile/cmp/button/RestoreDefaultsButton.ts +1 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
* Requires `hoist-core >= 21.1` for consolidated polling of Alert Banner updates (see below).
|
|
8
8
|
|
|
9
|
+
### 🎁 New Features
|
|
10
|
+
|
|
11
|
+
* Added expand/collapse affordance in the left column header of ZoneGrids in tree mode.
|
|
12
|
+
|
|
9
13
|
### ⚙️ Technical
|
|
10
14
|
|
|
11
15
|
* Updated Admin Console's Cluster tab to refresh more frequently.
|
package/admin/AppComponent.ts
CHANGED
|
@@ -27,22 +27,24 @@ export const AppComponent = hoistCmp({
|
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
const tbar = hoistCmp.factory<AppModel>(({model}) =>
|
|
31
|
-
|
|
30
|
+
const tbar = hoistCmp.factory<AppModel>(({model}) => {
|
|
31
|
+
const primaryApp = model.getPrimaryAppCode();
|
|
32
|
+
return appBar({
|
|
32
33
|
icon: Icon.gears({size: '2x', prefix: 'fal'}),
|
|
33
34
|
leftItems: [tabSwitcher({testId: 'tab-switcher', enableOverflow: true})],
|
|
34
35
|
rightItems: [
|
|
35
36
|
button({
|
|
36
37
|
icon: Icon.openExternal(),
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
tooltip: `Open ${primaryApp}...`,
|
|
39
|
+
omit: !primaryApp,
|
|
40
|
+
onClick: () => model.openPrimaryApp()
|
|
39
41
|
}),
|
|
40
|
-
appBarSeparator()
|
|
42
|
+
appBarSeparator({omit: !primaryApp})
|
|
41
43
|
],
|
|
42
44
|
appMenuButtonProps: {
|
|
43
45
|
hideAdminItem: true,
|
|
44
46
|
hideFeedbackItem: true,
|
|
45
47
|
extraItems: model.getAppMenuButtonExtraItems()
|
|
46
48
|
}
|
|
47
|
-
})
|
|
48
|
-
);
|
|
49
|
+
});
|
|
50
|
+
});
|
package/admin/AppModel.ts
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {clusterTab} from '@xh/hoist/admin/tabs/cluster/ClusterTab';
|
|
7
8
|
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
8
9
|
import {TabConfig, TabContainerModel} from '@xh/hoist/cmp/tab';
|
|
9
10
|
import {HoistAppModel, managed, XH} from '@xh/hoist/core';
|
|
10
11
|
import {Icon} from '@xh/hoist/icon';
|
|
12
|
+
import {without} from 'lodash';
|
|
11
13
|
import {Route} from 'router5';
|
|
12
14
|
import {activityTab} from './tabs/activity/ActivityTab';
|
|
13
15
|
import {generalTab} from './tabs/general/GeneralTab';
|
|
14
16
|
import {monitorTab} from './tabs/monitor/MonitorTab';
|
|
15
|
-
import {clusterTab} from '@xh/hoist/admin/tabs/cluster/ClusterTab';
|
|
16
17
|
import {userDataTab} from './tabs/userData/UserDataTab';
|
|
17
18
|
|
|
18
19
|
export class AppModel extends HoistAppModel {
|
|
@@ -136,4 +137,14 @@ export class AppModel extends HoistAppModel {
|
|
|
136
137
|
}
|
|
137
138
|
];
|
|
138
139
|
}
|
|
140
|
+
|
|
141
|
+
/** Open the primary business-facing application, typically 'app'. */
|
|
142
|
+
openPrimaryApp() {
|
|
143
|
+
window.open(`/${this.getPrimaryAppCode()}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
getPrimaryAppCode() {
|
|
147
|
+
const appCodes = without(XH.clientApps, XH.clientAppCode, 'mobile');
|
|
148
|
+
return appCodes.find(it => it === 'app') ?? appCodes[0];
|
|
149
|
+
}
|
|
139
150
|
}
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {RangeAggregator} from '@xh/hoist/admin/tabs/activity/aggregators/RangeAggregator';
|
|
8
|
+
import {badge} from '@xh/hoist/cmp/badge';
|
|
9
|
+
import {XH} from '@xh/hoist/core';
|
|
8
10
|
import {Icon} from '@xh/hoist/icon';
|
|
9
11
|
import {fmtDate, fmtSpan, numberRenderer} from '@xh/hoist/format';
|
|
10
12
|
import * as Col from '@xh/hoist/cmp/grid/columns';
|
|
11
13
|
import {ColumnSpec} from '@xh/hoist/cmp/grid/columns';
|
|
14
|
+
import copy from 'clipboard-copy';
|
|
12
15
|
|
|
13
16
|
export const appEnvironment: ColumnSpec = {
|
|
14
17
|
field: {
|
|
@@ -113,6 +116,7 @@ export const correlationId: ColumnSpec = {
|
|
|
113
116
|
type: 'string',
|
|
114
117
|
displayName: 'Correlation ID'
|
|
115
118
|
},
|
|
119
|
+
renderer: badgeRenderer,
|
|
116
120
|
width: 100
|
|
117
121
|
};
|
|
118
122
|
|
|
@@ -121,8 +125,8 @@ export const error: ColumnSpec = {
|
|
|
121
125
|
name: 'error',
|
|
122
126
|
type: 'string'
|
|
123
127
|
},
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
width: 250,
|
|
129
|
+
autosizeMaxWidth: 400,
|
|
126
130
|
renderer: e => fmtSpan(e, {className: 'xh-font-family-mono xh-font-size-small'})
|
|
127
131
|
};
|
|
128
132
|
|
|
@@ -134,9 +138,8 @@ export const msg: ColumnSpec = {
|
|
|
134
138
|
isDimension: true,
|
|
135
139
|
aggregator: 'UNIQUE'
|
|
136
140
|
},
|
|
137
|
-
|
|
138
|
-
autosizeMaxWidth: 400
|
|
139
|
-
flex: true
|
|
141
|
+
width: 250,
|
|
142
|
+
autosizeMaxWidth: 400
|
|
140
143
|
};
|
|
141
144
|
|
|
142
145
|
export const url: ColumnSpec = {
|
|
@@ -156,6 +159,7 @@ export const instance: ColumnSpec = {
|
|
|
156
159
|
isDimension: true,
|
|
157
160
|
aggregator: 'UNIQUE'
|
|
158
161
|
},
|
|
162
|
+
renderer: badgeRenderer,
|
|
159
163
|
width: 100
|
|
160
164
|
};
|
|
161
165
|
|
|
@@ -230,3 +234,20 @@ function dayRangeComparator(rangeA, rangeB, sortDir, abs, {defaultComparator}) {
|
|
|
230
234
|
|
|
231
235
|
return defaultComparator(maxA, maxB);
|
|
232
236
|
}
|
|
237
|
+
|
|
238
|
+
function badgeRenderer(v) {
|
|
239
|
+
return v
|
|
240
|
+
? badge({
|
|
241
|
+
item: v,
|
|
242
|
+
className: 'xh-font-family-mono xh-title-tip',
|
|
243
|
+
title: 'Double-click to copy',
|
|
244
|
+
onDoubleClick: () => {
|
|
245
|
+
copy(v);
|
|
246
|
+
XH.toast({
|
|
247
|
+
icon: Icon.copy(),
|
|
248
|
+
message: `Copied ${v}`
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
: '-';
|
|
253
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {correlationId, instance} from '@xh/hoist/admin/columns';
|
|
7
8
|
import {form} from '@xh/hoist/cmp/form';
|
|
8
9
|
import {a, div, h3, hframe, span, vbox} from '@xh/hoist/cmp/layout';
|
|
9
10
|
import {hoistCmp} from '@xh/hoist/core';
|
|
@@ -49,10 +50,6 @@ export const clientErrorDetail = hoistCmp.factory<ClientErrorsModel>(({model}) =
|
|
|
49
50
|
return span(username, impSpan);
|
|
50
51
|
}
|
|
51
52
|
}),
|
|
52
|
-
formField({
|
|
53
|
-
field: 'dateCreated',
|
|
54
|
-
readonlyRenderer: v => fmtDateTimeSec(v)
|
|
55
|
-
}),
|
|
56
53
|
formField({
|
|
57
54
|
field: 'appVersion',
|
|
58
55
|
readonlyRenderer: appVersion => {
|
|
@@ -65,12 +62,22 @@ export const clientErrorDetail = hoistCmp.factory<ClientErrorsModel>(({model}) =
|
|
|
65
62
|
field: 'userAlerted',
|
|
66
63
|
label: 'User Alerted?'
|
|
67
64
|
}),
|
|
68
|
-
formField({field: 'id'}),
|
|
69
|
-
formField({field: 'correlationId'}),
|
|
70
65
|
formField({
|
|
71
66
|
field: 'url',
|
|
72
67
|
readonlyRenderer: hyperlinkVal
|
|
73
68
|
}),
|
|
69
|
+
formField({
|
|
70
|
+
field: 'instance',
|
|
71
|
+
readonlyRenderer: v => instance.renderer(v, null)
|
|
72
|
+
}),
|
|
73
|
+
formField({
|
|
74
|
+
field: 'correlationId',
|
|
75
|
+
readonlyRenderer: v => correlationId.renderer(v, null)
|
|
76
|
+
}),
|
|
77
|
+
formField({
|
|
78
|
+
field: 'dateCreated',
|
|
79
|
+
readonlyRenderer: v => fmtDateTimeSec(v)
|
|
80
|
+
}),
|
|
74
81
|
h3(Icon.desktop(), 'Device / Browser'),
|
|
75
82
|
formField({field: 'device'}),
|
|
76
83
|
formField({field: 'browser'}),
|
|
@@ -115,4 +122,4 @@ export const clientErrorDetail = hoistCmp.factory<ClientErrorsModel>(({model}) =
|
|
|
115
122
|
|
|
116
123
|
const valOrNa = v => (!isNil(v) ? v.toString() : naSpan());
|
|
117
124
|
const naSpan = () => span({item: 'N/A', className: 'xh-text-color-muted'});
|
|
118
|
-
const hyperlinkVal = v => a({href: v, item: v, target: '_blank'});
|
|
125
|
+
const hyperlinkVal = v => (v ? a({href: v, item: v, target: '_blank'}) : '-');
|
|
@@ -52,9 +52,10 @@ export class ClientErrorsModel extends HoistModel {
|
|
|
52
52
|
columns: [
|
|
53
53
|
{...Col.userMessageFlag},
|
|
54
54
|
{...Col.userAlertedFlag},
|
|
55
|
-
{...Col.entryId, hidden},
|
|
56
55
|
{...Col.impersonatingFlag},
|
|
56
|
+
{...Col.entryId, hidden},
|
|
57
57
|
{...Col.username},
|
|
58
|
+
{...Col.impersonating, hidden},
|
|
58
59
|
{...Col.browser},
|
|
59
60
|
{...Col.device},
|
|
60
61
|
{...Col.userAgent, hidden},
|
|
@@ -63,11 +64,10 @@ export class ClientErrorsModel extends HoistModel {
|
|
|
63
64
|
{...Col.msg, displayName: 'User Message', hidden},
|
|
64
65
|
{...Col.error, hidden},
|
|
65
66
|
{...Col.url},
|
|
67
|
+
{...Col.correlationId},
|
|
66
68
|
{...Col.instance, hidden},
|
|
67
69
|
{...Col.day},
|
|
68
|
-
{...Col.dateCreatedWithSec, displayName: 'Timestamp'}
|
|
69
|
-
{...Col.impersonating, hidden},
|
|
70
|
-
{...Col.correlationId}
|
|
70
|
+
{...Col.dateCreatedWithSec, displayName: 'Timestamp'}
|
|
71
71
|
]
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -49,17 +49,17 @@ export class ActivityDetailModel extends HoistModel {
|
|
|
49
49
|
{...Col.impersonating, hidden},
|
|
50
50
|
{...Col.category},
|
|
51
51
|
{...Col.msg},
|
|
52
|
-
{...Col.
|
|
53
|
-
{...Col.
|
|
52
|
+
{...Col.browser},
|
|
53
|
+
{...Col.device},
|
|
54
|
+
{...Col.userAgent, hidden},
|
|
54
55
|
{...Col.appVersion},
|
|
55
56
|
{...Col.appEnvironment, hidden},
|
|
56
57
|
{...Col.data, hidden},
|
|
57
|
-
{...Col.
|
|
58
|
-
{...Col.
|
|
59
|
-
{...Col.
|
|
58
|
+
{...Col.url},
|
|
59
|
+
{...Col.correlationId},
|
|
60
|
+
{...Col.instance, hidden},
|
|
60
61
|
{...Col.elapsed},
|
|
61
|
-
{...Col.dateCreatedWithSec, displayName: 'Timestamp'}
|
|
62
|
-
{...Col.correlationId}
|
|
62
|
+
{...Col.dateCreatedWithSec, displayName: 'Timestamp'}
|
|
63
63
|
]
|
|
64
64
|
});
|
|
65
65
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {correlationId, instance} from '@xh/hoist/admin/columns';
|
|
7
8
|
import {form} from '@xh/hoist/cmp/form';
|
|
8
9
|
import {grid, gridCountLabel} from '@xh/hoist/cmp/grid';
|
|
9
10
|
import {a, div, filler, h3, hframe, placeholder, span} from '@xh/hoist/cmp/layout';
|
|
@@ -81,6 +82,7 @@ const detailRecForm = hoistCmp.factory<ActivityDetailModel>(({model}) => {
|
|
|
81
82
|
}
|
|
82
83
|
}),
|
|
83
84
|
formField({field: 'category'}),
|
|
85
|
+
formField({field: 'msg'}),
|
|
84
86
|
formField({
|
|
85
87
|
field: 'appVersion',
|
|
86
88
|
readonlyRenderer: appVersion => {
|
|
@@ -89,10 +91,17 @@ const detailRecForm = hoistCmp.factory<ActivityDetailModel>(({model}) => {
|
|
|
89
91
|
return `${appVersion} (${appEnvironment})`;
|
|
90
92
|
}
|
|
91
93
|
}),
|
|
92
|
-
formField({field: 'msg'}),
|
|
93
94
|
formField({
|
|
94
|
-
field: '
|
|
95
|
-
readonlyRenderer:
|
|
95
|
+
field: 'url',
|
|
96
|
+
readonlyRenderer: hyperlinkVal
|
|
97
|
+
}),
|
|
98
|
+
formField({
|
|
99
|
+
field: 'instance',
|
|
100
|
+
readonlyRenderer: v => instance.renderer(v, null)
|
|
101
|
+
}),
|
|
102
|
+
formField({
|
|
103
|
+
field: 'correlationId',
|
|
104
|
+
readonlyRenderer: v => correlationId.renderer(v, null)
|
|
96
105
|
}),
|
|
97
106
|
formField({
|
|
98
107
|
field: 'elapsed',
|
|
@@ -102,11 +111,9 @@ const detailRecForm = hoistCmp.factory<ActivityDetailModel>(({model}) => {
|
|
|
102
111
|
formatConfig: {thousandSeparated: false, mantissa: 0}
|
|
103
112
|
})
|
|
104
113
|
}),
|
|
105
|
-
formField({field: 'id'}),
|
|
106
|
-
formField({field: 'correlationId'}),
|
|
107
114
|
formField({
|
|
108
|
-
field: '
|
|
109
|
-
readonlyRenderer:
|
|
115
|
+
field: 'dateCreated',
|
|
116
|
+
readonlyRenderer: dateTimeSecRenderer({})
|
|
110
117
|
}),
|
|
111
118
|
h3(Icon.desktop(), 'Device / Browser'),
|
|
112
119
|
formField({field: 'device'}),
|
|
@@ -136,4 +143,4 @@ const additionalDataJsonInput = hoistCmp.factory<ActivityDetailModel>(({model})
|
|
|
136
143
|
|
|
137
144
|
const valOrNa = v => (v != null ? v : naSpan());
|
|
138
145
|
const naSpan = () => span({item: 'N/A', className: 'xh-text-color-muted'});
|
|
139
|
-
const hyperlinkVal = v => a({href: v, item: v, target: '_blank'});
|
|
146
|
+
const hyperlinkVal = v => (v ? a({href: v, item: v, target: '_blank'}) : '-');
|
|
@@ -10,4 +10,7 @@ export declare class AppModel extends HoistAppModel {
|
|
|
10
10
|
getAppMenuButtonExtraItems(): any[];
|
|
11
11
|
getTabRoutes(): Route[];
|
|
12
12
|
createTabs(): TabConfig[];
|
|
13
|
+
/** Open the primary business-facing application, typically 'app'. */
|
|
14
|
+
openPrimaryApp(): void;
|
|
15
|
+
getPrimaryAppCode(): string;
|
|
13
16
|
}
|
package/cmp/grid/GridModel.ts
CHANGED
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
} from '@xh/hoist/data';
|
|
52
52
|
import {ColChooserModel as DesktopColChooserModel} from '@xh/hoist/dynamics/desktop';
|
|
53
53
|
import {ColChooserModel as MobileColChooserModel} from '@xh/hoist/dynamics/mobile';
|
|
54
|
+
import {Icon} from '@xh/hoist/icon';
|
|
54
55
|
import {action, bindable, makeObservable, observable, when} from '@xh/hoist/mobx';
|
|
55
56
|
import {wait, waitFor} from '@xh/hoist/promise';
|
|
56
57
|
import {ExportOptions} from '@xh/hoist/svc/GridExportService';
|
|
@@ -635,6 +636,7 @@ export class GridModel extends HoistModel {
|
|
|
635
636
|
message: this.restoreDefaultsWarning,
|
|
636
637
|
confirmProps: {
|
|
637
638
|
text: 'Yes, restore defaults',
|
|
639
|
+
icon: Icon.reset(),
|
|
638
640
|
intent: 'primary'
|
|
639
641
|
}
|
|
640
642
|
});
|
|
@@ -386,6 +386,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
386
386
|
message: this.restoreDefaultsWarning,
|
|
387
387
|
confirmProps: {
|
|
388
388
|
text: 'Yes, restore defaults',
|
|
389
|
+
icon: Icon.reset(),
|
|
389
390
|
intent: 'primary'
|
|
390
391
|
}
|
|
391
392
|
});
|
|
@@ -583,7 +584,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
583
584
|
const colId = it.field;
|
|
584
585
|
subFields.push({
|
|
585
586
|
colId,
|
|
586
|
-
label: it.showLabel ? labelRenderers[colId] ?? true : false,
|
|
587
|
+
label: it.showLabel ? (labelRenderers[colId] ?? true) : false,
|
|
587
588
|
position: 'top'
|
|
588
589
|
});
|
|
589
590
|
});
|
|
@@ -591,7 +592,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
591
592
|
const colId = it.field;
|
|
592
593
|
subFields.push({
|
|
593
594
|
colId,
|
|
594
|
-
label: it.showLabel ? labelRenderers[colId] ?? true : false,
|
|
595
|
+
label: it.showLabel ? (labelRenderers[colId] ?? true) : false,
|
|
595
596
|
position: 'bottom'
|
|
596
597
|
});
|
|
597
598
|
});
|
|
@@ -608,6 +609,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
608
609
|
// Controlled properties
|
|
609
610
|
field: isLeft ? 'left_column' : 'right_column',
|
|
610
611
|
align: isLeft ? 'left' : 'right',
|
|
612
|
+
isTreeColumn: gridModel?.treeMode && isLeft,
|
|
611
613
|
flex: overrideSpec.width ? null : isLeft ? 2 : 1,
|
|
612
614
|
renderer: (value, context) => zoneGridRenderer(value, context, isLeft),
|
|
613
615
|
rendererIsComplex: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "68.0.0-SNAPSHOT.
|
|
3
|
+
"version": "68.0.0-SNAPSHOT.1726671325631",
|
|
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",
|