@xh/hoist 73.0.0-SNAPSHOT.1745976013413 → 73.0.0-SNAPSHOT.1746050068813
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 +10 -1
- package/admin/AdminUtils.ts +5 -0
- package/admin/App.scss +6 -0
- package/admin/AppModel.ts +19 -7
- package/admin/{tabs/client/clients/ClientsColumns.ts → columns/Clients.ts} +20 -53
- package/admin/columns/Core.ts +34 -35
- package/admin/columns/Rest.ts +8 -0
- package/admin/columns/Tracking.ts +144 -42
- package/admin/columns/index.ts +1 -0
- package/admin/tabs/activity/tracking/ActivityTracking.scss +18 -0
- package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +309 -210
- package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +81 -51
- package/admin/tabs/activity/tracking/chart/AggChartModel.ts +218 -0
- package/admin/tabs/activity/tracking/chart/AggChartPanel.ts +61 -0
- package/admin/tabs/activity/tracking/datafields/DataFieldsEditor.ts +147 -0
- package/admin/tabs/activity/tracking/datafields/DataFieldsEditorModel.ts +133 -0
- package/admin/tabs/activity/tracking/detail/ActivityDetailModel.ts +123 -59
- package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +110 -54
- package/admin/tabs/client/ClientTab.ts +2 -4
- package/admin/tabs/client/clients/ClientsModel.ts +10 -11
- package/admin/tabs/cluster/instances/memory/MemoryMonitorModel.ts +1 -2
- package/admin/tabs/general/GeneralTab.ts +2 -0
- package/build/types/admin/AdminUtils.d.ts +2 -0
- package/build/types/admin/AppModel.d.ts +4 -1
- package/build/types/admin/{tabs/client/clients/ClientsColumns.d.ts → columns/Clients.d.ts} +3 -7
- package/build/types/admin/columns/Core.d.ts +5 -5
- package/build/types/admin/columns/Rest.d.ts +1 -0
- package/build/types/admin/columns/Tracking.d.ts +13 -4
- package/build/types/admin/columns/index.d.ts +1 -0
- package/build/types/admin/tabs/activity/tracking/ActivityTrackingModel.d.ts +31 -28
- package/build/types/admin/tabs/activity/tracking/chart/AggChartModel.d.ts +33 -0
- package/build/types/admin/tabs/activity/tracking/chart/AggChartPanel.d.ts +2 -0
- package/build/types/admin/tabs/activity/tracking/datafields/DataFieldsEditor.d.ts +2 -0
- package/build/types/admin/tabs/activity/tracking/datafields/DataFieldsEditorModel.d.ts +46 -0
- package/build/types/admin/tabs/activity/tracking/detail/ActivityDetailModel.d.ts +14 -1
- package/build/types/cmp/form/FormModel.d.ts +19 -30
- package/build/types/cmp/form/field/SubformsFieldModel.d.ts +25 -22
- package/build/types/core/HoistBase.d.ts +2 -2
- package/build/types/data/cube/CubeField.d.ts +4 -5
- package/build/types/desktop/cmp/appOption/AutoRefreshAppOption.d.ts +3 -3
- package/build/types/desktop/cmp/appOption/ThemeAppOption.d.ts +3 -3
- package/cmp/error/ErrorBoundaryModel.ts +1 -1
- package/cmp/form/FormModel.ts +20 -28
- package/cmp/form/field/SubformsFieldModel.ts +28 -22
- package/cmp/grid/columns/DatesTimes.ts +1 -2
- package/cmp/grid/impl/GridHScrollbar.ts +1 -2
- package/core/HoistBase.ts +12 -12
- package/data/cube/CubeField.ts +17 -18
- package/package.json +1 -1
- package/svc/TrackService.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/admin/tabs/activity/tracking/charts/ChartsModel.ts +0 -218
- package/admin/tabs/activity/tracking/charts/ChartsPanel.ts +0 -76
- package/build/types/admin/tabs/activity/tracking/charts/ChartsModel.d.ts +0 -34
- package/build/types/admin/tabs/activity/tracking/charts/ChartsPanel.d.ts +0 -2
- /package/admin/tabs/{client → general}/feedback/FeedbackPanel.ts +0 -0
- /package/build/types/admin/tabs/{client → general}/feedback/FeedbackPanel.d.ts +0 -0
|
@@ -1,218 +0,0 @@
|
|
|
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
|
-
import {ChartModel} from '@xh/hoist/cmp/chart';
|
|
8
|
-
import {br, fragment} from '@xh/hoist/cmp/layout';
|
|
9
|
-
import {HoistModel, managed, lookup} from '@xh/hoist/core';
|
|
10
|
-
import {capitalizeWords, fmtDate} from '@xh/hoist/format';
|
|
11
|
-
import {bindable, makeObservable} from '@xh/hoist/mobx';
|
|
12
|
-
import {LocalDate} from '@xh/hoist/utils/datetime';
|
|
13
|
-
import {filter, sortBy, isEmpty} from 'lodash';
|
|
14
|
-
import moment from 'moment';
|
|
15
|
-
import {PanelModel} from '@xh/hoist/desktop/cmp/panel';
|
|
16
|
-
import {ActivityTrackingModel} from '../ActivityTrackingModel';
|
|
17
|
-
import {ONE_DAY} from '@xh/hoist/utils/datetime/DateTimeUtils';
|
|
18
|
-
|
|
19
|
-
export class ChartsModel extends HoistModel {
|
|
20
|
-
@managed panelModel = new PanelModel({
|
|
21
|
-
modalSupport: {width: '90vw', height: '60vh'},
|
|
22
|
-
side: 'bottom',
|
|
23
|
-
defaultSize: 370
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
@lookup(ActivityTrackingModel)
|
|
27
|
-
activityTrackingModel: ActivityTrackingModel;
|
|
28
|
-
|
|
29
|
-
/** metric to chart on Y axis - one of:
|
|
30
|
-
* + entryCount - count of total track log entries within the primary dim group.
|
|
31
|
-
* + count - count of unique secondary dim values within the primary dim group.
|
|
32
|
-
* + elapsed - avg elapsed time in ms for the primary dim group.
|
|
33
|
-
*/
|
|
34
|
-
@bindable
|
|
35
|
-
metric: 'entryCount' | 'count' | 'elapsed' = 'entryCount';
|
|
36
|
-
|
|
37
|
-
/** show weekends on the activity chart */
|
|
38
|
-
@bindable
|
|
39
|
-
incWeekends: boolean = false;
|
|
40
|
-
|
|
41
|
-
@managed
|
|
42
|
-
categoryChartModel: ChartModel = new ChartModel({
|
|
43
|
-
highchartsConfig: {
|
|
44
|
-
chart: {type: 'column', animation: false},
|
|
45
|
-
plotOptions: {column: {animation: false}},
|
|
46
|
-
legend: {enabled: false},
|
|
47
|
-
title: {text: null},
|
|
48
|
-
xAxis: {type: 'category', title: {}},
|
|
49
|
-
yAxis: [{title: {text: null}, allowDecimals: false}]
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
@managed
|
|
54
|
-
timeseriesChartModel: ChartModel = new ChartModel({
|
|
55
|
-
highchartsConfig: {
|
|
56
|
-
chart: {type: 'line', animation: false},
|
|
57
|
-
plotOptions: {
|
|
58
|
-
line: {
|
|
59
|
-
events: {
|
|
60
|
-
click: e => this.selectRow(e)
|
|
61
|
-
},
|
|
62
|
-
width: 1,
|
|
63
|
-
animation: false,
|
|
64
|
-
step: 'left'
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
legend: {enabled: false},
|
|
68
|
-
title: {text: null},
|
|
69
|
-
xAxis: {
|
|
70
|
-
type: 'datetime',
|
|
71
|
-
title: {},
|
|
72
|
-
units: [
|
|
73
|
-
['day', [1]],
|
|
74
|
-
['week', [2]],
|
|
75
|
-
['month', [1]]
|
|
76
|
-
],
|
|
77
|
-
labels: {
|
|
78
|
-
formatter: function () {
|
|
79
|
-
return fmtDate(this.value, 'D MMM');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
yAxis: [{title: {text: null}, allowDecimals: false}]
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
get showAsTimeseries(): boolean {
|
|
88
|
-
return this.dimensions[0] === 'day';
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get chartModel(): ChartModel {
|
|
92
|
-
return this.showAsTimeseries ? this.timeseriesChartModel : this.categoryChartModel;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get primaryDim(): string {
|
|
96
|
-
return this.dimensions[0];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
get secondaryDim(): string {
|
|
100
|
-
const {dimensions} = this;
|
|
101
|
-
return dimensions.length >= 2 ? dimensions[1] : null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get data() {
|
|
105
|
-
const roots = this.activityTrackingModel.gridModel.store.allRootRecords;
|
|
106
|
-
return roots.length ? roots[0].children : [];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
get dimensions() {
|
|
110
|
-
return this.activityTrackingModel.dimensions;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
constructor() {
|
|
114
|
-
super();
|
|
115
|
-
makeObservable(this);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
getLabelForMetric(metric, multiline) {
|
|
119
|
-
switch (metric) {
|
|
120
|
-
case 'count':
|
|
121
|
-
return multiline
|
|
122
|
-
? fragment(`Unique`, br(), `${this.getUnitsForDim(this.secondaryDim)} Count`)
|
|
123
|
-
: `Unique ${this.getUnitsForDim(this.secondaryDim)} Count`;
|
|
124
|
-
case 'entryCount':
|
|
125
|
-
return multiline ? fragment('Total', br(), 'Entry Count') : 'Total Entry Count';
|
|
126
|
-
case 'elapsed':
|
|
127
|
-
return 'Elapsed ms';
|
|
128
|
-
default:
|
|
129
|
-
return '???';
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
//-----------------
|
|
134
|
-
// Implementation
|
|
135
|
-
//-----------------
|
|
136
|
-
|
|
137
|
-
private selectRow(e) {
|
|
138
|
-
const date = moment(e.point.x).format('YYYY-MM-DD'),
|
|
139
|
-
id = `root>>day=[${date}]`;
|
|
140
|
-
this.activityTrackingModel.gridModel.selectAsync(id);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
override onLinked() {
|
|
144
|
-
this.addReaction({
|
|
145
|
-
track: () => [this.data, this.metric, this.incWeekends],
|
|
146
|
-
run: () => this.loadChart()
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
private loadChart() {
|
|
151
|
-
const {showAsTimeseries, chartModel, primaryDim} = this,
|
|
152
|
-
series = this.getSeriesData();
|
|
153
|
-
|
|
154
|
-
if (!showAsTimeseries) {
|
|
155
|
-
chartModel.updateHighchartsConfig({
|
|
156
|
-
xAxis: {title: {text: this.getUnitsForDim(primaryDim)}}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
chartModel.setSeries(series);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private getSeriesData() {
|
|
164
|
-
const {data, metric, primaryDim, showAsTimeseries} = this,
|
|
165
|
-
metricLabel = this.getLabelForMetric(metric, false);
|
|
166
|
-
let sortedData = sortBy(data, aggRow => {
|
|
167
|
-
const {cubeLabel} = aggRow.data;
|
|
168
|
-
switch (primaryDim) {
|
|
169
|
-
case 'day':
|
|
170
|
-
return LocalDate.from(cubeLabel).timestamp;
|
|
171
|
-
case 'month':
|
|
172
|
-
return moment(cubeLabel, 'MMM YYYY').valueOf();
|
|
173
|
-
default:
|
|
174
|
-
return cubeLabel;
|
|
175
|
-
}
|
|
176
|
-
}),
|
|
177
|
-
chartData = sortedData.map(aggRow => {
|
|
178
|
-
const {cubeLabel} = aggRow.data,
|
|
179
|
-
xVal = showAsTimeseries ? LocalDate.from(cubeLabel).timestamp : cubeLabel,
|
|
180
|
-
yVal = Math.round(aggRow.data[metric]);
|
|
181
|
-
return [xVal, yVal];
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Insert data where no activity was logged
|
|
185
|
-
if (showAsTimeseries) {
|
|
186
|
-
const fillData = [];
|
|
187
|
-
for (let i = 1; i < chartData.length; i++) {
|
|
188
|
-
const skippedDayCount = Math.floor(
|
|
189
|
-
(chartData[i][0] - chartData[i - 1][0]) / ONE_DAY - 1
|
|
190
|
-
);
|
|
191
|
-
if (skippedDayCount > 0) {
|
|
192
|
-
for (let j = 1; j <= skippedDayCount; j++) {
|
|
193
|
-
const skippedDate = chartData[i - 1][0] + j * ONE_DAY;
|
|
194
|
-
fillData.push([skippedDate, 0]);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (!isEmpty(fillData)) {
|
|
199
|
-
chartData.push(...fillData);
|
|
200
|
-
chartData = sortBy(chartData, data => data[0]);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (!this.incWeekends) {
|
|
204
|
-
chartData = filter(chartData, data => LocalDate.from(data[0]).isWeekday);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return [{name: metricLabel, data: chartData}];
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
private getUnitsForDim(dim) {
|
|
211
|
-
return (
|
|
212
|
-
{
|
|
213
|
-
username: 'User',
|
|
214
|
-
msg: 'Message'
|
|
215
|
-
}[dim] ?? capitalizeWords(dim)
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
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
|
-
import {chart} from '@xh/hoist/cmp/chart';
|
|
8
|
-
import {hoistCmp, creates} from '@xh/hoist/core';
|
|
9
|
-
import {button} from '@xh/hoist/desktop/cmp/button';
|
|
10
|
-
import {buttonGroupInput} from '@xh/hoist/desktop/cmp/input';
|
|
11
|
-
import {panel} from '@xh/hoist/desktop/cmp/panel';
|
|
12
|
-
import {Icon} from '@xh/hoist/icon/Icon';
|
|
13
|
-
import {toolbar} from '@xh/hoist/desktop/cmp/toolbar';
|
|
14
|
-
import {checkbox} from '@xh/hoist/desktop/cmp/input';
|
|
15
|
-
import {hspacer} from '@xh/hoist/cmp/layout';
|
|
16
|
-
import {ChartsModel} from './ChartsModel';
|
|
17
|
-
|
|
18
|
-
export const chartsPanel = hoistCmp.factory({
|
|
19
|
-
model: creates(ChartsModel),
|
|
20
|
-
render({model, ...props}) {
|
|
21
|
-
const {chartModel, activityTrackingModel, panelModel} = model,
|
|
22
|
-
{isModal} = panelModel;
|
|
23
|
-
return panel({
|
|
24
|
-
title: !isModal ? 'Aggregate Activity Chart' : activityTrackingModel.queryDisplayString,
|
|
25
|
-
icon: Icon.chartBar(),
|
|
26
|
-
model: panelModel,
|
|
27
|
-
compactHeader: !isModal,
|
|
28
|
-
item: chart({model: chartModel}),
|
|
29
|
-
bbar: bbar(),
|
|
30
|
-
height: '100%',
|
|
31
|
-
...props
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const bbar = hoistCmp.factory<ChartsModel>(() =>
|
|
37
|
-
toolbar(metricSwitcher({multiline: true}), hspacer(), incWeekendsCheckbox())
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const incWeekendsCheckbox = hoistCmp.factory<ChartsModel>(({model}) =>
|
|
41
|
-
checkbox({
|
|
42
|
-
omit: !model.showAsTimeseries,
|
|
43
|
-
bind: 'incWeekends',
|
|
44
|
-
label: 'Inc Wknds'
|
|
45
|
-
})
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const metricSwitcher = hoistCmp.factory<ChartsModel>(({model, multiline}) => {
|
|
49
|
-
return buttonGroupInput({
|
|
50
|
-
className: 'xh-admin-activity-panel__metric-switcher',
|
|
51
|
-
bind: 'metric',
|
|
52
|
-
outlined: true,
|
|
53
|
-
flex: 2,
|
|
54
|
-
items: [
|
|
55
|
-
button({
|
|
56
|
-
text: model.getLabelForMetric('entryCount', multiline),
|
|
57
|
-
value: 'entryCount',
|
|
58
|
-
outlined: true,
|
|
59
|
-
flex: 1
|
|
60
|
-
}),
|
|
61
|
-
button({
|
|
62
|
-
text: model.getLabelForMetric('count', multiline),
|
|
63
|
-
value: 'count',
|
|
64
|
-
outlined: true,
|
|
65
|
-
flex: 1,
|
|
66
|
-
omit: !model.secondaryDim
|
|
67
|
-
}),
|
|
68
|
-
button({
|
|
69
|
-
text: model.getLabelForMetric('elapsed', multiline),
|
|
70
|
-
value: 'elapsed',
|
|
71
|
-
outlined: true,
|
|
72
|
-
flex: 1
|
|
73
|
-
})
|
|
74
|
-
]
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import { ChartModel } from '@xh/hoist/cmp/chart';
|
|
3
|
-
import { HoistModel } from '@xh/hoist/core';
|
|
4
|
-
import { PanelModel } from '@xh/hoist/desktop/cmp/panel';
|
|
5
|
-
import { ActivityTrackingModel } from '../ActivityTrackingModel';
|
|
6
|
-
export declare class ChartsModel extends HoistModel {
|
|
7
|
-
panelModel: PanelModel;
|
|
8
|
-
activityTrackingModel: ActivityTrackingModel;
|
|
9
|
-
/** metric to chart on Y axis - one of:
|
|
10
|
-
* + entryCount - count of total track log entries within the primary dim group.
|
|
11
|
-
* + count - count of unique secondary dim values within the primary dim group.
|
|
12
|
-
* + elapsed - avg elapsed time in ms for the primary dim group.
|
|
13
|
-
*/
|
|
14
|
-
metric: 'entryCount' | 'count' | 'elapsed';
|
|
15
|
-
/** show weekends on the activity chart */
|
|
16
|
-
incWeekends: boolean;
|
|
17
|
-
categoryChartModel: ChartModel;
|
|
18
|
-
timeseriesChartModel: ChartModel;
|
|
19
|
-
get showAsTimeseries(): boolean;
|
|
20
|
-
get chartModel(): ChartModel;
|
|
21
|
-
get primaryDim(): string;
|
|
22
|
-
get secondaryDim(): string;
|
|
23
|
-
get data(): import("../../../../../data").StoreRecord[];
|
|
24
|
-
get dimensions(): string[];
|
|
25
|
-
constructor();
|
|
26
|
-
getLabelForMetric(metric: any, multiline: any): string | import("react").ReactElement<{
|
|
27
|
-
children?: import("react").ReactNode;
|
|
28
|
-
}, any>;
|
|
29
|
-
private selectRow;
|
|
30
|
-
onLinked(): void;
|
|
31
|
-
private loadChart;
|
|
32
|
-
private getSeriesData;
|
|
33
|
-
private getUnitsForDim;
|
|
34
|
-
}
|
|
File without changes
|
|
File without changes
|