@xh/hoist 59.3.2 → 59.4.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 +25 -3
- package/admin/differ/DifferModel.ts +5 -7
- package/appcontainer/AppContainerModel.ts +8 -10
- package/appcontainer/AppStateModel.ts +3 -2
- package/appcontainer/PageStateModel.ts +1 -2
- package/appcontainer/SizingModeModel.ts +2 -2
- package/cmp/ag-grid/AgGrid.ts +4 -3
- package/cmp/ag-grid/AgGridModel.ts +8 -9
- package/cmp/chart/Chart.ts +4 -3
- package/cmp/dataview/DataViewModel.ts +2 -2
- package/cmp/filter/FilterChooserModel.ts +5 -5
- package/cmp/grid/Grid.ts +2 -2
- package/cmp/grid/GridContextMenu.ts +2 -2
- package/cmp/grid/GridModel.ts +13 -21
- package/cmp/grid/Types.ts +6 -5
- package/cmp/grid/columns/Column.ts +12 -12
- package/cmp/grid/columns/ColumnGroup.ts +17 -6
- package/cmp/grid/helpers/GridCountLabel.ts +5 -4
- package/cmp/grid/impl/ColumnWidthCalculator.ts +3 -3
- package/cmp/grid/impl/GridPersistenceModel.ts +11 -4
- package/cmp/grid/renderers/MultiFieldRenderer.ts +28 -22
- package/cmp/grouping/GroupingChooserModel.ts +2 -2
- package/cmp/tab/TabContainerModel.ts +2 -2
- package/cmp/zoneGrid/impl/ZoneGridPersistenceModel.ts +10 -4
- package/core/HoistBase.ts +44 -5
- package/core/elem.ts +2 -2
- package/core/impl/InstallServices.ts +2 -8
- package/core/load/LoadSupport.ts +3 -3
- package/core/model/HoistModel.ts +1 -1
- package/data/Store.ts +1 -1
- package/data/UrlStore.ts +3 -3
- package/data/filter/CompoundFilter.ts +5 -3
- package/data/filter/FieldFilter.ts +4 -3
- package/data/filter/Filter.ts +2 -3
- package/data/filter/FunctionFilter.ts +2 -1
- package/data/impl/RecordSet.ts +5 -5
- package/desktop/appcontainer/ToastSource.ts +1 -1
- package/desktop/cmp/rest/Actions.ts +15 -9
- package/desktop/cmp/treemap/TreeMap.ts +4 -8
- package/package.json +1 -1
- package/svc/AutoRefreshService.ts +3 -3
- package/svc/FetchService.ts +5 -5
- package/svc/GridAutosizeService.ts +4 -7
- package/svc/TrackService.ts +6 -6
- package/svc/WebSocketService.ts +14 -15
- package/utils/async/AsyncUtils.ts +3 -2
- package/utils/async/Timer.ts +4 -3
- package/utils/js/BrowserUtils.ts +8 -8
- package/utils/js/LangUtils.ts +10 -9
- package/utils/js/LogUtils.ts +66 -26
- package/utils/react/LayoutPropUtils.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 59.4.0 - 2023-11-28
|
|
4
|
+
|
|
5
|
+
### 💥 Breaking Changes
|
|
6
|
+
|
|
7
|
+
* The constructors for `ColumnGroup` no long accept arbitrary rest (e.g `...rest`)
|
|
8
|
+
arguments for applying app-specific data to the object. Instead, use the new `appData` property.
|
|
9
|
+
|
|
10
|
+
### ⚙️ Technical
|
|
11
|
+
|
|
12
|
+
* Enhanced `LogUtils` to support logging objects (and any other non-string values). Also
|
|
13
|
+
added new exports for `logWarn()` and `logError()` with the same standardized formatting.
|
|
14
|
+
* Added standardized `LogUtils` methods to `HoistBase`, for use within Hoist models and services.
|
|
15
|
+
|
|
16
|
+
### 🐞 Bug Fixes
|
|
17
|
+
|
|
18
|
+
* `ZoneGrid` will no longer render labels or delimiters for empty values.
|
|
19
|
+
|
|
20
|
+
### ⚙️ Typescript API Adjustments
|
|
21
|
+
|
|
22
|
+
* Updated type for `ReactionSpec.equals` to include already-supported string shorthands.
|
|
23
|
+
|
|
3
24
|
## 59.3.2 - 2023-11-21
|
|
4
25
|
|
|
5
26
|
### 🐞 Bug Fixes
|
|
6
27
|
|
|
7
|
-
* `ZoneGrid` will more gracefully handle state that has become out of sync with its mapper
|
|
28
|
+
* `ZoneGrid` will more gracefully handle state that has become out of sync with its mapper
|
|
29
|
+
requirements.
|
|
8
30
|
|
|
9
31
|
## 59.3.1 - 2023-11-10
|
|
10
32
|
|
|
@@ -55,9 +77,9 @@
|
|
|
55
77
|
* Improved core `HoistComponent` performance by preventing unnecessary re-renderings triggered by
|
|
56
78
|
spurious model lookup changes.
|
|
57
79
|
* New flag `GridModel.experimental.enableFullWidthScroll` enables scrollbars to span pinned columns.
|
|
58
|
-
|
|
80
|
+
* Early test release behind the flag, expected to made the default behavior in next release.
|
|
59
81
|
* Renamed `XH.getActiveModels()` to `XH.getModels()` for clarity / consistency.
|
|
60
|
-
|
|
82
|
+
* API change, but not expected to impact applications.
|
|
61
83
|
* Added `XH.getModel()` convenience method to return the first matching model.
|
|
62
84
|
|
|
63
85
|
## 59.2.0 - 2023-10-16
|
|
@@ -6,18 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
9
|
+
import {div, hbox, p} from '@xh/hoist/cmp/layout';
|
|
9
10
|
import {HoistModel, LoadSpec, managed, XH} from '@xh/hoist/core';
|
|
11
|
+
import {RecordActionSpec} from '@xh/hoist/data';
|
|
10
12
|
import {actionCol} from '@xh/hoist/desktop/cmp/grid';
|
|
11
|
-
import {div, p} from '@xh/hoist/cmp/layout';
|
|
12
13
|
import {Icon} from '@xh/hoist/icon';
|
|
13
|
-
import {bindable, makeObservable, observable
|
|
14
|
+
import {action, bindable, makeObservable, observable} from '@xh/hoist/mobx';
|
|
14
15
|
import {pluralize} from '@xh/hoist/utils/js';
|
|
15
|
-
import {
|
|
16
|
-
import {cloneDeep, isEqual, isString, isNil, omit, remove, trimEnd} from 'lodash';
|
|
16
|
+
import {cloneDeep, isEqual, isNil, isString, omit, remove, trimEnd} from 'lodash';
|
|
17
17
|
import {hspacer} from '../../cmp/layout';
|
|
18
|
-
|
|
19
18
|
import {DifferDetailModel} from './DifferDetailModel';
|
|
20
|
-
import {RecordActionSpec} from '@xh/hoist/data';
|
|
21
19
|
|
|
22
20
|
/**
|
|
23
21
|
* @internal
|
|
@@ -378,7 +376,7 @@ export class DifferModel extends HoistModel {
|
|
|
378
376
|
content = await window.navigator.clipboard.readText();
|
|
379
377
|
content = JSON.parse(content);
|
|
380
378
|
} catch (e) {
|
|
381
|
-
|
|
379
|
+
this.logWarn('Error reading config from clipboard', e);
|
|
382
380
|
}
|
|
383
381
|
|
|
384
382
|
this.clipboardContent = content;
|
|
@@ -114,8 +114,8 @@ export class AppContainerModel extends HoistModel {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
* Called when
|
|
118
|
-
* authentication and initialization of
|
|
117
|
+
* Called when {@link AppContainer} first mounted.
|
|
118
|
+
* Triggers initial authentication and initialization of Hoist and application.
|
|
119
119
|
*/
|
|
120
120
|
async initAsync() {
|
|
121
121
|
// Avoid multiple calls, which can occur if AppContainer remounted.
|
|
@@ -196,14 +196,12 @@ export class AppContainerModel extends HoistModel {
|
|
|
196
196
|
numbro['BigNumber'].clone();
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
// Confirm hoist-core version after environment service loaded
|
|
200
|
-
const hcVersion = XH.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
`);
|
|
206
|
-
}
|
|
199
|
+
// Confirm hoist-core version after environment service loaded.
|
|
200
|
+
const hcVersion = XH.getEnv('hoistCoreVersion');
|
|
201
|
+
throwIf(
|
|
202
|
+
!checkMinVersion(hcVersion, MIN_HOIST_CORE_VERSION),
|
|
203
|
+
`This version of Hoist React requires the server to run Hoist Core ≥ v${MIN_HOIST_CORE_VERSION}. Version ${hcVersion} detected.`
|
|
204
|
+
);
|
|
207
205
|
|
|
208
206
|
await installServicesAsync([
|
|
209
207
|
AlertBannerService,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import {AppState, AppSuspendData, HoistModel, XH} from '@xh/hoist/core';
|
|
8
8
|
import {action, makeObservable, observable, reaction} from '@xh/hoist/mobx';
|
|
9
9
|
import {Timer} from '@xh/hoist/utils/async';
|
|
10
|
-
import {getClientDeviceInfo
|
|
10
|
+
import {getClientDeviceInfo} from '@xh/hoist/utils/js';
|
|
11
11
|
import {isBoolean, isString} from 'lodash';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -34,7 +34,7 @@ export class AppStateModel extends HoistModel {
|
|
|
34
34
|
@action
|
|
35
35
|
setAppState(nextState: AppState) {
|
|
36
36
|
if (this.state !== nextState) {
|
|
37
|
-
logDebug(`AppState change: ${this.state} → ${nextState}
|
|
37
|
+
this.logDebug(`AppState change: ${this.state} → ${nextState}`);
|
|
38
38
|
}
|
|
39
39
|
this.state = nextState;
|
|
40
40
|
}
|
|
@@ -87,6 +87,7 @@ export class AppStateModel extends HoistModel {
|
|
|
87
87
|
appVersion: XH.appVersion,
|
|
88
88
|
appBuild: XH.appBuild,
|
|
89
89
|
locationHref: window.location.href,
|
|
90
|
+
wasDiscarded: window.document['wasDiscarded'],
|
|
90
91
|
...getClientDeviceInfo()
|
|
91
92
|
},
|
|
92
93
|
logData: ['appVersion', 'appBuild'],
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import {HoistModel, PageState} from '@xh/hoist/core';
|
|
8
8
|
import {action, makeObservable, observable} from '@xh/hoist/mobx';
|
|
9
|
-
import {logDebug} from '@xh/hoist/utils/js';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Implementation of PageState maintenance.
|
|
@@ -35,7 +34,7 @@ export class PageStateModel extends HoistModel {
|
|
|
35
34
|
private setState(nextState: PageState) {
|
|
36
35
|
if (this.state == 'terminated' || this.state == nextState) return;
|
|
37
36
|
|
|
38
|
-
logDebug(`PageState change: ${this.state} → ${nextState}
|
|
37
|
+
this.logDebug(`PageState change: ${this.state} → ${nextState}`);
|
|
39
38
|
this.state = nextState;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -40,7 +40,7 @@ export class SizingModeModel extends HoistModel {
|
|
|
40
40
|
platform = this.getPlatform();
|
|
41
41
|
|
|
42
42
|
if (!isPlainObject(pref)) {
|
|
43
|
-
|
|
43
|
+
this.logWarn(
|
|
44
44
|
`Required pref 'xhSizingMode' must be type JSON - update via Admin Console.`
|
|
45
45
|
);
|
|
46
46
|
return;
|
|
@@ -48,7 +48,7 @@ export class SizingModeModel extends HoistModel {
|
|
|
48
48
|
|
|
49
49
|
XH.setPref('xhSizingMode', {...pref, [platform]: sizingMode});
|
|
50
50
|
} else {
|
|
51
|
-
|
|
51
|
+
this.logWarn(`Missing required JSON pref 'xhSizingMode' - add via Admin Console.`);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
package/cmp/ag-grid/AgGrid.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
XH
|
|
19
19
|
} from '@xh/hoist/core';
|
|
20
20
|
import {AgGridReact, GridOptions} from '@xh/hoist/kit/ag-grid';
|
|
21
|
+
import {logError} from '@xh/hoist/utils/js';
|
|
21
22
|
import {splitLayoutProps} from '@xh/hoist/utils/react';
|
|
22
23
|
import classNames from 'classnames';
|
|
23
24
|
import {isNil} from 'lodash';
|
|
@@ -60,9 +61,9 @@ export const [AgGrid, agGrid] = hoistCmp.withFactory<AgGridProps>({
|
|
|
60
61
|
|
|
61
62
|
render({model, className, testId, ...props}, ref) {
|
|
62
63
|
if (!AgGridReact) {
|
|
63
|
-
|
|
64
|
-
'
|
|
65
|
-
|
|
64
|
+
logError(
|
|
65
|
+
'AG Grid not imported/licensed by this app - import and register modules in Bootstrap.ts. See the XH Toolbox app for an example.',
|
|
66
|
+
AgGrid
|
|
66
67
|
);
|
|
67
68
|
return placeholder('ag-Grid library not available.');
|
|
68
69
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Copyright © 2023 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {HoistModel, PlainObject, SizingMode, Some} from '@xh/hoist/core';
|
|
8
|
+
import type {ColumnApi, GridApi, IRowNode, SortDirection} from '@xh/hoist/kit/ag-grid';
|
|
8
9
|
import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx';
|
|
9
10
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
10
11
|
import {
|
|
@@ -23,8 +24,6 @@ import {
|
|
|
23
24
|
} from 'lodash';
|
|
24
25
|
import {GridSorter, GridSorterLike} from '../grid/GridSorter';
|
|
25
26
|
|
|
26
|
-
import type {ColumnApi, GridApi, SortDirection} from '@xh/hoist/kit/ag-grid';
|
|
27
|
-
|
|
28
27
|
export interface AgGridModelConfig {
|
|
29
28
|
sizingMode?: SizingMode;
|
|
30
29
|
|
|
@@ -177,7 +176,7 @@ export class AgGridModel extends HoistModel {
|
|
|
177
176
|
try {
|
|
178
177
|
return this[`get${startCase(type)}State`]();
|
|
179
178
|
} catch (err) {
|
|
180
|
-
|
|
179
|
+
this.logWarn(`Encountered errors retrieving ${type} state`, err);
|
|
181
180
|
errors[type] = err.toString();
|
|
182
181
|
}
|
|
183
182
|
};
|
|
@@ -358,7 +357,7 @@ export class AgGridModel extends HoistModel {
|
|
|
358
357
|
col.setSort(state.sort);
|
|
359
358
|
col.setSortIndex(state.sortIndex);
|
|
360
359
|
} else {
|
|
361
|
-
|
|
360
|
+
this.logWarn(
|
|
362
361
|
'Could not find a secondary column to associate with the pivot column path',
|
|
363
362
|
state.colId
|
|
364
363
|
);
|
|
@@ -554,7 +553,7 @@ export class AgGridModel extends HoistModel {
|
|
|
554
553
|
* @returns the first row in the grid, after sorting and filtering, which
|
|
555
554
|
* has data associated with it (i.e. not a group or other synthetic row).
|
|
556
555
|
*/
|
|
557
|
-
getFirstSelectableRowNode():
|
|
556
|
+
getFirstSelectableRowNode(): IRowNode {
|
|
558
557
|
this.throwIfNotReady();
|
|
559
558
|
|
|
560
559
|
let ret = null;
|
|
@@ -595,7 +594,7 @@ export class AgGridModel extends HoistModel {
|
|
|
595
594
|
/**
|
|
596
595
|
* @returns row data pinned to the bottom of the grid
|
|
597
596
|
*/
|
|
598
|
-
getPinnedBottomRowData() {
|
|
597
|
+
getPinnedBottomRowData(): PlainObject[] {
|
|
599
598
|
this.throwIfNotReady();
|
|
600
599
|
return this.getPinnedRowData('Bottom');
|
|
601
600
|
}
|
|
@@ -605,7 +604,7 @@ export class AgGridModel extends HoistModel {
|
|
|
605
604
|
//------------------------
|
|
606
605
|
@action
|
|
607
606
|
handleGridReady({api, columnApi}) {
|
|
608
|
-
|
|
607
|
+
this.logDebug(`Initializing`, this.xhId);
|
|
609
608
|
throwIf(
|
|
610
609
|
this.agApi && this.agApi != api,
|
|
611
610
|
'Attempted to mount a grid on a GridModel that is already in use. ' +
|
|
@@ -617,12 +616,12 @@ export class AgGridModel extends HoistModel {
|
|
|
617
616
|
|
|
618
617
|
@action
|
|
619
618
|
handleGridUnmount() {
|
|
620
|
-
|
|
619
|
+
this.logDebug(`Un-initializing`, this.xhId);
|
|
621
620
|
this.agApi = null;
|
|
622
621
|
this.agColumnApi = null;
|
|
623
622
|
}
|
|
624
623
|
|
|
625
|
-
private getPinnedRowData(side) {
|
|
624
|
+
private getPinnedRowData(side: string): PlainObject[] {
|
|
626
625
|
const {agApi} = this,
|
|
627
626
|
count = agApi[`getPinned${side}RowCount`](),
|
|
628
627
|
ret = [];
|
package/cmp/chart/Chart.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {useContextMenu} from '@xh/hoist/dynamics/desktop';
|
|
|
22
22
|
import {Icon} from '@xh/hoist/icon';
|
|
23
23
|
import {Highcharts} from '@xh/hoist/kit/highcharts';
|
|
24
24
|
import {runInAction} from '@xh/hoist/mobx';
|
|
25
|
+
import {logError} from '@xh/hoist/utils/js';
|
|
25
26
|
import {
|
|
26
27
|
createObservableRef,
|
|
27
28
|
getLayoutProps,
|
|
@@ -61,9 +62,9 @@ export const [Chart, chart] = hoistCmp.withFactory<ChartProps>({
|
|
|
61
62
|
|
|
62
63
|
render({model, className, aspectRatio, testId, ...props}, ref) {
|
|
63
64
|
if (!Highcharts) {
|
|
64
|
-
|
|
65
|
-
'Highcharts
|
|
66
|
-
|
|
65
|
+
logError(
|
|
66
|
+
'Highcharts not imported by this app - import and register modules in Bootstrap.ts. See the XH Toolbox app for an example.',
|
|
67
|
+
Chart
|
|
67
68
|
);
|
|
68
69
|
return placeholder('Highcharts library not available.');
|
|
69
70
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2023 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {RowClickedEvent, RowDoubleClickedEvent} from '@ag-grid-community/core';
|
|
7
|
+
import {RowClickedEvent, RowDoubleClickedEvent, RowHeightParams} from '@ag-grid-community/core';
|
|
8
8
|
import {
|
|
9
9
|
ColumnRenderer,
|
|
10
10
|
ColumnSpec,
|
|
@@ -127,7 +127,7 @@ export interface DataViewConfig {
|
|
|
127
127
|
export type ItemHeightFn = (params: {
|
|
128
128
|
record: StoreRecord;
|
|
129
129
|
dataViewModel: DataViewModel;
|
|
130
|
-
agParams:
|
|
130
|
+
agParams: RowHeightParams;
|
|
131
131
|
}) => number;
|
|
132
132
|
|
|
133
133
|
/**
|
|
@@ -199,7 +199,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
199
199
|
run: state => this.provider.write(state)
|
|
200
200
|
});
|
|
201
201
|
} catch (e) {
|
|
202
|
-
|
|
202
|
+
this.logError(e);
|
|
203
203
|
XH.safeDestroy(this.provider);
|
|
204
204
|
this.provider = null;
|
|
205
205
|
}
|
|
@@ -251,7 +251,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
// 2) Main path - set internal value.
|
|
254
|
-
|
|
254
|
+
this.logDebug('Setting value', value);
|
|
255
255
|
this.value = value;
|
|
256
256
|
|
|
257
257
|
// 3) Set props on select input needed to display
|
|
@@ -292,7 +292,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
292
292
|
})
|
|
293
293
|
.linkTo(this.filterTask);
|
|
294
294
|
} catch (e) {
|
|
295
|
-
|
|
295
|
+
this.logError('Failed to set value', e);
|
|
296
296
|
this.value = null;
|
|
297
297
|
this.selectOptions = null;
|
|
298
298
|
this.selectValue = null;
|
|
@@ -490,7 +490,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
490
490
|
if (f === null) return true;
|
|
491
491
|
if (f instanceof FieldFilter) {
|
|
492
492
|
if (!this.getFieldSpec(f.field)) {
|
|
493
|
-
|
|
493
|
+
this.logError(`Invalid FieldFilter - no fieldSpec configured for ${f.field}.`);
|
|
494
494
|
return false;
|
|
495
495
|
}
|
|
496
496
|
return true;
|
|
@@ -500,7 +500,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
500
500
|
return f.filters.every(it => this.validateFilter(it));
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
-
|
|
503
|
+
this.logError('Invalid Filter - unhandled type', f);
|
|
504
504
|
return false;
|
|
505
505
|
}
|
|
506
506
|
|
package/cmp/grid/Grid.ts
CHANGED
|
@@ -41,7 +41,7 @@ import type {
|
|
|
41
41
|
} from '@xh/hoist/kit/ag-grid';
|
|
42
42
|
import {computed, observer} from '@xh/hoist/mobx';
|
|
43
43
|
import {wait} from '@xh/hoist/promise';
|
|
44
|
-
import {consumeEvent, isDisplayed,
|
|
44
|
+
import {consumeEvent, isDisplayed, logWithDebug} from '@xh/hoist/utils/js';
|
|
45
45
|
import {createObservableRef, getLayoutProps} from '@xh/hoist/utils/react';
|
|
46
46
|
import classNames from 'classnames';
|
|
47
47
|
import {debounce, isEmpty, isEqual, isNil, max, maxBy, merge} from 'lodash';
|
|
@@ -634,7 +634,7 @@ export class GridLocalModel extends HoistModel {
|
|
|
634
634
|
let transaction = null;
|
|
635
635
|
if (prevCount !== 0) {
|
|
636
636
|
transaction = this.genTransaction(newRs, prevRs);
|
|
637
|
-
logDebug(this.transactionLogStr(transaction)
|
|
637
|
+
this.logDebug(this.transactionLogStr(transaction));
|
|
638
638
|
|
|
639
639
|
if (!this.transactionIsEmpty(transaction)) {
|
|
640
640
|
agApi.applyTransaction(transaction);
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2023 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {PlainObject} from '@xh/hoist/core';
|
|
8
7
|
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
9
8
|
import {RecordActionLike} from '@xh/hoist/data';
|
|
9
|
+
import {GetContextMenuItemsParams} from '@xh/hoist/kit/ag-grid';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* If a String, value can be '-' for a separator, or a token supported by ag-Grid
|
|
@@ -46,4 +46,4 @@ export type GridContextMenuToken =
|
|
|
46
46
|
*/
|
|
47
47
|
export type GridContextMenuSpec =
|
|
48
48
|
| GridContextMenuItemLike[]
|
|
49
|
-
| ((agParams:
|
|
49
|
+
| ((agParams: GetContextMenuItemsParams, gridModel: GridModel) => GridContextMenuItemLike[]);
|
package/cmp/grid/GridModel.ts
CHANGED
|
@@ -56,14 +56,7 @@ import {action, bindable, makeObservable, observable, when} from '@xh/hoist/mobx
|
|
|
56
56
|
import {wait, waitFor} from '@xh/hoist/promise';
|
|
57
57
|
import {ExportOptions} from '@xh/hoist/svc/GridExportService';
|
|
58
58
|
import {SECONDS} from '@xh/hoist/utils/datetime';
|
|
59
|
-
import {
|
|
60
|
-
deepFreeze,
|
|
61
|
-
logWithDebug,
|
|
62
|
-
throwIf,
|
|
63
|
-
warnIf,
|
|
64
|
-
withDebug,
|
|
65
|
-
withDefault
|
|
66
|
-
} from '@xh/hoist/utils/js';
|
|
59
|
+
import {deepFreeze, logWithDebug, throwIf, warnIf, withDefault} from '@xh/hoist/utils/js';
|
|
67
60
|
import equal from 'fast-deep-equal';
|
|
68
61
|
import {
|
|
69
62
|
castArray,
|
|
@@ -818,7 +811,7 @@ export class GridModel extends HoistModel {
|
|
|
818
811
|
|
|
819
812
|
const indexCount = indices.length;
|
|
820
813
|
if (indexCount !== records.length) {
|
|
821
|
-
|
|
814
|
+
this.logWarn('Grid row nodes not found for all provided records.');
|
|
822
815
|
}
|
|
823
816
|
|
|
824
817
|
if (indexCount === 1) {
|
|
@@ -978,7 +971,7 @@ export class GridModel extends HoistModel {
|
|
|
978
971
|
|
|
979
972
|
const invalidColIds = colIds.filter(it => !this.findColumn(this.columns, it));
|
|
980
973
|
if (invalidColIds.length) {
|
|
981
|
-
|
|
974
|
+
this.logWarn(
|
|
982
975
|
'Unknown colId specified in groupBy - grid will not be grouped.',
|
|
983
976
|
invalidColIds
|
|
984
977
|
);
|
|
@@ -1025,7 +1018,7 @@ export class GridModel extends HoistModel {
|
|
|
1025
1018
|
it => !it.colId?.startsWith('ag-Grid') && !this.findColumn(this.columns, it.colId)
|
|
1026
1019
|
);
|
|
1027
1020
|
if (invalidSorters.length) {
|
|
1028
|
-
|
|
1021
|
+
this.logWarn('GridSorter colId not found in grid columns', invalidSorters);
|
|
1029
1022
|
return;
|
|
1030
1023
|
}
|
|
1031
1024
|
|
|
@@ -1360,10 +1353,9 @@ export class GridModel extends HoistModel {
|
|
|
1360
1353
|
|
|
1361
1354
|
const rowIndex = agApi.getRowNode(recToEdit?.agId)?.rowIndex;
|
|
1362
1355
|
if (isNil(rowIndex) || rowIndex < 0) {
|
|
1363
|
-
|
|
1364
|
-
'Unable to start editing
|
|
1365
|
-
|
|
1366
|
-
: 'no records found'
|
|
1356
|
+
this.logWarn(
|
|
1357
|
+
'Unable to start editing',
|
|
1358
|
+
record ? 'specified record not found' : 'no records found'
|
|
1367
1359
|
);
|
|
1368
1360
|
return;
|
|
1369
1361
|
}
|
|
@@ -1381,11 +1373,11 @@ export class GridModel extends HoistModel {
|
|
|
1381
1373
|
}
|
|
1382
1374
|
|
|
1383
1375
|
if (!colToEdit) {
|
|
1384
|
-
|
|
1385
|
-
'Unable to start editing
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1376
|
+
this.logWarn(
|
|
1377
|
+
'Unable to start editing',
|
|
1378
|
+
colId
|
|
1379
|
+
? `column with colId ${colId} not found, or not editable`
|
|
1380
|
+
: 'no editable columns found'
|
|
1389
1381
|
);
|
|
1390
1382
|
return;
|
|
1391
1383
|
}
|
|
@@ -1438,7 +1430,7 @@ export class GridModel extends HoistModel {
|
|
|
1438
1430
|
try {
|
|
1439
1431
|
await when(() => this.isReady, {timeout});
|
|
1440
1432
|
} catch (ignored) {
|
|
1441
|
-
|
|
1433
|
+
this.logDebug(`Grid failed to enter ready state after waiting ${timeout}ms`);
|
|
1442
1434
|
}
|
|
1443
1435
|
await wait();
|
|
1444
1436
|
|
package/cmp/grid/Types.ts
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* Copyright © 2023 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import {IRowNode} from '@xh/hoist/kit/ag-grid';
|
|
8
9
|
import {GridFilterFieldSpecConfig} from '@xh/hoist/cmp/grid/filter/GridFilterFieldSpec';
|
|
9
|
-
import {HSide, PersistOptions,
|
|
10
|
+
import {HSide, PersistOptions, SizingMode, Some} from '@xh/hoist/core';
|
|
10
11
|
import {Store, StoreRecord, View} from '@xh/hoist/data';
|
|
11
12
|
import {ReactElement, ReactNode} from 'react';
|
|
12
13
|
import {Column} from './columns/Column';
|
|
@@ -54,8 +55,8 @@ export type GridGroupSortFn = (
|
|
|
54
55
|
groupField: string,
|
|
55
56
|
metadata: {
|
|
56
57
|
gridModel: GridModel;
|
|
57
|
-
nodeA:
|
|
58
|
-
nodeB:
|
|
58
|
+
nodeA: IRowNode;
|
|
59
|
+
nodeB: IRowNode;
|
|
59
60
|
}
|
|
60
61
|
) => number;
|
|
61
62
|
|
|
@@ -167,8 +168,8 @@ export type ColumnComparator<T = any> = (
|
|
|
167
168
|
params: {
|
|
168
169
|
recordA: StoreRecord;
|
|
169
170
|
recordB: StoreRecord;
|
|
170
|
-
agNodeA:
|
|
171
|
-
agNodeB:
|
|
171
|
+
agNodeA: IRowNode;
|
|
172
|
+
agNodeB: IRowNode;
|
|
172
173
|
column: Column;
|
|
173
174
|
gridModel: GridModel;
|
|
174
175
|
defaultComparator: (a: T, b: T) => number;
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
RecordActionSpec,
|
|
15
15
|
StoreRecord
|
|
16
16
|
} from '@xh/hoist/data';
|
|
17
|
-
import {apiRemoved, throwIf, warnIf, withDefault} from '@xh/hoist/utils/js';
|
|
17
|
+
import {apiRemoved, logDebug, logWarn, throwIf, warnIf, withDefault} from '@xh/hoist/utils/js';
|
|
18
18
|
import classNames from 'classnames';
|
|
19
19
|
import {
|
|
20
20
|
castArray,
|
|
@@ -932,12 +932,12 @@ export class Column {
|
|
|
932
932
|
sortCfg = find(gridModel.sortBy, {colId}),
|
|
933
933
|
sortDir = sortCfg?.sort || 'asc',
|
|
934
934
|
abs = sortCfg?.abs || false,
|
|
935
|
-
recordA = agNodeA?.data,
|
|
936
|
-
recordB = agNodeB?.data,
|
|
935
|
+
recordA = agNodeA?.data as StoreRecord,
|
|
936
|
+
recordB = agNodeB?.data as StoreRecord,
|
|
937
937
|
params = {
|
|
938
938
|
recordA,
|
|
939
939
|
recordB,
|
|
940
|
-
column: this,
|
|
940
|
+
column: this as Column,
|
|
941
941
|
gridModel,
|
|
942
942
|
defaultComparator: this.defaultComparator,
|
|
943
943
|
agNodeA,
|
|
@@ -962,7 +962,7 @@ export class Column {
|
|
|
962
962
|
if (editor) {
|
|
963
963
|
ret.cellEditor = forwardRef((agParams: PlainObject, ref) => {
|
|
964
964
|
const props = {
|
|
965
|
-
record: agParams.data,
|
|
965
|
+
record: agParams.data as StoreRecord,
|
|
966
966
|
gridModel,
|
|
967
967
|
column: this,
|
|
968
968
|
agParams,
|
|
@@ -1056,23 +1056,23 @@ export class Column {
|
|
|
1056
1056
|
|
|
1057
1057
|
private parseFilterable(filterable) {
|
|
1058
1058
|
if (!filterable) return false;
|
|
1059
|
+
const {colId} = this;
|
|
1059
1060
|
|
|
1060
1061
|
if (XH.isMobileApp) {
|
|
1061
|
-
|
|
1062
|
+
logDebug(
|
|
1063
|
+
`Column ${colId} specs 'filterable' but not supported on mobile - will be ignored.`,
|
|
1064
|
+
this
|
|
1065
|
+
);
|
|
1062
1066
|
return false;
|
|
1063
1067
|
}
|
|
1064
1068
|
|
|
1065
1069
|
if (!this.field) {
|
|
1066
|
-
|
|
1067
|
-
`Column '${this.colId}' is not a Store field. 'filterable' will be ignored.`
|
|
1068
|
-
);
|
|
1070
|
+
logWarn(`Column ${colId} is not a Store field. 'filterable' will be ignored.`, this);
|
|
1069
1071
|
return false;
|
|
1070
1072
|
}
|
|
1071
1073
|
|
|
1072
1074
|
if (this.field === 'cubeLabel') {
|
|
1073
|
-
|
|
1074
|
-
`Column '${this.colId}' is a cube label column. 'filterable' will be ignored.`
|
|
1075
|
-
);
|
|
1075
|
+
logWarn(`Column ${colId} is a cube label column. 'filterable' will be ignored.`, this);
|
|
1076
1076
|
return false;
|
|
1077
1077
|
}
|
|
1078
1078
|
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2023 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {HAlign, PlainObject, Some, Thunkable} from '@xh/hoist/core';
|
|
7
|
+
import {HAlign, PlainObject, Some, Thunkable, XH} from '@xh/hoist/core';
|
|
8
8
|
import {genDisplayName} from '@xh/hoist/data';
|
|
9
|
+
|
|
10
|
+
import type {ColGroupDef} from '@xh/hoist/kit/ag-grid';
|
|
9
11
|
import {throwIf, withDefault} from '@xh/hoist/utils/js';
|
|
10
|
-
import {clone, isEmpty, isFunction, isString} from 'lodash';
|
|
12
|
+
import {clone, isEmpty, isFunction, isString, keysIn} from 'lodash';
|
|
11
13
|
import {ReactNode} from 'react';
|
|
12
14
|
import {GridModel} from '../GridModel';
|
|
13
15
|
import {ColumnHeaderClassFn, ColumnHeaderNameFn} from '../Types';
|
|
14
16
|
import {Column, ColumnSpec, getAgHeaderClassFn} from './Column';
|
|
15
17
|
|
|
16
|
-
import type {ColGroupDef} from '@xh/hoist/kit/ag-grid';
|
|
17
|
-
|
|
18
18
|
export interface ColumnGroupSpec {
|
|
19
19
|
/** Column or ColumnGroup configs for children of this group.*/
|
|
20
20
|
children: Array<ColumnGroupSpec | ColumnSpec>;
|
|
@@ -39,6 +39,8 @@ export interface ColumnGroupSpec {
|
|
|
39
39
|
|
|
40
40
|
/** True to skip this column when adding to grid. */
|
|
41
41
|
omit?: Thunkable<boolean>;
|
|
42
|
+
|
|
43
|
+
appData?: PlainObject;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/**
|
|
@@ -62,6 +64,8 @@ export class ColumnGroup {
|
|
|
62
64
|
*/
|
|
63
65
|
agOptions?: PlainObject;
|
|
64
66
|
|
|
67
|
+
appData: PlainObject;
|
|
68
|
+
|
|
65
69
|
/**
|
|
66
70
|
* Not for application use. ColumnGroups are created internally by Hoist.
|
|
67
71
|
*
|
|
@@ -83,6 +87,7 @@ export class ColumnGroup {
|
|
|
83
87
|
headerAlign,
|
|
84
88
|
agOptions,
|
|
85
89
|
borders,
|
|
90
|
+
appData,
|
|
86
91
|
...rest
|
|
87
92
|
} = config;
|
|
88
93
|
|
|
@@ -92,8 +97,6 @@ export class ColumnGroup {
|
|
|
92
97
|
'Must specify groupId or a string headerName for a ColumnGroup'
|
|
93
98
|
);
|
|
94
99
|
|
|
95
|
-
Object.assign(this, rest);
|
|
96
|
-
|
|
97
100
|
this.groupId = withDefault(groupId, headerName) as string;
|
|
98
101
|
this.headerName = withDefault(headerName, genDisplayName(this.groupId));
|
|
99
102
|
this.headerClass = headerClass;
|
|
@@ -102,6 +105,14 @@ export class ColumnGroup {
|
|
|
102
105
|
this.children = children;
|
|
103
106
|
this.gridModel = gridModel;
|
|
104
107
|
this.agOptions = agOptions ? clone(agOptions) : {};
|
|
108
|
+
this.appData = appData ? clone(appData) : {};
|
|
109
|
+
|
|
110
|
+
if (!isEmpty(rest)) {
|
|
111
|
+
const keys = keysIn(rest);
|
|
112
|
+
throw XH.exception(
|
|
113
|
+
`Column group '${this.groupId}' configured with unsupported key(s) '${keys}'. Custom config data must be nested within the 'appData' property.`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
105
116
|
}
|
|
106
117
|
|
|
107
118
|
getAgSpec(): ColGroupDef {
|