@xh/hoist 73.0.0-SNAPSHOT.1745446457207 → 73.0.0-SNAPSHOT.1745457790188
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 +21 -0
- package/admin/AppModel.ts +19 -12
- package/admin/columns/Core.ts +29 -0
- package/admin/columns/Tracking.ts +3 -23
- package/admin/tabs/BaseAdminTabModel.ts +17 -0
- package/admin/tabs/activity/{ActivityTab.scss → tracking/ActivityTracking.scss} +0 -8
- package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +1 -0
- package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +5 -1
- package/admin/tabs/{activity/ActivityTab.ts → client/ClientTab.ts} +7 -8
- package/admin/tabs/{cluster/instances/websocket/WebSocketColumns.ts → client/clients/ClientsColumns.ts} +12 -6
- package/admin/tabs/{cluster/instances/websocket/WebSocketModel.ts → client/clients/ClientsModel.ts} +99 -57
- package/admin/tabs/{cluster/instances/websocket/WebSocketPanel.ts → client/clients/ClientsPanel.ts} +32 -26
- package/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorDetail.ts +9 -5
- package/admin/tabs/client/errors/ClientErrors.scss +52 -0
- package/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorsPanel.ts +2 -1
- package/admin/tabs/cluster/instances/BaseInstanceModel.ts +3 -10
- package/admin/tabs/cluster/instances/InstancesTabModel.ts +1 -3
- package/admin/tabs/monitor/MonitorTabModel.ts +4 -3
- package/admin/tabs/userData/roles/RoleModel.ts +1 -0
- package/admin/tabs/userData/roles/RolePanel.ts +4 -2
- package/build/types/admin/columns/Core.d.ts +3 -0
- package/build/types/admin/tabs/BaseAdminTabModel.d.ts +6 -0
- package/build/types/admin/tabs/activity/tracking/ActivityTrackingPanel.d.ts +1 -0
- package/build/types/admin/tabs/client/ClientTab.d.ts +1 -0
- package/build/types/admin/tabs/{cluster/instances/websocket/WebSocketModel.d.ts → client/clients/ClientsModel.d.ts} +5 -2
- package/build/types/admin/tabs/client/clients/ClientsPanel.d.ts +2 -0
- package/build/types/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorsPanel.d.ts +1 -0
- package/build/types/admin/tabs/cluster/instances/BaseInstanceModel.d.ts +3 -5
- package/build/types/admin/tabs/monitor/MonitorTabModel.d.ts +3 -2
- package/build/types/svc/EnvironmentService.d.ts +3 -1
- package/package.json +1 -1
- package/svc/EnvironmentService.ts +6 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/build/types/admin/tabs/activity/ActivityTab.d.ts +0 -2
- package/build/types/admin/tabs/cluster/instances/websocket/WebSocketPanel.d.ts +0 -2
- /package/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorsModel.ts +0 -0
- /package/admin/tabs/{activity → client}/feedback/FeedbackPanel.ts +0 -0
- /package/build/types/admin/tabs/{cluster/instances/websocket/WebSocketColumns.d.ts → client/clients/ClientsColumns.d.ts} +0 -0
- /package/build/types/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorDetail.d.ts +0 -0
- /package/build/types/admin/tabs/{activity/clienterrors → client/errors}/ClientErrorsModel.d.ts +0 -0
- /package/build/types/admin/tabs/{activity → client}/feedback/FeedbackPanel.d.ts +0 -0
|
@@ -23,16 +23,19 @@ export const clientErrorDetail = hoistCmp.factory<ClientErrorsModel>(({model}) =
|
|
|
23
23
|
if (!selectedRecord) return null;
|
|
24
24
|
|
|
25
25
|
return panel({
|
|
26
|
-
className: 'xh-admin-
|
|
26
|
+
className: 'xh-admin-client-errors-detail',
|
|
27
|
+
collapsedTitle: 'Error Details',
|
|
28
|
+
collapsedIcon: Icon.info(),
|
|
29
|
+
compactHeader: true,
|
|
27
30
|
modelConfig: {
|
|
28
31
|
side: 'bottom',
|
|
29
|
-
defaultSize:
|
|
32
|
+
defaultSize: 400
|
|
30
33
|
},
|
|
31
34
|
item: form({
|
|
32
35
|
fieldDefaults: {inline: true, readonlyRenderer: valOrNa},
|
|
33
36
|
item: hframe(
|
|
34
37
|
div({
|
|
35
|
-
className: 'xh-admin-
|
|
38
|
+
className: 'xh-admin-client-errors-detail__form',
|
|
36
39
|
style: {width: '400px'},
|
|
37
40
|
items: [
|
|
38
41
|
h3(Icon.info(), 'Error Info'),
|
|
@@ -89,12 +92,13 @@ export const clientErrorDetail = hoistCmp.factory<ClientErrorsModel>(({model}) =
|
|
|
89
92
|
className: 'xh-border-left',
|
|
90
93
|
items: [
|
|
91
94
|
panel({
|
|
92
|
-
|
|
95
|
+
flex: 0.5,
|
|
93
96
|
className: 'xh-border-bottom',
|
|
94
97
|
items: [
|
|
95
98
|
h3(Icon.comment(), 'User Message'),
|
|
96
99
|
div({
|
|
97
|
-
className: `xh-
|
|
100
|
+
className: `xh-pad`,
|
|
101
|
+
style: {overflowY: 'auto'},
|
|
98
102
|
item: userMsg
|
|
99
103
|
})
|
|
100
104
|
],
|
|
@@ -0,0 +1,52 @@
|
|
|
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 © 2025 Extremely Heavy Industries Inc.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.xh-admin-client-errors-detail {
|
|
9
|
+
&__form {
|
|
10
|
+
overflow-y: auto;
|
|
11
|
+
|
|
12
|
+
.xh-form-field {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 2px var(--xh-pad-px);
|
|
15
|
+
|
|
16
|
+
&.xh-form-field-readonly .xh-form-field-readonly-display {
|
|
17
|
+
padding: var(--xh-pad-half-px);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&:nth-child(odd) {
|
|
21
|
+
background-color: var(--xh-grid-bg-odd);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.xh-form-field-label {
|
|
26
|
+
font-size: var(--xh-font-size-small-px);
|
|
27
|
+
padding: 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
h3 {
|
|
32
|
+
color: var(--xh-text-color-headings);
|
|
33
|
+
background-color: var(--xh-blue-gray-light);
|
|
34
|
+
margin: 0 !important;
|
|
35
|
+
font-size: var(--xh-font-size-px);
|
|
36
|
+
font-weight: normal;
|
|
37
|
+
padding: var(--xh-pad-half-px) !important;
|
|
38
|
+
border-bottom: var(--xh-border-solid);
|
|
39
|
+
|
|
40
|
+
&:not(:first-child) {
|
|
41
|
+
border-top: var(--xh-border-solid);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.xh-dark & {
|
|
45
|
+
background-color: var(--xh-blue-gray-dark);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.xh-icon {
|
|
49
|
+
margin-right: var(--xh-pad-px);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -16,13 +16,14 @@ import {Icon} from '@xh/hoist/icon';
|
|
|
16
16
|
import {LocalDate} from '@xh/hoist/utils/datetime';
|
|
17
17
|
import {clientErrorDetail} from './ClientErrorDetail';
|
|
18
18
|
import {ClientErrorsModel} from './ClientErrorsModel';
|
|
19
|
+
import './ClientErrors.scss';
|
|
19
20
|
|
|
20
21
|
export const clientErrorsPanel = hoistCmp.factory({
|
|
21
22
|
model: creates(ClientErrorsModel),
|
|
22
23
|
|
|
23
24
|
render() {
|
|
24
25
|
return panel({
|
|
25
|
-
className: 'xh-admin-
|
|
26
|
+
className: 'xh-admin-client-errors-panel',
|
|
26
27
|
tbar: tbar(),
|
|
27
28
|
items: [grid(), clientErrorDetail()],
|
|
28
29
|
mask: 'onLoad'
|
|
@@ -5,13 +5,10 @@
|
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {InstancesTabModel} from '@xh/hoist/admin/tabs/cluster/instances/InstancesTabModel';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {isDisplayed} from '@xh/hoist/utils/js';
|
|
11
|
-
|
|
12
|
-
export class BaseInstanceModel extends HoistModel {
|
|
13
|
-
viewRef = createRef<HTMLElement>();
|
|
8
|
+
import {LoadSpec, lookup, XH} from '@xh/hoist/core';
|
|
9
|
+
import {BaseAdminTabModel} from '@xh/hoist/admin/tabs/BaseAdminTabModel';
|
|
14
10
|
|
|
11
|
+
export class BaseInstanceModel extends BaseAdminTabModel {
|
|
15
12
|
@lookup(() => InstancesTabModel) parent: InstancesTabModel;
|
|
16
13
|
|
|
17
14
|
get instanceName(): string {
|
|
@@ -30,10 +27,6 @@ export class BaseInstanceModel extends HoistModel {
|
|
|
30
27
|
});
|
|
31
28
|
}
|
|
32
29
|
|
|
33
|
-
get isVisible() {
|
|
34
|
-
return isDisplayed(this.viewRef.current);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
30
|
//-------------------
|
|
38
31
|
// Implementation
|
|
39
32
|
//-------------------
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
} from '@xh/hoist/admin/tabs/cluster/instances/memory/MemoryMonitorModel';
|
|
16
16
|
import {memoryMonitorPanel} from '@xh/hoist/admin/tabs/cluster/instances/memory/MemoryMonitorPanel';
|
|
17
17
|
import {servicePanel} from '@xh/hoist/admin/tabs/cluster/instances/services/ServicePanel';
|
|
18
|
-
import {webSocketPanel} from '@xh/hoist/admin/tabs/cluster/instances/websocket/WebSocketPanel';
|
|
19
18
|
import {badge} from '@xh/hoist/cmp/badge';
|
|
20
19
|
import {GridContextMenuSpec, GridModel, numberCol} from '@xh/hoist/cmp/grid';
|
|
21
20
|
import {hbox} from '@xh/hoist/cmp/layout';
|
|
@@ -205,8 +204,7 @@ export class InstancesTabModel extends HoistModel {
|
|
|
205
204
|
content: connPoolMonitorPanel
|
|
206
205
|
},
|
|
207
206
|
{id: 'environment', icon: Icon.globe(), content: serverEnvPanel},
|
|
208
|
-
{id: 'services', icon: Icon.gears(), content: servicePanel}
|
|
209
|
-
{id: 'webSockets', title: 'WebSockets', icon: Icon.bolt(), content: webSocketPanel}
|
|
207
|
+
{id: 'services', icon: Icon.gears(), content: servicePanel}
|
|
210
208
|
]
|
|
211
209
|
});
|
|
212
210
|
}
|
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {MonitorResults, MonitorStatus} from '@xh/hoist/admin/tabs/monitor/Types';
|
|
8
|
-
import {
|
|
8
|
+
import {LoadSpec, managed, persist, XH} from '@xh/hoist/core';
|
|
9
9
|
import {Icon} from '@xh/hoist/icon';
|
|
10
10
|
import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx';
|
|
11
11
|
import {Timer} from '@xh/hoist/utils/async';
|
|
12
12
|
import {SECONDS} from '@xh/hoist/utils/datetime';
|
|
13
13
|
import {pluralize} from '@xh/hoist/utils/js';
|
|
14
14
|
import {filter, isEqual, minBy, sortBy} from 'lodash';
|
|
15
|
+
import {BaseAdminTabModel} from '@xh/hoist/admin/tabs/BaseAdminTabModel';
|
|
15
16
|
|
|
16
|
-
export class MonitorTabModel extends
|
|
17
|
+
export class MonitorTabModel extends BaseAdminTabModel {
|
|
17
18
|
override persistWith = {localStorageKey: 'xhAdminClientMonitorState'};
|
|
18
19
|
|
|
19
20
|
@observable.ref results: MonitorResults[] = [];
|
|
@@ -73,7 +74,7 @@ export class MonitorTabModel extends HoistModel {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
override async doLoadAsync(loadSpec: LoadSpec) {
|
|
76
|
-
if (!
|
|
77
|
+
if (!this.isVisible) return;
|
|
77
78
|
|
|
78
79
|
try {
|
|
79
80
|
const results = await XH.fetchJson({url: 'monitorResultsAdmin/results', loadSpec});
|
|
@@ -8,7 +8,7 @@ import {recategorizeDialog} from '@xh/hoist/admin/tabs/userData/roles/recategori
|
|
|
8
8
|
import {grid} from '@xh/hoist/cmp/grid';
|
|
9
9
|
import {fragment, hframe, vframe} from '@xh/hoist/cmp/layout';
|
|
10
10
|
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
11
|
-
import {button} from '@xh/hoist/desktop/cmp/button';
|
|
11
|
+
import {button, colChooserButton} from '@xh/hoist/desktop/cmp/button';
|
|
12
12
|
import {errorMessage} from '@xh/hoist/cmp/error';
|
|
13
13
|
import {filterChooser} from '@xh/hoist/desktop/cmp/filter';
|
|
14
14
|
import {switchInput} from '@xh/hoist/desktop/cmp/input';
|
|
@@ -50,7 +50,9 @@ export const rolePanel = hoistCmp.factory({
|
|
|
50
50
|
bind: 'showInGroups',
|
|
51
51
|
label: 'Group by Category',
|
|
52
52
|
labelSide: 'left'
|
|
53
|
-
})
|
|
53
|
+
}),
|
|
54
|
+
'-',
|
|
55
|
+
colChooserButton()
|
|
54
56
|
],
|
|
55
57
|
item: hframe(vframe(grid(), roleGraph()), detailsPanel())
|
|
56
58
|
}),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { ColumnSpec } from '@xh/hoist/cmp/grid';
|
|
2
3
|
export declare const name: ColumnSpec;
|
|
3
4
|
export declare const type: ColumnSpec;
|
|
@@ -5,3 +6,5 @@ export declare const description: ColumnSpec;
|
|
|
5
6
|
export declare const notes: ColumnSpec;
|
|
6
7
|
export declare const note: ColumnSpec;
|
|
7
8
|
export declare const timestampNoYear: ColumnSpec;
|
|
9
|
+
export declare function badgeRenderer(v: any): "-" | import("react").ReactElement<import("@xh/hoist/cmp/badge").BadgeProps, any>;
|
|
10
|
+
export declare const badgeCol: ColumnSpec;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const clientTab: import("@xh/hoist/core").ElementFactory<import("@xh/hoist/core").DefaultHoistProps<import("@xh/hoist/core").HoistModel>>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { BaseInstanceModel } from '@xh/hoist/admin/tabs/cluster/instances/BaseInstanceModel';
|
|
2
1
|
import { GridModel } from '@xh/hoist/cmp/grid';
|
|
3
2
|
import { LoadSpec } from '@xh/hoist/core';
|
|
4
3
|
import { RecordActionSpec, StoreRecord } from '@xh/hoist/data';
|
|
5
|
-
|
|
4
|
+
import { BaseAdminTabModel } from '@xh/hoist/admin/tabs/BaseAdminTabModel';
|
|
5
|
+
export declare class ClientsModel extends BaseAdminTabModel {
|
|
6
6
|
lastRefresh: number;
|
|
7
7
|
gridModel: GridModel;
|
|
8
|
+
groupBy: 'user' | 'instance';
|
|
8
9
|
private _timer;
|
|
9
10
|
forceSuspendAction: RecordActionSpec;
|
|
10
11
|
reqHealthReportAction: RecordActionSpec;
|
|
@@ -12,5 +13,7 @@ export declare class WebSocketModel extends BaseInstanceModel {
|
|
|
12
13
|
doLoadAsync(loadSpec: LoadSpec): Promise<void>;
|
|
13
14
|
forceSuspendAsync(toRecs: StoreRecord[]): Promise<void>;
|
|
14
15
|
requestHealthReportAsync(toRecs: StoreRecord[]): Promise<void>;
|
|
16
|
+
private createGridModel;
|
|
15
17
|
private bulkPush;
|
|
18
|
+
private applyGroupBy;
|
|
16
19
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { InstancesTabModel } from '@xh/hoist/admin/tabs/cluster/instances/InstancesTabModel';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { LoadSpec } from '@xh/hoist/core';
|
|
3
|
+
import { BaseAdminTabModel } from '@xh/hoist/admin/tabs/BaseAdminTabModel';
|
|
4
|
+
export declare class BaseInstanceModel extends BaseAdminTabModel {
|
|
6
5
|
parent: InstancesTabModel;
|
|
7
6
|
get instanceName(): string;
|
|
8
7
|
handleLoadException(e: unknown, loadSpec: LoadSpec): void;
|
|
9
|
-
get isVisible(): boolean;
|
|
10
8
|
private isInstanceNotFound;
|
|
11
9
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { MonitorResults, MonitorStatus } from '@xh/hoist/admin/tabs/monitor/Types';
|
|
2
|
-
import {
|
|
2
|
+
import { LoadSpec } from '@xh/hoist/core';
|
|
3
3
|
import { Timer } from '@xh/hoist/utils/async';
|
|
4
|
-
|
|
4
|
+
import { BaseAdminTabModel } from '@xh/hoist/admin/tabs/BaseAdminTabModel';
|
|
5
|
+
export declare class MonitorTabModel extends BaseAdminTabModel {
|
|
5
6
|
persistWith: {
|
|
6
7
|
localStorageKey: string;
|
|
7
8
|
};
|
|
@@ -31,7 +31,9 @@ export declare class EnvironmentService extends HoistService {
|
|
|
31
31
|
isMinHoistCoreVersion(version: string): boolean;
|
|
32
32
|
isMaxHoistCoreVersion(version: string): boolean;
|
|
33
33
|
/**
|
|
34
|
-
* Update critical environment information from server
|
|
34
|
+
* Update critical environment information from server, including current app version + build,
|
|
35
|
+
* upgrade prompt mode, and alert banner.
|
|
36
|
+
*
|
|
35
37
|
* @internal - not for app use. Called by `pollTimer` and as needed by Hoist code.
|
|
36
38
|
*/
|
|
37
39
|
pollServerAsync(): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "73.0.0-SNAPSHOT.
|
|
3
|
+
"version": "73.0.0-SNAPSHOT.1745457790188",
|
|
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",
|
|
@@ -113,7 +113,9 @@ export class EnvironmentService extends HoistService {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
|
-
* Update critical environment information from server
|
|
116
|
+
* Update critical environment information from server, including current app version + build,
|
|
117
|
+
* upgrade prompt mode, and alert banner.
|
|
118
|
+
*
|
|
117
119
|
* @internal - not for app use. Called by `pollTimer` and as needed by Hoist code.
|
|
118
120
|
*/
|
|
119
121
|
async pollServerAsync() {
|
|
@@ -125,15 +127,15 @@ export class EnvironmentService extends HoistService {
|
|
|
125
127
|
return;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
|
-
// Update config/interval, and
|
|
130
|
+
// Update config/interval, server info, and alert banner.
|
|
129
131
|
const {pollConfig, instanceName, alertBanner, appVersion, appBuild} = data;
|
|
130
132
|
this.pollConfig = pollConfig;
|
|
131
133
|
this.pollTimer.setInterval(this.pollIntervalMs);
|
|
132
134
|
this.setServerInfo(instanceName, appVersion, appBuild);
|
|
133
135
|
XH.alertBannerService.updateBanner(alertBanner);
|
|
134
136
|
|
|
135
|
-
// Handle version change
|
|
136
|
-
if (appVersion != XH.
|
|
137
|
+
// Handle version change - compare to constants baked into client build.
|
|
138
|
+
if (appVersion != XH.appVersion || appBuild != XH.appBuild) {
|
|
137
139
|
// force the user to refresh or prompt the user to refresh via the banner according to config
|
|
138
140
|
// build checked to trigger refresh across SNAPSHOT updates in lower environments
|
|
139
141
|
const {onVersionChange} = pollConfig;
|