@xh/hoist 77.0.0-SNAPSHOT.1761157373322 → 77.0.0-SNAPSHOT.1761257771095
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 +0 -8
- package/admin/jsonsearch/impl/JsonSearchImplModel.ts +1 -1
- package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +1 -1
- package/admin/tabs/cluster/instances/logs/LogDisplayModel.ts +1 -1
- package/admin/tabs/userData/users/UserModel.ts +0 -1
- package/build/types/data/Store.d.ts +0 -1
- package/build/types/data/cube/ViewRowData.d.ts +0 -2
- package/cmp/chart/impl/copyToClipboard.ts +8 -14
- package/cmp/treemap/TreeMap.ts +14 -4
- package/cmp/treemap/TreeMapModel.ts +2 -2
- package/data/Store.ts +3 -13
- package/data/cube/ViewRowData.ts +0 -3
- package/data/cube/row/AggregateRow.ts +0 -1
- package/data/cube/row/BucketRow.ts +0 -1
- package/data/cube/row/LeafRow.ts +1 -1
- package/kit/highcharts/index.ts +2 -2
- package/package.json +1 -1
- package/promise/Promise.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,14 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
## 77.0.0-SNAPSHOT - unreleased
|
|
4
4
|
|
|
5
|
-
## 76.2.0 - 2025-10-22
|
|
6
|
-
|
|
7
|
-
### ⚙️ Technical
|
|
8
|
-
|
|
9
|
-
* Performance improvements to Store for large data sets.
|
|
10
|
-
* New property `cubeRowType` on `ViewRowData` supports identifying bucketed rows.
|
|
11
|
-
* `waitFor` can accept a null value for a timeout.
|
|
12
|
-
|
|
13
5
|
## 76.1.0 - 2025-10-17
|
|
14
6
|
|
|
15
7
|
### 🎁 New Features
|
|
@@ -395,7 +395,7 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
395
395
|
treeStyle: TreeStyle.HIGHLIGHTS_AND_BORDERS,
|
|
396
396
|
autosizeOptions: {mode: 'managed', includeCollapsedChildren: true},
|
|
397
397
|
exportOptions: {filename: exportFilename('activity-summary')},
|
|
398
|
-
emptyText: 'No activity reported
|
|
398
|
+
emptyText: 'No activity reported...',
|
|
399
399
|
sortBy: ['cubeLabel'],
|
|
400
400
|
expandLevel: 1,
|
|
401
401
|
levelLabels: () => ['Total', ...this.groupingChooserModel.valueDisplayNames],
|
|
@@ -136,7 +136,7 @@ export class LogDisplayModel extends HoistModel {
|
|
|
136
136
|
hideHeaders: true,
|
|
137
137
|
rowBorders: false,
|
|
138
138
|
sizingMode: 'tiny',
|
|
139
|
-
emptyText: 'No log entries found
|
|
139
|
+
emptyText: 'No log entries found...',
|
|
140
140
|
sortBy: 'rowNum|asc',
|
|
141
141
|
autosizeOptions: {mode: 'disabled'},
|
|
142
142
|
store: {
|
|
@@ -7,8 +7,6 @@ export declare class ViewRowData {
|
|
|
7
7
|
constructor(id: string);
|
|
8
8
|
/** Unique id. */
|
|
9
9
|
id: string;
|
|
10
|
-
/** Denotes a type for the row */
|
|
11
|
-
cubeRowType: 'leaf' | 'aggregate' | 'bucket';
|
|
12
10
|
/**
|
|
13
11
|
* Label of the row. The dimension value or, for leaf rows. the underlying cubeId.
|
|
14
12
|
* Suitable for display, although apps will typically wish to customize leaf row rendering.
|
|
@@ -24,14 +24,14 @@ export function installCopyToClipboard(Highcharts) {
|
|
|
24
24
|
try {
|
|
25
25
|
const blobPromise = convertChartToPngAsync(this),
|
|
26
26
|
clipboardItemInput = new window.ClipboardItem({
|
|
27
|
-
// Safari requires an unresolved promise.
|
|
27
|
+
// Safari requires an unresolved promise. See https://bugs.webkit.org/show_bug.cgi?id=222262 for discussion
|
|
28
28
|
'image/png': Highcharts.isSafari ? blobPromise : await blobPromise
|
|
29
29
|
});
|
|
30
30
|
await window.navigator.clipboard.write([clipboardItemInput]);
|
|
31
31
|
XH.successToast('Chart copied to clipboard');
|
|
32
32
|
} catch (e) {
|
|
33
33
|
XH.handleException(e, {showAlert: false, logOnServer: true});
|
|
34
|
-
XH.dangerToast('Error: Chart could not be copied.
|
|
34
|
+
XH.dangerToast('Error: Chart could not be copied. This error has been logged.');
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
});
|
|
@@ -41,14 +41,8 @@ export function installCopyToClipboard(Highcharts) {
|
|
|
41
41
|
// Implementation
|
|
42
42
|
//------------------
|
|
43
43
|
async function convertChartToPngAsync(chart) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
chart.options.exporting,
|
|
47
|
-
{},
|
|
48
|
-
() => reject('Cannot fallback to export server'),
|
|
49
|
-
svg => resolve(svg)
|
|
50
|
-
)
|
|
51
|
-
),
|
|
44
|
+
// v12 replacement for getSVGForLocalExport
|
|
45
|
+
const svg = chart.getSVG(),
|
|
52
46
|
svgUrl = svgToDataUrl(svg),
|
|
53
47
|
pngDataUrl = await svgUrlToPngDataUrlAsync(svgUrl),
|
|
54
48
|
ret = await loadBlob(pngDataUrl);
|
|
@@ -65,7 +59,7 @@ function memoryCleanup(svgUrl) {
|
|
|
65
59
|
}
|
|
66
60
|
|
|
67
61
|
/**
|
|
68
|
-
* Convert dataUri
|
|
62
|
+
* Convert dataUri to blob
|
|
69
63
|
*/
|
|
70
64
|
async function loadBlob(dataUrl) {
|
|
71
65
|
const fetched = await fetch(dataUrl);
|
|
@@ -84,7 +78,7 @@ function svgToDataUrl(svg) {
|
|
|
84
78
|
try {
|
|
85
79
|
// Safari requires data URI since it doesn't allow navigation to blob
|
|
86
80
|
// URLs.
|
|
87
|
-
// foreignObjects
|
|
81
|
+
// foreignObjects don't work well in Blobs in Chrome (#14780).
|
|
88
82
|
if (!isWebKitButNotChrome && svg.indexOf('<foreignObject') === -1) {
|
|
89
83
|
return domurl.createObjectURL(
|
|
90
84
|
new window.Blob([svg], {
|
|
@@ -94,12 +88,12 @@ function svgToDataUrl(svg) {
|
|
|
94
88
|
}
|
|
95
89
|
} catch (e) {}
|
|
96
90
|
|
|
97
|
-
//
|
|
91
|
+
// Safari, Firefox, or SVGs with foreignObject fallback
|
|
98
92
|
return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
|
|
99
93
|
}
|
|
100
94
|
|
|
101
95
|
/**
|
|
102
|
-
* Get PNG data:URL from image URL.
|
|
96
|
+
* Get PNG data:URL from image URL.
|
|
103
97
|
*/
|
|
104
98
|
async function svgUrlToPngDataUrlAsync(imageURL, scale = 1) {
|
|
105
99
|
const img = new window.Image(),
|
package/cmp/treemap/TreeMap.ts
CHANGED
|
@@ -172,8 +172,6 @@ class TreeMapLocalModel extends HoistModel {
|
|
|
172
172
|
this.prevConfig = cloneDeep(chartCfg);
|
|
173
173
|
this.createChart(config);
|
|
174
174
|
}
|
|
175
|
-
|
|
176
|
-
this.updateLabelVisibility();
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
createChart(config) {
|
|
@@ -195,13 +193,25 @@ class TreeMapLocalModel extends HoistModel {
|
|
|
195
193
|
|
|
196
194
|
assign(config.chart, parentDims, {renderTo: chartElem});
|
|
197
195
|
this.withDebug(['Creating new TreeMap', `${newData.length} records`], () => {
|
|
198
|
-
this.chart = Highcharts.chart(config)
|
|
196
|
+
this.chart = Highcharts.chart(config, () => {
|
|
197
|
+
this.updateLabelVisibility();
|
|
198
|
+
});
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
@logWithDebug
|
|
203
203
|
reloadSeriesData(newData) {
|
|
204
|
-
this.chart
|
|
204
|
+
if (!this.chart) return;
|
|
205
|
+
|
|
206
|
+
this.chart.series[0].setData(newData, true, false);
|
|
207
|
+
|
|
208
|
+
// Use an event handler to trigger label updates
|
|
209
|
+
// This approach was required when `cluster` series option is enabled
|
|
210
|
+
const onRedraw = () => {
|
|
211
|
+
this.updateLabelVisibility();
|
|
212
|
+
Highcharts.removeEvent(this.chart, 'redraw', onRedraw);
|
|
213
|
+
};
|
|
214
|
+
Highcharts.addEvent(this.chart, 'redraw', onRedraw);
|
|
205
215
|
}
|
|
206
216
|
|
|
207
217
|
startResize = ({width, height}) => {
|
|
@@ -465,7 +465,7 @@ export class TreeMapModel extends HoistModel {
|
|
|
465
465
|
//----------------------
|
|
466
466
|
defaultOnClick = (record, e) => {
|
|
467
467
|
const {gridModel} = this;
|
|
468
|
-
if (!gridModel) return;
|
|
468
|
+
if (!gridModel || !record) return;
|
|
469
469
|
|
|
470
470
|
// Select nodes in grid
|
|
471
471
|
const {selModel} = gridModel;
|
|
@@ -477,7 +477,7 @@ export class TreeMapModel extends HoistModel {
|
|
|
477
477
|
};
|
|
478
478
|
|
|
479
479
|
defaultOnDoubleClick = record => {
|
|
480
|
-
if (!this.gridModel?.treeMode || isEmpty(record
|
|
480
|
+
if (!this.gridModel?.treeMode || isEmpty(record?.children)) return;
|
|
481
481
|
this.toggleNodeExpanded(record.treePath);
|
|
482
482
|
};
|
|
483
483
|
}
|
package/data/Store.ts
CHANGED
|
@@ -1041,36 +1041,26 @@ export class Store extends HoistBase {
|
|
|
1041
1041
|
return ret;
|
|
1042
1042
|
}
|
|
1043
1043
|
|
|
1044
|
-
private createRecords(
|
|
1045
|
-
rawData: PlainObject[],
|
|
1046
|
-
parent: StoreRecord,
|
|
1047
|
-
recordMap: Map<StoreRecordId, StoreRecord> = new Map(),
|
|
1048
|
-
summaryRecordIds: Set<StoreRecordId> = this.summaryRecordIds
|
|
1049
|
-
) {
|
|
1044
|
+
private createRecords(rawData: PlainObject[], parent: StoreRecord, recordMap = new Map()) {
|
|
1050
1045
|
const {loadTreeData, loadTreeDataFrom} = this;
|
|
1051
|
-
|
|
1052
1046
|
rawData.forEach(raw => {
|
|
1053
1047
|
const rec = this.createRecord(raw, parent),
|
|
1054
1048
|
{id} = rec;
|
|
1055
1049
|
|
|
1056
1050
|
throwIf(
|
|
1057
|
-
recordMap.has(id) ||
|
|
1051
|
+
recordMap.has(id) || this.summaryRecords?.some(it => it.id === id),
|
|
1058
1052
|
`ID ${id} is not unique. Use the 'Store.idSpec' config to resolve a unique ID for each record.`
|
|
1059
1053
|
);
|
|
1060
1054
|
|
|
1061
1055
|
recordMap.set(id, rec);
|
|
1062
1056
|
|
|
1063
1057
|
if (loadTreeData && raw[loadTreeDataFrom]) {
|
|
1064
|
-
this.createRecords(raw[loadTreeDataFrom], rec, recordMap
|
|
1058
|
+
this.createRecords(raw[loadTreeDataFrom], rec, recordMap);
|
|
1065
1059
|
}
|
|
1066
1060
|
});
|
|
1067
1061
|
return recordMap;
|
|
1068
1062
|
}
|
|
1069
1063
|
|
|
1070
|
-
private get summaryRecordIds(): Set<StoreRecordId> {
|
|
1071
|
-
return new Set(this.summaryRecords?.map(it => it.id) ?? []);
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
1064
|
private parseRaw(data: PlainObject): PlainObject {
|
|
1075
1065
|
// a) create/prepare the data object
|
|
1076
1066
|
const ret = Object.create(this._dataDefaults);
|
package/data/cube/ViewRowData.ts
CHANGED
|
@@ -19,9 +19,6 @@ export class ViewRowData {
|
|
|
19
19
|
/** Unique id. */
|
|
20
20
|
id: string;
|
|
21
21
|
|
|
22
|
-
/** Denotes a type for the row */
|
|
23
|
-
cubeRowType: 'leaf' | 'aggregate' | 'bucket';
|
|
24
|
-
|
|
25
22
|
/**
|
|
26
23
|
* Label of the row. The dimension value or, for leaf rows. the underlying cubeId.
|
|
27
24
|
* Suitable for display, although apps will typically wish to customize leaf row rendering.
|
package/data/cube/row/LeafRow.ts
CHANGED
|
@@ -33,8 +33,8 @@ export class LeafRow extends BaseRow {
|
|
|
33
33
|
|
|
34
34
|
constructor(view: View, id: string, rawRecord: StoreRecord) {
|
|
35
35
|
super(view, id);
|
|
36
|
+
|
|
36
37
|
this.cubeRecordId = rawRecord.id;
|
|
37
|
-
this.data.cubeRowType = 'leaf';
|
|
38
38
|
this.data.cubeLabel = rawRecord.id.toString();
|
|
39
39
|
this.data.cubeDimension = null;
|
|
40
40
|
|
package/kit/highcharts/index.ts
CHANGED
|
@@ -9,8 +9,8 @@ import {checkVersion, logError} from '@xh/hoist/utils/js';
|
|
|
9
9
|
|
|
10
10
|
export let Highcharts = null;
|
|
11
11
|
|
|
12
|
-
const MIN_VERSION = '
|
|
13
|
-
const MAX_VERSION = '
|
|
12
|
+
const MIN_VERSION = '12.4.0';
|
|
13
|
+
const MAX_VERSION = '12.*.*';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Expose application versions of Highcharts to Hoist.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "77.0.0-SNAPSHOT.
|
|
3
|
+
"version": "77.0.0-SNAPSHOT.1761257771095",
|
|
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
|
@@ -132,15 +132,15 @@ export function waitFor(
|
|
|
132
132
|
condition: () => boolean,
|
|
133
133
|
{interval = 50, timeout = 5 * SECONDS}: {interval?: number; timeout?: number} = {}
|
|
134
134
|
): Promise<void> {
|
|
135
|
-
if (interval <= 0) throw new Error('Invalid interval');
|
|
136
|
-
if (timeout
|
|
135
|
+
if (!isNumber(interval) || interval <= 0) throw new Error('Invalid interval');
|
|
136
|
+
if (!isNumber(timeout) || timeout <= 0) throw new Error('Invalid timeout');
|
|
137
137
|
|
|
138
138
|
const startTime = Date.now();
|
|
139
139
|
return new Promise((resolve, reject) => {
|
|
140
140
|
const resolveOnMet = () => {
|
|
141
141
|
if (condition()) {
|
|
142
142
|
resolve();
|
|
143
|
-
} else if (
|
|
143
|
+
} else if (olderThan(startTime, timeout)) {
|
|
144
144
|
reject(Exception.timeout({interval: Date.now() - startTime}));
|
|
145
145
|
} else {
|
|
146
146
|
setTimeout(resolveOnMet, interval);
|