@xh/hoist 63.0.2 → 63.1.0
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 +12 -0
- package/cmp/grid/Grid.ts +4 -4
- package/cmp/grid/GridModel.ts +2 -2
- package/cmp/zoneGrid/ZoneGridModel.ts +2 -2
- package/data/Store.ts +40 -24
- package/kit/blueprint/index.ts +1 -0
- package/package.json +1 -1
- package/svc/GridAutosizeService.ts +2 -2
- package/svc/GridExportService.ts +12 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 63.1.0 - 2024-04-23
|
|
4
|
+
|
|
5
|
+
### 🎁 New Features
|
|
6
|
+
|
|
7
|
+
* `Store` now supports multiple `summaryRecords`.
|
|
8
|
+
|
|
9
|
+
## 63.0.3 - 2024-04-16
|
|
10
|
+
|
|
11
|
+
### 🐞 Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Import BPs default datetime package css in addition to datetime2 css to support BP datetime components.
|
|
14
|
+
|
|
3
15
|
## 63.0.2 - 2024-04-16
|
|
4
16
|
|
|
5
17
|
### 🐞 Bug Fixes
|
package/cmp/grid/Grid.ts
CHANGED
|
@@ -326,7 +326,7 @@ export class GridLocalModel extends HoistModel {
|
|
|
326
326
|
const {model} = this,
|
|
327
327
|
{store} = model;
|
|
328
328
|
return {
|
|
329
|
-
track: () => [model.isReady, store._filtered, model.showSummary, store.
|
|
329
|
+
track: () => [model.isReady, store._filtered, model.showSummary, store.summaryRecords],
|
|
330
330
|
run: () => {
|
|
331
331
|
if (model.isReady) this.syncData();
|
|
332
332
|
}
|
|
@@ -583,11 +583,11 @@ export class GridLocalModel extends HoistModel {
|
|
|
583
583
|
pinnedTopRowData = agGridModel.getPinnedTopRowData().filter(filterSummaryFn),
|
|
584
584
|
pinnedBottomRowData = agGridModel.getPinnedBottomRowData().filter(filterSummaryFn);
|
|
585
585
|
|
|
586
|
-
if (showSummary && store.
|
|
586
|
+
if (showSummary && !isEmpty(store.summaryRecords)) {
|
|
587
587
|
if (showSummary === 'bottom') {
|
|
588
|
-
pinnedBottomRowData.push(store.
|
|
588
|
+
pinnedBottomRowData.push(...store.summaryRecords);
|
|
589
589
|
} else {
|
|
590
|
-
pinnedTopRowData.unshift(store.
|
|
590
|
+
pinnedTopRowData.unshift(...store.summaryRecords);
|
|
591
591
|
}
|
|
592
592
|
}
|
|
593
593
|
|
package/cmp/grid/GridModel.ts
CHANGED
|
@@ -123,7 +123,7 @@ export interface GridConfig {
|
|
|
123
123
|
/** True if grid is a tree grid (default false). */
|
|
124
124
|
treeMode?: boolean;
|
|
125
125
|
|
|
126
|
-
/** Location for
|
|
126
|
+
/** Location for docked summary row(s). Requires `store.summaryRecords` to be populated. */
|
|
127
127
|
showSummary?: boolean | VSide;
|
|
128
128
|
|
|
129
129
|
/** Specification of selection behavior. Defaults to 'single' (desktop) and 'disabled' (mobile) */
|
|
@@ -1038,7 +1038,7 @@ export class GridModel extends HoistModel {
|
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
1040
1040
|
/** Load the underlying store. */
|
|
1041
|
-
loadData(rawData: any[], rawSummaryData?: PlainObject) {
|
|
1041
|
+
loadData(rawData: any[], rawSummaryData?: Some<PlainObject>) {
|
|
1042
1042
|
return this.store.loadData(rawData, rawSummaryData);
|
|
1043
1043
|
}
|
|
1044
1044
|
|
|
@@ -102,7 +102,7 @@ export interface ZoneGridConfig {
|
|
|
102
102
|
/** True if grid is a tree grid (default false). */
|
|
103
103
|
treeMode?: boolean;
|
|
104
104
|
|
|
105
|
-
/** Location for
|
|
105
|
+
/** Location for docked summary row(s). Requires `store.summaryRecords` to be populated. */
|
|
106
106
|
showSummary?: boolean | VSide;
|
|
107
107
|
|
|
108
108
|
/** Specification of selection behavior. Defaults to 'single' (desktop) and 'disabled' (mobile) */
|
|
@@ -520,7 +520,7 @@ export class ZoneGridModel extends HoistModel {
|
|
|
520
520
|
return this.gridModel.doLoadAsync(loadSpec);
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
-
loadData(rawData: any[], rawSummaryData?: PlainObject) {
|
|
523
|
+
loadData(rawData: any[], rawSummaryData?: Some<PlainObject>) {
|
|
524
524
|
return this.gridModel.loadData(rawData, rawSummaryData);
|
|
525
525
|
}
|
|
526
526
|
|
package/data/Store.ts
CHANGED
|
@@ -21,7 +21,9 @@ import {
|
|
|
21
21
|
isString,
|
|
22
22
|
values,
|
|
23
23
|
remove as lodashRemove,
|
|
24
|
-
uniq
|
|
24
|
+
uniq,
|
|
25
|
+
first,
|
|
26
|
+
some
|
|
25
27
|
} from 'lodash';
|
|
26
28
|
import {Field, FieldSpec} from './Field';
|
|
27
29
|
import {parseFilter} from './filter/Utils';
|
|
@@ -143,11 +145,11 @@ export interface StoreTransaction {
|
|
|
143
145
|
remove?: StoreRecordId[];
|
|
144
146
|
|
|
145
147
|
/**
|
|
146
|
-
* Update to the dedicated summary
|
|
148
|
+
* Update to the dedicated summary record(s) for this store. If the store has its
|
|
147
149
|
* `loadRootAsSummary` flag set to true, the summary record should instead be provided via the
|
|
148
150
|
* `update` property.
|
|
149
151
|
*/
|
|
150
|
-
rawSummaryData?: PlainObject
|
|
152
|
+
rawSummaryData?: Some<PlainObject>;
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
export interface ChildRawData {
|
|
@@ -197,9 +199,9 @@ export class Store extends HoistBase {
|
|
|
197
199
|
@observable
|
|
198
200
|
lastLoaded: number = null;
|
|
199
201
|
|
|
200
|
-
/**
|
|
202
|
+
/** Records containing summary data. */
|
|
201
203
|
@observable.ref
|
|
202
|
-
|
|
204
|
+
summaryRecords: StoreRecord[] = null;
|
|
203
205
|
|
|
204
206
|
/** @internal - used internally by any StoreFilterField bound to this store. */
|
|
205
207
|
@observable
|
|
@@ -290,23 +292,25 @@ export class Store extends HoistBase {
|
|
|
290
292
|
* created with its `loadRootAsSummary` flag set to true.
|
|
291
293
|
*
|
|
292
294
|
* @param rawData - source data to load
|
|
293
|
-
* @param rawSummaryData - source data for
|
|
294
|
-
*
|
|
295
|
+
* @param rawSummaryData - source data for optional summary record(s), representing
|
|
296
|
+
* custom aggregations for the dataset, if desired.
|
|
295
297
|
*/
|
|
296
298
|
@action
|
|
297
299
|
@logWithDebug
|
|
298
|
-
loadData(rawData: PlainObject[], rawSummaryData?: PlainObject) {
|
|
300
|
+
loadData(rawData: PlainObject[], rawSummaryData?: Some<PlainObject>) {
|
|
299
301
|
// Extract rootSummary if loading non-empty data[] (i.e. not clearing) and loadRootAsSummary
|
|
300
302
|
if (rawData.length !== 0 && this.loadRootAsSummary) {
|
|
301
303
|
throwIf(
|
|
302
|
-
rawData.length !== 1 || rawSummaryData,
|
|
304
|
+
rawData.length !== 1 || !isEmpty(rawSummaryData),
|
|
303
305
|
'Incorrect call to loadData with loadRootAsSummary=true. Summary data should be in a single root node with top-level row data as its children.'
|
|
304
306
|
);
|
|
305
307
|
rawSummaryData = rawData[0];
|
|
306
308
|
rawData = rawData[0].children ?? [];
|
|
307
309
|
}
|
|
308
310
|
|
|
309
|
-
this.
|
|
311
|
+
this.summaryRecords = rawSummaryData
|
|
312
|
+
? castArray(rawSummaryData).map(it => this.createRecord(it, null, true))
|
|
313
|
+
: null;
|
|
310
314
|
|
|
311
315
|
const records = this.createRecords(rawData, null);
|
|
312
316
|
this._committed = this._current = this._committed.withNewRecords(records);
|
|
@@ -381,7 +385,7 @@ export class Store extends HoistBase {
|
|
|
381
385
|
'In order to update grid data, records must have stable ids. Note: XH.genId() will not provide such ids.'
|
|
382
386
|
),
|
|
383
387
|
parent = rec.parent,
|
|
384
|
-
isSummary =
|
|
388
|
+
isSummary = some(this.summaryRecords, {id: recId});
|
|
385
389
|
return this.createRecord(it, parent, isSummary);
|
|
386
390
|
});
|
|
387
391
|
}
|
|
@@ -398,20 +402,22 @@ export class Store extends HoistBase {
|
|
|
398
402
|
});
|
|
399
403
|
}
|
|
400
404
|
|
|
401
|
-
// 2) Pre-process summary
|
|
402
|
-
const {
|
|
403
|
-
let
|
|
404
|
-
if (
|
|
405
|
-
|
|
405
|
+
// 2) Pre-process summary records, peeling them out of updates if needed
|
|
406
|
+
const {summaryRecords} = this;
|
|
407
|
+
let summaryUpdateRecs: StoreRecord[];
|
|
408
|
+
if (!isEmpty(summaryRecords)) {
|
|
409
|
+
summaryUpdateRecs = lodashRemove(updateRecs, ({id}) => some(summaryRecords, {id}));
|
|
406
410
|
}
|
|
407
411
|
|
|
408
|
-
if (
|
|
409
|
-
|
|
412
|
+
if (isEmpty(summaryUpdateRecs) && rawSummaryData) {
|
|
413
|
+
summaryUpdateRecs = castArray(rawSummaryData).map(it =>
|
|
414
|
+
this.createRecord(it, null, true)
|
|
415
|
+
);
|
|
410
416
|
}
|
|
411
417
|
|
|
412
|
-
if (
|
|
413
|
-
this.
|
|
414
|
-
changeLog.
|
|
418
|
+
if (!isEmpty(summaryUpdateRecs)) {
|
|
419
|
+
this.summaryRecords = summaryUpdateRecs;
|
|
420
|
+
changeLog.summaryRecords = this.summaryRecords;
|
|
415
421
|
}
|
|
416
422
|
|
|
417
423
|
// 3) Apply changes
|
|
@@ -672,6 +678,15 @@ export class Store extends HoistBase {
|
|
|
672
678
|
return this._current.rootList;
|
|
673
679
|
}
|
|
674
680
|
|
|
681
|
+
/** Record containing summary data. */
|
|
682
|
+
get summaryRecord(): StoreRecord {
|
|
683
|
+
throwIf(
|
|
684
|
+
this.summaryRecords.length > 1,
|
|
685
|
+
'Store has multiple summary records. Use Store.summaryRecords.'
|
|
686
|
+
);
|
|
687
|
+
return first(this.summaryRecords);
|
|
688
|
+
}
|
|
689
|
+
|
|
675
690
|
/** True if the store has changes which need to be committed. */
|
|
676
691
|
@computed
|
|
677
692
|
get isModified(): boolean {
|
|
@@ -787,7 +802,8 @@ export class Store extends HoistBase {
|
|
|
787
802
|
*/
|
|
788
803
|
getById(id: StoreRecordId, respectFilter: boolean = false): StoreRecord {
|
|
789
804
|
if (isNil(id)) return null;
|
|
790
|
-
|
|
805
|
+
const summaryRecord = this.summaryRecords?.find(it => it.id === id);
|
|
806
|
+
if (summaryRecord) return summaryRecord;
|
|
791
807
|
|
|
792
808
|
const rs = respectFilter ? this._filtered : this._current;
|
|
793
809
|
return rs.getById(id);
|
|
@@ -892,7 +908,7 @@ export class Store extends HoistBase {
|
|
|
892
908
|
@action
|
|
893
909
|
private resetRecords() {
|
|
894
910
|
this._committed = this._current = this._filtered = new RecordSet(this);
|
|
895
|
-
this.
|
|
911
|
+
this.summaryRecords = null;
|
|
896
912
|
}
|
|
897
913
|
|
|
898
914
|
private parseFields(fields: any[], defaults: any): Field[] {
|
|
@@ -965,7 +981,7 @@ export class Store extends HoistBase {
|
|
|
965
981
|
{id} = rec;
|
|
966
982
|
|
|
967
983
|
throwIf(
|
|
968
|
-
recordMap.has(id) || this.
|
|
984
|
+
recordMap.has(id) || this.summaryRecords?.some(it => it.id === id),
|
|
969
985
|
`ID ${id} is not unique. Use the 'Store.idSpec' config to resolve a unique ID for each record.`
|
|
970
986
|
);
|
|
971
987
|
|
package/kit/blueprint/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
useHotkeys
|
|
20
20
|
} from '@blueprintjs/core';
|
|
21
21
|
import '@blueprintjs/core/lib/css/blueprint.css';
|
|
22
|
+
import '@blueprintjs/datetime/lib/css/blueprint-datetime.css';
|
|
22
23
|
import '@blueprintjs/datetime2/lib/css/blueprint-datetime2.css';
|
|
23
24
|
import {elementFactory} from '@xh/hoist/core';
|
|
24
25
|
import './styles.scss';
|
package/package.json
CHANGED
|
@@ -139,8 +139,8 @@ export class GridAutosizeService extends HoistService {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
// Ensure the summary record is always included, since it is likely to contain the largest values.
|
|
142
|
-
if (gridModel.showSummary && store.
|
|
143
|
-
ret.push(store.
|
|
142
|
+
if (gridModel.showSummary && !isEmpty(store.summaryRecords)) {
|
|
143
|
+
ret.push(...store.summaryRecords);
|
|
144
144
|
}
|
|
145
145
|
return ret;
|
|
146
146
|
}
|
package/svc/GridExportService.ts
CHANGED
|
@@ -75,7 +75,7 @@ export class GridExportService extends HoistService {
|
|
|
75
75
|
|
|
76
76
|
const config = XH.configService.get('xhExportConfig', {}),
|
|
77
77
|
exportColumns = this.getExportableColumns(gridModel, columns),
|
|
78
|
-
|
|
78
|
+
summaryRecords = gridModel.store.summaryRecords,
|
|
79
79
|
records = gridModel.store.rootRecords,
|
|
80
80
|
meta = this.getColumnMetadata(exportColumns);
|
|
81
81
|
|
|
@@ -84,18 +84,17 @@ export class GridExportService extends HoistService {
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
// If the grid includes
|
|
88
|
-
const rows =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.getRecordRow(gridModel, summaryRecord, exportColumns, type, 0)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
];
|
|
87
|
+
// If the grid includes summary rows, add them to the export payload as root-level nodes.
|
|
88
|
+
const rows = [
|
|
89
|
+
this.getHeaderRow(exportColumns, type, gridModel),
|
|
90
|
+
...(gridModel.showSummary && !isEmpty(summaryRecords)
|
|
91
|
+
? summaryRecords.map(summaryRecord =>
|
|
92
|
+
this.getRecordRow(gridModel, summaryRecord, exportColumns, type, 0)
|
|
93
|
+
)
|
|
94
|
+
: []),
|
|
95
|
+
|
|
96
|
+
...this.getRecordRowsRecursive(gridModel, records, exportColumns, type, 1)
|
|
97
|
+
];
|
|
99
98
|
|
|
100
99
|
// Show separate 'started' toasts for larger (i.e. slower) exports.
|
|
101
100
|
let startToast = null,
|