@xh/hoist 69.0.0-SNAPSHOT.1726689665759 → 69.0.0-SNAPSHOT.1727288627891
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 +3 -0
- package/admin/tabs/cluster/hzobject/HzObjectModel.ts +45 -7
- package/admin/tabs/cluster/hzobject/HzObjectPanel.ts +47 -24
- package/admin/tabs/cluster/services/ServiceModel.ts +30 -4
- package/admin/tabs/cluster/services/ServicePanel.ts +43 -18
- package/build/types/admin/tabs/cluster/hzobject/HzObjectModel.d.ts +3 -0
- package/build/types/admin/tabs/cluster/services/ServiceModel.d.ts +5 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,12 +11,15 @@ import {BaseInstanceModel} from '@xh/hoist/admin/tabs/cluster/BaseInstanceModel'
|
|
|
11
11
|
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
12
12
|
import * as Col from '@xh/hoist/cmp/grid/columns';
|
|
13
13
|
import {br, fragment} from '@xh/hoist/cmp/layout';
|
|
14
|
-
import {LoadSpec, managed, XH} from '@xh/hoist/core';
|
|
14
|
+
import {LoadSpec, managed, PlainObject, XH} from '@xh/hoist/core';
|
|
15
15
|
import {RecordActionSpec} from '@xh/hoist/data';
|
|
16
16
|
import {Icon} from '@xh/hoist/icon';
|
|
17
|
-
import {
|
|
17
|
+
import {bindable, makeObservable} from '@xh/hoist/mobx';
|
|
18
|
+
import {first, isEmpty, last} from 'lodash';
|
|
18
19
|
|
|
19
20
|
export class HzObjectModel extends BaseInstanceModel {
|
|
21
|
+
@bindable groupBy: 'type' | 'owner' = 'owner';
|
|
22
|
+
|
|
20
23
|
clearAction: RecordActionSpec = {
|
|
21
24
|
text: 'Clear Objects',
|
|
22
25
|
icon: Icon.reset(),
|
|
@@ -35,21 +38,25 @@ export class HzObjectModel extends BaseInstanceModel {
|
|
|
35
38
|
selModel: 'multiple',
|
|
36
39
|
enableExport: true,
|
|
37
40
|
exportOptions: {filename: exportFilenameWithDate('distributed-objects'), columns: 'ALL'},
|
|
38
|
-
sortBy: '
|
|
39
|
-
groupBy:
|
|
41
|
+
sortBy: 'displayName',
|
|
42
|
+
groupBy: this.groupBy,
|
|
40
43
|
store: {
|
|
41
44
|
fields: [
|
|
42
45
|
{name: 'name', type: 'string'},
|
|
46
|
+
{name: 'displayName', type: 'string'},
|
|
47
|
+
{name: 'owner', type: 'string'},
|
|
43
48
|
{name: 'type', type: 'string', displayName: 'Type'},
|
|
44
49
|
{name: 'size', type: 'int'},
|
|
45
50
|
{name: 'lastUpdateTime', type: 'date'},
|
|
46
51
|
{name: 'lastAccessTime', type: 'date'}
|
|
47
52
|
],
|
|
48
|
-
idSpec: 'name'
|
|
53
|
+
idSpec: 'name',
|
|
54
|
+
processRawData: o => this.processRawData(o)
|
|
49
55
|
},
|
|
50
56
|
columns: [
|
|
51
|
-
{field: '
|
|
52
|
-
{field: '
|
|
57
|
+
{field: 'displayName', flex: 1},
|
|
58
|
+
{field: 'owner'},
|
|
59
|
+
{field: 'type'},
|
|
53
60
|
{field: 'size', displayName: 'Entry Count', ...Col.number, width: 130},
|
|
54
61
|
{
|
|
55
62
|
...timestampNoYear,
|
|
@@ -65,6 +72,15 @@ export class HzObjectModel extends BaseInstanceModel {
|
|
|
65
72
|
contextMenu: [this.clearAction, '-', ...GridModel.defaultContextMenu]
|
|
66
73
|
});
|
|
67
74
|
|
|
75
|
+
constructor() {
|
|
76
|
+
super();
|
|
77
|
+
makeObservable(this);
|
|
78
|
+
this.addReaction({
|
|
79
|
+
track: () => this.groupBy,
|
|
80
|
+
run: v => this.gridModel.setGroupBy(v)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
68
84
|
async clearAsync() {
|
|
69
85
|
const {gridModel} = this;
|
|
70
86
|
if (
|
|
@@ -151,4 +167,26 @@ export class HzObjectModel extends BaseInstanceModel {
|
|
|
151
167
|
this.handleLoadException(e, loadSpec);
|
|
152
168
|
}
|
|
153
169
|
}
|
|
170
|
+
|
|
171
|
+
//----------------------
|
|
172
|
+
// Implementation
|
|
173
|
+
//----------------------
|
|
174
|
+
private processRawData(obj: PlainObject): PlainObject {
|
|
175
|
+
const tail: string = last(obj.name.split('.')),
|
|
176
|
+
className = first(tail.split('['));
|
|
177
|
+
|
|
178
|
+
const owner = className.endsWith('Service')
|
|
179
|
+
? className
|
|
180
|
+
: className.startsWith('xh')
|
|
181
|
+
? 'Hoist'
|
|
182
|
+
: obj.type == 'Cache'
|
|
183
|
+
? 'Hibernate'
|
|
184
|
+
: 'Other';
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
displayName: tail,
|
|
188
|
+
owner: owner,
|
|
189
|
+
...obj
|
|
190
|
+
};
|
|
191
|
+
}
|
|
154
192
|
}
|
|
@@ -9,8 +9,9 @@ import {filler, hframe, placeholder} from '@xh/hoist/cmp/layout';
|
|
|
9
9
|
import {storeFilterField} from '@xh/hoist/cmp/store';
|
|
10
10
|
import {creates, hoistCmp, uses} from '@xh/hoist/core';
|
|
11
11
|
import {button, exportButton} from '@xh/hoist/desktop/cmp/button';
|
|
12
|
-
import {jsonInput} from '@xh/hoist/desktop/cmp/input';
|
|
12
|
+
import {jsonInput, select} from '@xh/hoist/desktop/cmp/input';
|
|
13
13
|
import {panel} from '@xh/hoist/desktop/cmp/panel';
|
|
14
|
+
import {toolbar} from '@xh/hoist/desktop/cmp/toolbar';
|
|
14
15
|
import {recordActionBar} from '@xh/hoist/desktop/cmp/record';
|
|
15
16
|
import {Icon} from '@xh/hoist/icon';
|
|
16
17
|
import {HzObjectModel} from './HzObjectModel';
|
|
@@ -20,26 +21,13 @@ export const hzObjectPanel = hoistCmp.factory({
|
|
|
20
21
|
|
|
21
22
|
render({model}) {
|
|
22
23
|
return panel({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
item: hframe(
|
|
25
|
+
panel({
|
|
26
|
+
item: grid({agOptions: {groupDefaultExpanded: 0}}),
|
|
27
|
+
bbar: bbar()
|
|
27
28
|
}),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
text: 'Clear Hibernate Caches',
|
|
31
|
-
icon: Icon.reset(),
|
|
32
|
-
intent: 'warning',
|
|
33
|
-
tooltip: 'Clear the Hibernate caches using the native Hibernate API',
|
|
34
|
-
onClick: () => model.clearHibernateCachesAsync()
|
|
35
|
-
}),
|
|
36
|
-
filler(),
|
|
37
|
-
gridCountLabel({unit: 'objects'}),
|
|
38
|
-
'-',
|
|
39
|
-
storeFilterField({matchMode: 'any'}),
|
|
40
|
-
exportButton()
|
|
41
|
-
],
|
|
42
|
-
item: hframe(grid(), detailsPanel()),
|
|
29
|
+
detailsPanel()
|
|
30
|
+
),
|
|
43
31
|
mask: 'onLoad',
|
|
44
32
|
ref: model.viewRef
|
|
45
33
|
});
|
|
@@ -49,16 +37,16 @@ export const hzObjectPanel = hoistCmp.factory({
|
|
|
49
37
|
const detailsPanel = hoistCmp.factory({
|
|
50
38
|
model: uses(HzObjectModel),
|
|
51
39
|
render({model}) {
|
|
52
|
-
const
|
|
40
|
+
const record = model.gridModel.selectedRecord;
|
|
53
41
|
return panel({
|
|
54
|
-
title:
|
|
42
|
+
title: record ? `Stats: ${record.data.displayName}` : 'Stats',
|
|
55
43
|
icon: Icon.info(),
|
|
56
44
|
compactHeader: true,
|
|
57
45
|
modelConfig: {
|
|
58
46
|
side: 'right',
|
|
59
47
|
defaultSize: 450
|
|
60
48
|
},
|
|
61
|
-
item:
|
|
49
|
+
item: record
|
|
62
50
|
? panel({
|
|
63
51
|
item: jsonInput({
|
|
64
52
|
readonly: true,
|
|
@@ -66,10 +54,45 @@ const detailsPanel = hoistCmp.factory({
|
|
|
66
54
|
height: '100%',
|
|
67
55
|
showFullscreenButton: false,
|
|
68
56
|
editorProps: {lineNumbers: false},
|
|
69
|
-
value: model.fmtStats(
|
|
57
|
+
value: model.fmtStats(record.raw)
|
|
70
58
|
})
|
|
71
59
|
})
|
|
72
60
|
: placeholder(Icon.grip(), 'Select an object')
|
|
73
61
|
});
|
|
74
62
|
}
|
|
75
63
|
});
|
|
64
|
+
|
|
65
|
+
const bbar = hoistCmp.factory({
|
|
66
|
+
model: uses(HzObjectModel),
|
|
67
|
+
render({model}) {
|
|
68
|
+
return toolbar(
|
|
69
|
+
recordActionBar({
|
|
70
|
+
selModel: model.gridModel.selModel,
|
|
71
|
+
actions: [model.clearAction]
|
|
72
|
+
}),
|
|
73
|
+
'-',
|
|
74
|
+
button({
|
|
75
|
+
text: 'Clear Hibernate Caches',
|
|
76
|
+
icon: Icon.reset(),
|
|
77
|
+
intent: 'warning',
|
|
78
|
+
tooltip: 'Clear the Hibernate caches using the native Hibernate API',
|
|
79
|
+
onClick: () => model.clearHibernateCachesAsync()
|
|
80
|
+
}),
|
|
81
|
+
filler(),
|
|
82
|
+
gridCountLabel({unit: 'objects'}),
|
|
83
|
+
'-',
|
|
84
|
+
select({
|
|
85
|
+
options: [
|
|
86
|
+
{label: 'By Owner', value: 'owner'},
|
|
87
|
+
{label: 'By Type', value: 'type'},
|
|
88
|
+
{label: 'Ungrouped', value: null}
|
|
89
|
+
],
|
|
90
|
+
width: 125,
|
|
91
|
+
bind: 'groupBy',
|
|
92
|
+
hideDropdownIndicator: true
|
|
93
|
+
}),
|
|
94
|
+
storeFilterField({matchMode: 'any'}),
|
|
95
|
+
exportButton()
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
@@ -11,12 +11,19 @@ import {BaseInstanceModel} from '@xh/hoist/admin/tabs/cluster/BaseInstanceModel'
|
|
|
11
11
|
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
12
12
|
import {br, fragment} from '@xh/hoist/cmp/layout';
|
|
13
13
|
import {LoadSpec, managed, XH} from '@xh/hoist/core';
|
|
14
|
-
import {RecordActionSpec} from '@xh/hoist/data';
|
|
14
|
+
import {FilterLike, FilterTestFn, RecordActionSpec} from '@xh/hoist/data';
|
|
15
15
|
import {Icon} from '@xh/hoist/icon';
|
|
16
|
+
import {bindable, makeObservable} from '@xh/hoist/mobx';
|
|
16
17
|
import {pluralize} from '@xh/hoist/utils/js';
|
|
17
|
-
import {isEmpty, lowerFirst} from 'lodash';
|
|
18
|
+
import {capitalize, isEmpty, lowerFirst} from 'lodash';
|
|
18
19
|
|
|
19
20
|
export class ServiceModel extends BaseInstanceModel {
|
|
21
|
+
@bindable
|
|
22
|
+
typeFilter: 'hoist' | 'app' | 'all' = 'all';
|
|
23
|
+
|
|
24
|
+
@bindable.ref
|
|
25
|
+
textFilter: FilterTestFn = null;
|
|
26
|
+
|
|
20
27
|
clearCachesAction: RecordActionSpec = {
|
|
21
28
|
text: 'Clear Caches',
|
|
22
29
|
icon: Icon.reset(),
|
|
@@ -57,10 +64,9 @@ export class ServiceModel extends BaseInstanceModel {
|
|
|
57
64
|
]
|
|
58
65
|
},
|
|
59
66
|
sortBy: 'displayName',
|
|
60
|
-
groupBy: 'provider',
|
|
61
67
|
columns: [
|
|
62
|
-
{field: 'provider', hidden: true},
|
|
63
68
|
{field: 'displayName', flex: 1},
|
|
69
|
+
{field: 'provider'},
|
|
64
70
|
{...timestampNoYear, field: 'lastCachesCleared'},
|
|
65
71
|
{...timestampNoYear, field: 'initializedDate'}
|
|
66
72
|
],
|
|
@@ -72,6 +78,16 @@ export class ServiceModel extends BaseInstanceModel {
|
|
|
72
78
|
]
|
|
73
79
|
});
|
|
74
80
|
|
|
81
|
+
constructor() {
|
|
82
|
+
super();
|
|
83
|
+
makeObservable(this);
|
|
84
|
+
this.addReaction({
|
|
85
|
+
track: () => [this.textFilter, this.typeFilter],
|
|
86
|
+
run: this.applyFilters,
|
|
87
|
+
fireImmediately: true
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
75
91
|
async clearCachesAsync(entireCluster: boolean) {
|
|
76
92
|
const {gridModel, instanceName, loadModel} = this,
|
|
77
93
|
{selectedRecords} = gridModel;
|
|
@@ -132,4 +148,14 @@ export class ServiceModel extends BaseInstanceModel {
|
|
|
132
148
|
const displayName = lowerFirst(r.name.replace('hoistCore', ''));
|
|
133
149
|
return {provider, displayName, ...r};
|
|
134
150
|
}
|
|
151
|
+
|
|
152
|
+
private applyFilters() {
|
|
153
|
+
const {typeFilter, textFilter} = this;
|
|
154
|
+
const filters: FilterLike[] = [textFilter];
|
|
155
|
+
|
|
156
|
+
if (typeFilter == 'hoist' || typeFilter == 'app') {
|
|
157
|
+
filters.push({field: 'provider', op: '=', value: capitalize(typeFilter)});
|
|
158
|
+
}
|
|
159
|
+
this.gridModel.store.setFilter(filters);
|
|
160
|
+
}
|
|
135
161
|
}
|
|
@@ -8,10 +8,12 @@ import {detailsPanel} from '@xh/hoist/admin/tabs/cluster/services/DetailsPanel';
|
|
|
8
8
|
import {grid, gridCountLabel} from '@xh/hoist/cmp/grid';
|
|
9
9
|
import {filler, hframe} from '@xh/hoist/cmp/layout';
|
|
10
10
|
import {storeFilterField} from '@xh/hoist/cmp/store';
|
|
11
|
-
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
11
|
+
import {creates, hoistCmp, uses} from '@xh/hoist/core';
|
|
12
12
|
import {exportButton} from '@xh/hoist/desktop/cmp/button';
|
|
13
13
|
import {panel} from '@xh/hoist/desktop/cmp/panel';
|
|
14
14
|
import {recordActionBar} from '@xh/hoist/desktop/cmp/record';
|
|
15
|
+
import {toolbar} from '@xh/hoist/desktop/cmp/toolbar';
|
|
16
|
+
import {select} from '@xh/hoist/desktop/cmp/input';
|
|
15
17
|
import {ServiceModel} from './ServiceModel';
|
|
16
18
|
|
|
17
19
|
export const servicePanel = hoistCmp.factory({
|
|
@@ -19,25 +21,17 @@ export const servicePanel = hoistCmp.factory({
|
|
|
19
21
|
|
|
20
22
|
render({model}) {
|
|
21
23
|
return panel({
|
|
22
|
-
bbar: [
|
|
23
|
-
recordActionBar({
|
|
24
|
-
selModel: model.gridModel.selModel,
|
|
25
|
-
actions: [model.clearCachesAction, model.clearClusterCachesAction]
|
|
26
|
-
}),
|
|
27
|
-
filler(),
|
|
28
|
-
gridCountLabel({unit: 'service'}),
|
|
29
|
-
'-',
|
|
30
|
-
storeFilterField({matchMode: 'any'}),
|
|
31
|
-
exportButton()
|
|
32
|
-
],
|
|
33
24
|
item: hframe(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
panel({
|
|
26
|
+
item: grid({
|
|
27
|
+
flex: 1,
|
|
28
|
+
agOptions: {
|
|
29
|
+
groupRowRendererParams: {
|
|
30
|
+
innerRenderer: params => params.value + ' Services'
|
|
31
|
+
}
|
|
39
32
|
}
|
|
40
|
-
}
|
|
33
|
+
}),
|
|
34
|
+
bbar: bbar()
|
|
41
35
|
}),
|
|
42
36
|
detailsPanel()
|
|
43
37
|
),
|
|
@@ -46,3 +40,34 @@ export const servicePanel = hoistCmp.factory({
|
|
|
46
40
|
});
|
|
47
41
|
}
|
|
48
42
|
});
|
|
43
|
+
|
|
44
|
+
const bbar = hoistCmp.factory({
|
|
45
|
+
model: uses(ServiceModel),
|
|
46
|
+
render({model}) {
|
|
47
|
+
return toolbar(
|
|
48
|
+
recordActionBar({
|
|
49
|
+
selModel: model.gridModel.selModel,
|
|
50
|
+
actions: [model.clearCachesAction, model.clearClusterCachesAction]
|
|
51
|
+
}),
|
|
52
|
+
filler(),
|
|
53
|
+
gridCountLabel({unit: 'service'}),
|
|
54
|
+
'-',
|
|
55
|
+
select({
|
|
56
|
+
options: [
|
|
57
|
+
{value: 'all', label: 'All'},
|
|
58
|
+
{value: 'app', label: 'App Only'},
|
|
59
|
+
{value: 'hoist', label: 'Hoist Only'}
|
|
60
|
+
],
|
|
61
|
+
width: 125,
|
|
62
|
+
bind: 'typeFilter',
|
|
63
|
+
hideDropdownIndicator: true
|
|
64
|
+
}),
|
|
65
|
+
storeFilterField({
|
|
66
|
+
matchMode: 'any',
|
|
67
|
+
autoApply: false,
|
|
68
|
+
onFilterChange: f => (model.textFilter = f)
|
|
69
|
+
}),
|
|
70
|
+
exportButton()
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
@@ -3,9 +3,12 @@ import { GridModel } from '@xh/hoist/cmp/grid';
|
|
|
3
3
|
import { LoadSpec } from '@xh/hoist/core';
|
|
4
4
|
import { RecordActionSpec } from '@xh/hoist/data';
|
|
5
5
|
export declare class HzObjectModel extends BaseInstanceModel {
|
|
6
|
+
groupBy: 'type' | 'owner';
|
|
6
7
|
clearAction: RecordActionSpec;
|
|
7
8
|
gridModel: GridModel;
|
|
9
|
+
constructor();
|
|
8
10
|
clearAsync(): Promise<void>;
|
|
9
11
|
clearHibernateCachesAsync(): Promise<void>;
|
|
10
12
|
doLoadAsync(loadSpec: LoadSpec): Promise<void>;
|
|
13
|
+
private processRawData;
|
|
11
14
|
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { BaseInstanceModel } from '@xh/hoist/admin/tabs/cluster/BaseInstanceModel';
|
|
2
2
|
import { GridModel } from '@xh/hoist/cmp/grid';
|
|
3
3
|
import { LoadSpec } from '@xh/hoist/core';
|
|
4
|
-
import { RecordActionSpec } from '@xh/hoist/data';
|
|
4
|
+
import { FilterTestFn, RecordActionSpec } from '@xh/hoist/data';
|
|
5
5
|
export declare class ServiceModel extends BaseInstanceModel {
|
|
6
|
+
typeFilter: 'hoist' | 'app' | 'all';
|
|
7
|
+
textFilter: FilterTestFn;
|
|
6
8
|
clearCachesAction: RecordActionSpec;
|
|
7
9
|
clearClusterCachesAction: RecordActionSpec;
|
|
8
10
|
gridModel: GridModel;
|
|
11
|
+
constructor();
|
|
9
12
|
clearCachesAsync(entireCluster: boolean): Promise<void>;
|
|
10
13
|
doLoadAsync(loadSpec: LoadSpec): Promise<void>;
|
|
11
14
|
private processRawData;
|
|
15
|
+
private applyFilters;
|
|
12
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "69.0.0-SNAPSHOT.
|
|
3
|
+
"version": "69.0.0-SNAPSHOT.1727288627891",
|
|
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",
|