@xh/hoist 56.1.0 → 56.3.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 +74 -30
- package/admin/tabs/server/memory/MemoryMonitorModel.ts +3 -2
- package/admin/tabs/server/websocket/WebSocketModel.ts +1 -1
- package/appcontainer/AppContainerModel.ts +3 -1
- package/appcontainer/BannerModel.ts +24 -14
- package/appcontainer/BannerSourceModel.ts +19 -24
- package/cmp/ag-grid/AgGrid.ts +20 -7
- package/cmp/filter/FilterChooserModel.ts +2 -2
- package/cmp/form/FormModel.ts +1 -1
- package/cmp/grid/Grid.ts +68 -25
- package/core/HoistComponent.ts +8 -9
- package/core/HoistProps.ts +4 -1
- package/core/XH.ts +5 -5
- package/core/types/Interfaces.ts +11 -2
- package/data/RecordAction.ts +1 -1
- package/data/Store.ts +1 -1
- package/data/StoreRecord.ts +2 -2
- package/data/cube/Cube.ts +3 -3
- package/data/cube/CubeField.ts +2 -5
- package/data/cube/View.ts +1 -1
- package/data/validation/Rule.ts +3 -3
- package/desktop/appcontainer/Banner.scss +0 -2
- package/desktop/appcontainer/Banner.ts +2 -3
- package/desktop/cmp/dash/DashViewModel.ts +2 -1
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +1 -1
- package/desktop/cmp/dash/container/DashContainerModel.ts +10 -3
- package/desktop/cmp/error/ErrorMessage.ts +2 -2
- package/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.scss +2 -2
- package/desktop/cmp/input/CodeInput.ts +2 -2
- package/desktop/cmp/treemap/TreeMapModel.ts +1 -1
- package/docs/upgrade-to-typescript.md +6 -1
- package/kit/ag-grid/index.ts +1 -0
- package/mobile/appcontainer/Banner.scss +1 -1
- package/mobile/appcontainer/Banner.ts +2 -3
- package/mobile/appcontainer/ExceptionDialogDetails.ts +3 -3
- package/mobile/cmp/error/ErrorMessage.ts +2 -2
- package/mobile/cmp/input/DateInput.ts +2 -2
- package/mobile/cmp/popover/Popover.ts +10 -2
- package/package.json +8 -8
- package/styles/vars.scss +4 -7
- package/svc/AlertBannerService.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,60 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
## v56.3.0 - 2023-05-08
|
|
4
|
+
|
|
5
|
+
### 🎁 New Features
|
|
6
|
+
|
|
7
|
+
* Added support for new `sortOrder` argument to `XH.showBanner()`. A default sort order is applied
|
|
8
|
+
if unspecified, ensuring banners do not unexpectedly change order when refreshed.
|
|
9
|
+
|
|
10
|
+
### ⚙️ Typescript API Adjustments
|
|
11
|
+
|
|
12
|
+
* Improved the recommendation for the app `declare` statement within
|
|
13
|
+
our [TypeScript migration docs](https://github.com/xh/hoist-react/blob/develop/docs/upgrade-to-typescript.md#bootstrapts--service-declarations).
|
|
14
|
+
* See this [Toolbox commit](https://github.com/xh/toolbox/commit/8df642cf) for a small,
|
|
15
|
+
recommended app-level change to improve autocompletion and usage checks within IntelliJ.
|
|
16
|
+
* Added generic support to `XH.message()` and `XH.prompt()` signatures with return type
|
|
17
|
+
of `Promise<T | boolean>`.
|
|
18
|
+
* Moved declaration of optional `children` prop to base `HoistProps` interface - required for TSX
|
|
19
|
+
support.
|
|
20
|
+
|
|
21
|
+
### ✨ Styles
|
|
22
|
+
|
|
23
|
+
* Removed `--xh-banner-height` CSS var.
|
|
24
|
+
* Desktop banners are implemented via `Toolbar`, which correctly sets a min height.
|
|
25
|
+
* Mobile banners now specify `min-height: 40px` via the `.xh-banner` class.
|
|
26
|
+
* This change allows banners containing custom components to grow to fit their contents without
|
|
27
|
+
requiring app-level CSS overrides.
|
|
28
|
+
* Added new `--xh-grid-filter-popover-[height|width]-px` CSS variables to support easier custom
|
|
29
|
+
sizing for grid column header filter popovers.
|
|
30
|
+
|
|
31
|
+
### ⚙️ Technical
|
|
32
|
+
|
|
33
|
+
* Updated internal config defaults to support latest AG Grid v29.3.4+ with use of
|
|
34
|
+
AG `suppressBrowserResizeObserver` config. Applications are encouraged to update to the latest AG
|
|
35
|
+
Grid dependencies to take advantage of ongoing performance updates.
|
|
36
|
+
|
|
37
|
+
## v56.2.0 - 2023-04-28
|
|
38
|
+
|
|
39
|
+
### 🎁 New Features
|
|
40
|
+
|
|
41
|
+
* Added `DashContainerModel.margin` config to customize the width of the resize splitters
|
|
42
|
+
between widgets.
|
|
43
|
+
|
|
44
|
+
### ⚙️ Technical
|
|
45
|
+
|
|
46
|
+
* Improve scrolling performance for `Grid` and `DataView` via internal configuration updates.
|
|
47
|
+
|
|
48
|
+
## v56.1.0 - 2023-04-14
|
|
49
|
+
|
|
50
|
+
### 🎁 New Features
|
|
51
|
+
|
|
52
|
+
* Display improved memory management diagnostics within Admin console Memory Monitor.
|
|
53
|
+
* New metrics require optional-but-recommended update to `hoist-core >= v16.1.0`.
|
|
6
54
|
|
|
7
55
|
### 🐞 Bug Fixes
|
|
8
|
-
* Fixes bug with display/reporting of exceptions during app initialization sequence.
|
|
9
56
|
|
|
57
|
+
* Fixes bug with display/reporting of exceptions during app initialization sequence.
|
|
10
58
|
|
|
11
59
|
## v56.0.0 - 2023-03-29
|
|
12
60
|
|
|
@@ -28,10 +76,12 @@
|
|
|
28
76
|
* Add a dependency on `@ag-grid-community/styles` to import new dedicated styles package.
|
|
29
77
|
* Imports of AG Grid CSS files within your app's `Bootstrap.ts` file will also need to be
|
|
30
78
|
updated to import styles from their new location. The recommended imports are now:
|
|
79
|
+
|
|
31
80
|
```typescript
|
|
32
81
|
import '@ag-grid-community/styles/ag-grid.css';
|
|
33
82
|
import '@ag-grid-community/styles/ag-theme-balham.css';
|
|
34
83
|
```
|
|
84
|
+
|
|
35
85
|
* New `xhActivityTrackingConfig` soft-configuration entry places new limits on the size of
|
|
36
86
|
any `data` objects passed to `XH.track()` calls.
|
|
37
87
|
* Any track requests with data objects exceeding this length will be persisted, but without the
|
|
@@ -65,20 +115,14 @@ import '@ag-grid-community/styles/ag-theme-balham.css';
|
|
|
65
115
|
|
|
66
116
|
## v55.4.0 - 2023-03-23
|
|
67
117
|
|
|
68
|
-
### 🐞 Bug Fixes
|
|
69
|
-
* Addresses `AgGrid` v28 regression whereby changing column visibility via state throws an
|
|
70
|
-
exception and doesn't
|
|
71
|
-
render the grid when column groups are set via the `groupId` property.
|
|
72
|
-
|
|
73
118
|
### 💥 Breaking Changes
|
|
74
|
-
* Hoist now requires `AgGrid` v29.1.0 or higher - update your `AgGrid` dependency in your app's
|
|
75
|
-
`package.json` file. See the [ag-Grid Changelog](https://www.ag-grid.com/changelog) for details.
|
|
76
|
-
* `AgGrid` stylesheets are now imported from the new `@ag-grid-community/styles` module. Update
|
|
77
|
-
your app's `Bootstrap.ts` file to import `ag-grid.css` and `ag-theme-balham.css` from this
|
|
78
|
-
module, and include it as a dependency in your app's `package.json` file.
|
|
79
119
|
|
|
80
|
-
|
|
81
|
-
|
|
120
|
+
* Requires AG Grid v29.0.0 or higher - see release notes for v56.0.0 above.
|
|
121
|
+
|
|
122
|
+
### 🐞 Bug Fixes
|
|
123
|
+
|
|
124
|
+
* Addresses `AgGrid` v28 regression whereby changing column visibility via state breaks grid
|
|
125
|
+
rendering when column groups are set via the `groupId` property.
|
|
82
126
|
|
|
83
127
|
## v55.3.2 - 2023-03-22
|
|
84
128
|
|
|
@@ -1019,7 +1063,7 @@ to use TypeScript for its own app-level code.
|
|
|
1019
1063
|
with the select library component and touch devices.
|
|
1020
1064
|
* Ensure `Column.autosizeBufferPx` is respected if provided.
|
|
1021
1065
|
|
|
1022
|
-
### ✨
|
|
1066
|
+
### ✨ Styles
|
|
1023
1067
|
|
|
1024
1068
|
* New `--xh-menu-item` CSS vars added, with tweaks to default desktop menu styling.
|
|
1025
1069
|
* Highlight background color added to mobile menu items while pressed.
|
|
@@ -1143,7 +1187,7 @@ to use TypeScript for its own app-level code.
|
|
|
1143
1187
|
* Triggering inline editing of text or select editor cells by typing characters will no longer lose
|
|
1144
1188
|
the first character pressed.
|
|
1145
1189
|
|
|
1146
|
-
### ✨
|
|
1190
|
+
### ✨ Styles
|
|
1147
1191
|
|
|
1148
1192
|
* New `TreeStyle.COLORS` and `TreeStyle.COLORS_AND_BORDERS` tree grid styles have been added. Use
|
|
1149
1193
|
the `--xh-grid-tree-group-color-level-*` CSS vars to customize colors as needed.
|
|
@@ -1185,7 +1229,7 @@ to use TypeScript for its own app-level code.
|
|
|
1185
1229
|
`agOptions`.
|
|
1186
1230
|
* Fixes an issue on iOS where `NumberInput` would incorrectly bring up a text keyboard.
|
|
1187
1231
|
|
|
1188
|
-
### ✨
|
|
1232
|
+
### ✨ Styles
|
|
1189
1233
|
|
|
1190
1234
|
* Reduced default Grid header and group row heights to minimize their use of vertical space,
|
|
1191
1235
|
especially at larger sizing modes. As before, apps can override via the `AgGrid.HEADER_HEIGHTS`
|
|
@@ -1210,7 +1254,7 @@ to use TypeScript for its own app-level code.
|
|
|
1210
1254
|
* The in-app changelog will no longer prompt the user with the "What's New" button if category-based
|
|
1211
1255
|
filtering results in a version without any release notes.
|
|
1212
1256
|
|
|
1213
|
-
### ✨
|
|
1257
|
+
### ✨ Styles
|
|
1214
1258
|
|
|
1215
1259
|
* New CSS vars added to support easier customization of desktop Tab font/size/color. Tabs now
|
|
1216
1260
|
respect standard `--xh-font-size` by default.
|
|
@@ -1232,7 +1276,7 @@ to use TypeScript for its own app-level code.
|
|
|
1232
1276
|
* Mobile `Select` input now supports async `queryFn` prop for parity with desktop.
|
|
1233
1277
|
* `TreeMapModel` now supports new `maxLabels` config for improved performance.
|
|
1234
1278
|
|
|
1235
|
-
### ✨
|
|
1279
|
+
### ✨ Styles
|
|
1236
1280
|
|
|
1237
1281
|
* Hoist's default font is now [Inter](https://rsms.me/inter/), shipped and bundled via the
|
|
1238
1282
|
`inter-ui` npm package. Inter is a modern, open-source font that leverages optical sizing to
|
|
@@ -1293,7 +1337,7 @@ to use TypeScript for its own app-level code.
|
|
|
1293
1337
|
|
|
1294
1338
|
* Fixed an issue preventing `FormField` labels from rendering if `fieldDefaults` was undefined.
|
|
1295
1339
|
|
|
1296
|
-
### ✨
|
|
1340
|
+
### ✨ Styles
|
|
1297
1341
|
|
|
1298
1342
|
* New `Badge.compact` prop sets size to half that of parent element when true (default false). The
|
|
1299
1343
|
`position` prop has been removed in favor of customizing placement of the component.
|
|
@@ -1347,7 +1391,7 @@ to use TypeScript for its own app-level code.
|
|
|
1347
1391
|
and
|
|
1348
1392
|
`selectedIds`, respectively, in `StoreSelectionModel`
|
|
1349
1393
|
|
|
1350
|
-
### ✨
|
|
1394
|
+
### ✨ Styles
|
|
1351
1395
|
|
|
1352
1396
|
* Higher contrast on grid context menus for improved legibility.
|
|
1353
1397
|
|
|
@@ -1415,7 +1459,7 @@ to use TypeScript for its own app-level code.
|
|
|
1415
1459
|
custom handling in a raw `AgGrid` component, see the example here:
|
|
1416
1460
|
https://www.ag-grid.com/javascript-grid/row-selection/#example-selection-with-keyboard-arrow-keys
|
|
1417
1461
|
|
|
1418
|
-
### ✨
|
|
1462
|
+
### ✨ Styles
|
|
1419
1463
|
|
|
1420
1464
|
* The red and green color values applied in dark mode have been lightened for improved legibility.
|
|
1421
1465
|
* The default `colorSpec` config for number formatters has changed to use new dedicated CSS classes
|
|
@@ -1471,7 +1515,7 @@ to use TypeScript for its own app-level code.
|
|
|
1471
1515
|
* `withShortDebug` has been deprecated. Use `withDebug` instead, which has the identical behavior.
|
|
1472
1516
|
This API simplification mirrors a recent change to `hoist-core`.
|
|
1473
1517
|
|
|
1474
|
-
### ✨
|
|
1518
|
+
### ✨ Styles
|
|
1475
1519
|
|
|
1476
1520
|
* If the first child of a `Placeholder` component is a Hoist icon, it will not automatically be
|
|
1477
1521
|
styled to 4x size with reduced opacity. (See new Toolbox example under the "Other" tab.)
|
|
@@ -1640,7 +1684,7 @@ your dev-utils dependency for your project to build.
|
|
|
1640
1684
|
* Improvements to exception serialization, especially for any raw javascript `Error` thrown by
|
|
1641
1685
|
client-side code.
|
|
1642
1686
|
|
|
1643
|
-
### ✨
|
|
1687
|
+
### ✨ Styles
|
|
1644
1688
|
|
|
1645
1689
|
* Buttons nested inline within desktop input components (e.g. clear buttons) tweaked to avoid
|
|
1646
1690
|
odd-looking background highlight on hover.
|
|
@@ -1993,7 +2037,7 @@ decorators, in favor of a simpler inheritance-based approach to defining models
|
|
|
1993
2037
|
* Fix issue where grid row striping inadvertently disabled by default for non-tree grids.
|
|
1994
2038
|
* Fix issue where grid empty text cleared on autosize.
|
|
1995
2039
|
|
|
1996
|
-
### ✨
|
|
2040
|
+
### ✨ Styles
|
|
1997
2041
|
|
|
1998
2042
|
* Default `Chart` themes reworked in both light and dark modes to better match overall Hoist theme.
|
|
1999
2043
|
|
|
@@ -2302,7 +2346,7 @@ below regarding related updates to `GridModel.columns` config processing.
|
|
|
2302
2346
|
* `StoreFilterField.filterOptions` has been removed. Set `filterIncludesChildren` directly on
|
|
2303
2347
|
the store instead.
|
|
2304
2348
|
|
|
2305
|
-
### ✨
|
|
2349
|
+
### ✨ Styles
|
|
2306
2350
|
|
|
2307
2351
|
* CSS variables for "intents" - most commonly used on buttons - have been reworked to use HSL color
|
|
2308
2352
|
values and support several standard variations of lightness and transparency.
|
|
@@ -3651,7 +3695,7 @@ leverage the context for model support discussed above.
|
|
|
3651
3695
|
* When checking for a possible expired session within `XH.handleException()`, prompt for app login
|
|
3652
3696
|
only for Ajax requests made to relative URLs (not e.g. remote APIs accessed via CORS). #1189
|
|
3653
3697
|
|
|
3654
|
-
### ✨
|
|
3698
|
+
### ✨ Styles
|
|
3655
3699
|
|
|
3656
3700
|
* Panel splitter collapse button more visible in dark theme. CSS vars to customize further fixed.
|
|
3657
3701
|
* The mobile app menu button has been moved to the right side of the top appBar, consistent with its
|
|
@@ -3908,7 +3952,7 @@ leverage the context for model support discussed above.
|
|
|
3908
3952
|
* FetchService's fetch methods no longer support `acceptJson` parameter. Instead, pass an {"Accept":
|
|
3909
3953
|
"application/json"} header using the `headers` parameter.
|
|
3910
3954
|
|
|
3911
|
-
### ✨
|
|
3955
|
+
### ✨ Styles
|
|
3912
3956
|
|
|
3913
3957
|
* Black point + grid colors adjusted in dark theme to better blend with overall blue-gray tint.
|
|
3914
3958
|
* Mobile styles have been adjusted to increase the default font size and grid row height, in
|
|
@@ -87,7 +87,8 @@ export class MemoryMonitorModel extends HoistModel {
|
|
|
87
87
|
floor: 0,
|
|
88
88
|
top: '30%',
|
|
89
89
|
height: '70%',
|
|
90
|
-
title: {text: 'Heap (mb)'}
|
|
90
|
+
title: {text: 'Heap (mb)'},
|
|
91
|
+
offset: 0
|
|
91
92
|
}
|
|
92
93
|
],
|
|
93
94
|
tooltip: {outside: true, shared: true}
|
|
@@ -185,7 +186,7 @@ export class MemoryMonitorModel extends HoistModel {
|
|
|
185
186
|
async dumpHeapAsync() {
|
|
186
187
|
try {
|
|
187
188
|
const appEnv = XH.getEnv('appEnvironment').toLowerCase(),
|
|
188
|
-
filename = await XH.prompt({
|
|
189
|
+
filename = await XH.prompt<string>({
|
|
189
190
|
title: 'Dump Heap',
|
|
190
191
|
icon: Icon.fileArchive(),
|
|
191
192
|
message: `Specify a filename for the heap dump (to be saved in ${this.heapDumpDir})`,
|
|
@@ -93,7 +93,7 @@ export class WebSocketModel extends HoistModel {
|
|
|
93
93
|
const {selectedRecords} = this.gridModel;
|
|
94
94
|
if (isEmpty(selectedRecords)) return;
|
|
95
95
|
|
|
96
|
-
const message = await XH.prompt({
|
|
96
|
+
const message = await XH.prompt<string>({
|
|
97
97
|
title: 'Force suspend',
|
|
98
98
|
icon: Icon.stopCircle(),
|
|
99
99
|
confirmProps: {text: 'Force Suspend', icon: Icon.stopCircle(), intent: 'danger'},
|
|
@@ -19,6 +19,7 @@ import {SizingModeModel} from './SizingModeModel';
|
|
|
19
19
|
import {ViewportSizeModel} from './ViewportSizeModel';
|
|
20
20
|
import {ThemeModel} from './ThemeModel';
|
|
21
21
|
import {ToastSourceModel} from './ToastSourceModel';
|
|
22
|
+
import {BannerModel} from './BannerModel';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Root object for Framework GUI State.
|
|
@@ -87,10 +88,11 @@ export class AppContainerModel extends HoistModel {
|
|
|
87
88
|
buttonText = mobile ? version : `Update to ${version}`;
|
|
88
89
|
|
|
89
90
|
XH.showBanner({
|
|
90
|
-
category: '
|
|
91
|
+
category: 'xhAppUpdate',
|
|
91
92
|
message,
|
|
92
93
|
icon: Icon.rocket({size: 'lg'}),
|
|
93
94
|
intent: 'warning',
|
|
95
|
+
sortOrder: BannerModel.BANNER_SORTS.APP_UPDATE,
|
|
94
96
|
enableClose: false,
|
|
95
97
|
actionButtonProps: {
|
|
96
98
|
icon: Icon.refresh(),
|
|
@@ -18,36 +18,46 @@ export class BannerModel extends HoistModel {
|
|
|
18
18
|
icon;
|
|
19
19
|
message;
|
|
20
20
|
intent;
|
|
21
|
+
sortOrder;
|
|
21
22
|
className;
|
|
22
23
|
enableClose;
|
|
23
24
|
onClose;
|
|
24
25
|
onClick;
|
|
25
26
|
actionButtonProps;
|
|
26
|
-
props;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
actionButtonProps,
|
|
38
|
-
...props
|
|
39
|
-
}: BannerSpec) {
|
|
28
|
+
/**
|
|
29
|
+
* Sort order for Hoist-provided banners.
|
|
30
|
+
*/
|
|
31
|
+
static BANNER_SORTS = {
|
|
32
|
+
APP_UPDATE: -2,
|
|
33
|
+
ADMIN_ALERT: -1
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
constructor(spec: BannerSpec) {
|
|
40
37
|
super();
|
|
41
38
|
|
|
39
|
+
const {
|
|
40
|
+
category = 'default',
|
|
41
|
+
icon,
|
|
42
|
+
message,
|
|
43
|
+
intent = 'primary',
|
|
44
|
+
sortOrder,
|
|
45
|
+
className,
|
|
46
|
+
enableClose = true,
|
|
47
|
+
onClose,
|
|
48
|
+
onClick,
|
|
49
|
+
actionButtonProps
|
|
50
|
+
} = spec;
|
|
51
|
+
|
|
42
52
|
this.category = category;
|
|
43
53
|
this.icon = icon;
|
|
44
54
|
this.message = message;
|
|
45
55
|
this.intent = intent;
|
|
56
|
+
this.sortOrder = sortOrder;
|
|
46
57
|
this.className = className;
|
|
47
58
|
this.enableClose = enableClose;
|
|
48
59
|
this.onClose = onClose;
|
|
49
60
|
this.onClick = onClick;
|
|
50
61
|
this.actionButtonProps = actionButtonProps;
|
|
51
|
-
this.props = props;
|
|
52
62
|
}
|
|
53
63
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import {XH, HoistModel, managed, BannerSpec} from '@xh/hoist/core';
|
|
8
8
|
import {action, observable, makeObservable} from '@xh/hoist/mobx';
|
|
9
|
-
import {find, reject} from 'lodash';
|
|
9
|
+
import {find, reject, sortBy, without, last} from 'lodash';
|
|
10
10
|
|
|
11
11
|
import {BannerModel} from './BannerModel';
|
|
12
12
|
|
|
@@ -22,17 +22,29 @@ export class BannerSourceModel extends HoistModel {
|
|
|
22
22
|
@observable.ref
|
|
23
23
|
bannerModels: BannerModel[] = [];
|
|
24
24
|
|
|
25
|
-
MAX_BANNERS = 4;
|
|
26
|
-
|
|
27
25
|
constructor() {
|
|
28
26
|
super();
|
|
29
27
|
makeObservable(this);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
@action
|
|
33
|
-
show(
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
show(spec: BannerSpec): BannerModel {
|
|
32
|
+
let {bannerModels} = this,
|
|
33
|
+
ret = new BannerModel(spec);
|
|
34
|
+
|
|
35
|
+
// Removes banner from new banner's category if it exists.
|
|
36
|
+
const existing = find(bannerModels, {category: ret.category});
|
|
37
|
+
if (existing) {
|
|
38
|
+
bannerModels = without(bannerModels, existing);
|
|
39
|
+
XH.safeDestroy(existing);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Place in requested pos, existing pos, or last
|
|
43
|
+
const maxSortOrder = last(bannerModels)?.sortOrder ?? 0;
|
|
44
|
+
ret.sortOrder = spec.sortOrder ?? existing?.sortOrder ?? maxSortOrder + 1;
|
|
45
|
+
bannerModels = sortBy([...bannerModels, ret], 'sortOrder');
|
|
46
|
+
|
|
47
|
+
this.bannerModels = bannerModels;
|
|
36
48
|
return ret;
|
|
37
49
|
}
|
|
38
50
|
|
|
@@ -43,24 +55,7 @@ export class BannerSourceModel extends HoistModel {
|
|
|
43
55
|
this.bannerModels = reject(this.bannerModels, {category});
|
|
44
56
|
}
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
// Implementation
|
|
48
|
-
//------------------------------------
|
|
49
|
-
@action
|
|
50
|
-
addModel(model: BannerModel) {
|
|
51
|
-
// Remove existing banner for category
|
|
52
|
-
this.hide(model.category);
|
|
53
|
-
|
|
54
|
-
// Add new banner, removing old banners if limit exceeded
|
|
55
|
-
const models = [...this.bannerModels, model];
|
|
56
|
-
while (models.length > this.MAX_BANNERS) {
|
|
57
|
-
const bannerModel = models.shift();
|
|
58
|
-
XH.safeDestroy(bannerModel);
|
|
59
|
-
}
|
|
60
|
-
this.bannerModels = models;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
getBanner(category: string): BannerModel {
|
|
58
|
+
private getBanner(category: string): BannerModel {
|
|
64
59
|
return find(this.bannerModels, {category});
|
|
65
60
|
}
|
|
66
61
|
}
|
package/cmp/ag-grid/AgGrid.ts
CHANGED
|
@@ -35,13 +35,18 @@ export interface AgGridProps extends HoistProps<AgGridModel>, GridOptions, Layou
|
|
|
35
35
|
* via the `model` prop to control additional Hoist customizations.
|
|
36
36
|
*
|
|
37
37
|
* This component complements and contrasts with the primary Hoist `Grid` class, which provides a
|
|
38
|
-
* significantly more managed and opinionated
|
|
38
|
+
* significantly more managed and opinionated use of ag-Grid and a number of Hoist-specific
|
|
39
39
|
* extensions and customizations. That fully managed component is expected to cover the majority of
|
|
40
40
|
* use cases within Hoist apps and is recommended as the primary grid class within the toolkit.
|
|
41
41
|
*
|
|
42
42
|
* This wrapper is provided for advanced usages of grid that wish to leverage features of the
|
|
43
43
|
* underlying component not yet supported by the Hoist layer - most notably pivoting - where the
|
|
44
44
|
* managed option would conflict with or complicate access to those features.
|
|
45
|
+
*
|
|
46
|
+
* Note that this component uses the ag-Grid `getRowHeight` prop to provide the grid with row
|
|
47
|
+
* heights. As of 4/2023, this may cause scrolling to be slow in large data sets, and
|
|
48
|
+
* applications may wish to set this prop to `null` and use either a fixed `rowWidth` property, or
|
|
49
|
+
* an explicit per-row setting instead. See GridModel for a more efficient, data aware approach.
|
|
45
50
|
*/
|
|
46
51
|
export const [AgGrid, agGrid] = hoistCmp.withFactory<AgGridProps>({
|
|
47
52
|
displayName: 'AgGrid',
|
|
@@ -79,6 +84,7 @@ export const [AgGrid, agGrid] = hoistCmp.withFactory<AgGridProps>({
|
|
|
79
84
|
item: createElement(AgGridReact, {
|
|
80
85
|
// Default some ag-grid props, but allow overriding.
|
|
81
86
|
getRowHeight: impl.getRowHeight,
|
|
87
|
+
suppressBrowserResizeObserver: true,
|
|
82
88
|
// Pass others on directly.
|
|
83
89
|
...agGridProps,
|
|
84
90
|
|
|
@@ -125,8 +131,10 @@ class AgGridLocalModel extends HoistModel {
|
|
|
125
131
|
@lookup(AgGridModel) model: AgGridModel;
|
|
126
132
|
|
|
127
133
|
get headerHeight() {
|
|
128
|
-
const {hideHeaders, sizingMode} = this.model
|
|
129
|
-
|
|
134
|
+
const {hideHeaders, sizingMode} = this.model,
|
|
135
|
+
AgGridCmp = AgGrid as any;
|
|
136
|
+
|
|
137
|
+
return hideHeaders ? 0 : AgGridCmp.getHeaderHeightForSizingMode(sizingMode);
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
override onLinked() {
|
|
@@ -141,15 +149,20 @@ class AgGridLocalModel extends HoistModel {
|
|
|
141
149
|
}
|
|
142
150
|
}
|
|
143
151
|
|
|
152
|
+
getRowHeight = ({node}) => {
|
|
153
|
+
const {sizingMode} = this.model,
|
|
154
|
+
{groupDisplayType} = this.componentProps,
|
|
155
|
+
AgGridCmp = AgGrid as any;
|
|
156
|
+
return node.group && groupDisplayType === 'groupRows'
|
|
157
|
+
? AgGridCmp.getGroupRowHeightForSizingMode(sizingMode)
|
|
158
|
+
: AgGridCmp.getRowHeightForSizingMode(sizingMode);
|
|
159
|
+
};
|
|
160
|
+
|
|
144
161
|
noteGridReady = agParams => {
|
|
145
162
|
this.model.handleGridReady(agParams);
|
|
146
163
|
this.componentProps.onGridReady?.(agParams);
|
|
147
164
|
};
|
|
148
165
|
|
|
149
|
-
getRowHeight = () => {
|
|
150
|
-
return (AgGrid as any).getRowHeightForSizingMode(this.model.sizingMode);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
166
|
override destroy() {
|
|
154
167
|
this.model?.handleGridUnmount();
|
|
155
168
|
super.destroy();
|
|
@@ -60,7 +60,7 @@ export interface FilterChooserConfig {
|
|
|
60
60
|
fieldSpecs?: Array<FilterChooserFieldSpecConfig | string>;
|
|
61
61
|
|
|
62
62
|
/** Default properties to be assigned to all FilterChooserFieldSpecs created by this model. */
|
|
63
|
-
fieldSpecDefaults?: FilterChooserFieldSpecConfig
|
|
63
|
+
fieldSpecDefaults?: Partial<FilterChooserFieldSpecConfig>;
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
* Store or cube View that should actually be filtered as this model's value changes.
|
|
@@ -460,7 +460,7 @@ export class FilterChooserModel extends HoistModel {
|
|
|
460
460
|
//--------------------------------
|
|
461
461
|
parseFieldSpecs(
|
|
462
462
|
specs: Array<FilterChooserFieldSpecConfig | string>,
|
|
463
|
-
fieldSpecDefaults: FilterChooserFieldSpecConfig
|
|
463
|
+
fieldSpecDefaults: Partial<FilterChooserFieldSpecConfig>
|
|
464
464
|
): Array<FilterChooserFieldSpec> {
|
|
465
465
|
const {valueSource} = this;
|
|
466
466
|
|
package/cmp/form/FormModel.ts
CHANGED
package/cmp/grid/Grid.ts
CHANGED
|
@@ -8,7 +8,6 @@ import composeRefs from '@seznam/compose-react-refs';
|
|
|
8
8
|
import {agGrid, AgGrid} from '@xh/hoist/cmp/ag-grid';
|
|
9
9
|
import {getTreeStyleClasses} from '@xh/hoist/cmp/grid';
|
|
10
10
|
import {getAgGridMenuItems} from '@xh/hoist/cmp/grid/impl/MenuSupport';
|
|
11
|
-
import {Column} from './columns/Column';
|
|
12
11
|
import {div, fragment, frame} from '@xh/hoist/cmp/layout';
|
|
13
12
|
import {
|
|
14
13
|
hoistCmp,
|
|
@@ -17,7 +16,6 @@ import {
|
|
|
17
16
|
LayoutProps,
|
|
18
17
|
lookup,
|
|
19
18
|
PlainObject,
|
|
20
|
-
SizingMode,
|
|
21
19
|
useLocalModel,
|
|
22
20
|
uses,
|
|
23
21
|
XH
|
|
@@ -137,23 +135,9 @@ class GridLocalModel extends HoistModel {
|
|
|
137
135
|
private model: GridModel;
|
|
138
136
|
agOptions: GridOptions;
|
|
139
137
|
viewRef = createRef<HTMLElement>();
|
|
140
|
-
private fixedRowHeight: number;
|
|
141
138
|
private rowKeyNavSupport: RowKeyNavSupport;
|
|
142
139
|
private prevRs: RecordSet;
|
|
143
140
|
|
|
144
|
-
getRowHeight(node) {
|
|
145
|
-
const {model, agOptions} = this,
|
|
146
|
-
{sizingMode, groupRowHeight} = model,
|
|
147
|
-
{groupDisplayType} = agOptions;
|
|
148
|
-
|
|
149
|
-
if (node?.group) {
|
|
150
|
-
return groupRowHeight ?? groupDisplayType === 'groupRows'
|
|
151
|
-
? (AgGrid as any).getGroupRowHeightForSizingMode(sizingMode)
|
|
152
|
-
: (AgGrid as any).getRowHeightForSizingMode(sizingMode);
|
|
153
|
-
}
|
|
154
|
-
return this.fixedRowHeight;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
141
|
/** @returns true if any root-level records have children */
|
|
158
142
|
@computed
|
|
159
143
|
get isHierarchical(): boolean {
|
|
@@ -220,7 +204,7 @@ class GridLocalModel extends HoistModel {
|
|
|
220
204
|
suppressRowClickSelection: !selModel.isEnabled,
|
|
221
205
|
isRowSelectable: () => selModel.isEnabled,
|
|
222
206
|
tooltipShowDelay: 0,
|
|
223
|
-
getRowHeight:
|
|
207
|
+
getRowHeight: this.defaultGetRowHeight,
|
|
224
208
|
getRowClass: ({data}) => (model.rowClassFn ? model.rowClassFn(data) : null),
|
|
225
209
|
rowClassRules: model.rowClassRules,
|
|
226
210
|
noRowsOverlayComponent: observer(() => div(this.emptyText)),
|
|
@@ -367,20 +351,78 @@ class GridLocalModel extends HoistModel {
|
|
|
367
351
|
};
|
|
368
352
|
}
|
|
369
353
|
|
|
354
|
+
//----------------------
|
|
355
|
+
// Row Height Management
|
|
356
|
+
//----------------------
|
|
357
|
+
@computed
|
|
358
|
+
get calculatedRowHeight() {
|
|
359
|
+
const {model} = this,
|
|
360
|
+
AgGridCmp = AgGrid as any;
|
|
361
|
+
return max([
|
|
362
|
+
AgGridCmp.getRowHeightForSizingMode(model.sizingMode),
|
|
363
|
+
maxBy(model.getVisibleLeafColumns(), 'rowHeight')?.rowHeight
|
|
364
|
+
]);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
@computed
|
|
368
|
+
get calculatedGroupRowHeight() {
|
|
369
|
+
const {sizingMode, groupRowHeight} = this.model,
|
|
370
|
+
{groupDisplayType} = this.agOptions,
|
|
371
|
+
AgGridCmp = AgGrid as any;
|
|
372
|
+
return groupRowHeight ?? groupDisplayType === 'groupRows'
|
|
373
|
+
? AgGridCmp.getGroupRowHeightForSizingMode(sizingMode)
|
|
374
|
+
: AgGridCmp.getRowHeightForSizingMode(sizingMode);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
defaultGetRowHeight = ({node}) => {
|
|
378
|
+
return node.group ? this.calculatedGroupRowHeight : this.calculatedRowHeight;
|
|
379
|
+
};
|
|
380
|
+
|
|
370
381
|
rowHeightReaction() {
|
|
371
|
-
const {model} = this;
|
|
372
382
|
return {
|
|
373
|
-
track: () => [
|
|
374
|
-
|
|
375
|
-
this.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
383
|
+
track: () => [
|
|
384
|
+
this.useScrollOptimization,
|
|
385
|
+
this.calculatedRowHeight,
|
|
386
|
+
this.calculatedGroupRowHeight
|
|
387
|
+
],
|
|
388
|
+
run: () => {
|
|
389
|
+
const {agApi} = this.model;
|
|
390
|
+
if (!agApi) return;
|
|
391
|
+
agApi.resetRowHeights();
|
|
392
|
+
this.applyScrollOptimization();
|
|
379
393
|
},
|
|
380
|
-
|
|
394
|
+
debounce: 1
|
|
381
395
|
};
|
|
382
396
|
}
|
|
383
397
|
|
|
398
|
+
@computed
|
|
399
|
+
get useScrollOptimization() {
|
|
400
|
+
// When true, we preemptively evaluate and assign functional row heights after data loading.
|
|
401
|
+
// This improves slow scrolling but means function not guaranteed to be re-called
|
|
402
|
+
// when node is rendered in viewport.
|
|
403
|
+
const {model, agOptions} = this;
|
|
404
|
+
return (
|
|
405
|
+
agOptions.getRowHeight &&
|
|
406
|
+
!agOptions.rowHeight &&
|
|
407
|
+
!model.getVisibleLeafColumns().some(c => c.autoHeight) &&
|
|
408
|
+
model.experimental.useScrollOptimization !== false
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
applyScrollOptimization() {
|
|
413
|
+
if (!this.useScrollOptimization) return;
|
|
414
|
+
const {agApi, agColumnApi} = this.model,
|
|
415
|
+
{getRowHeight} = this.agOptions,
|
|
416
|
+
params = {api: agApi, columnApi: agColumnApi, context: null} as any;
|
|
417
|
+
|
|
418
|
+
agApi.forEachNode(node => {
|
|
419
|
+
params.node = node;
|
|
420
|
+
params.data = node.data;
|
|
421
|
+
node.setRowHeight(getRowHeight(params));
|
|
422
|
+
});
|
|
423
|
+
agApi.onRowHeightChanged();
|
|
424
|
+
}
|
|
425
|
+
|
|
384
426
|
columnsReaction() {
|
|
385
427
|
const {model} = this;
|
|
386
428
|
return {
|
|
@@ -627,6 +669,7 @@ class GridLocalModel extends HoistModel {
|
|
|
627
669
|
model.noteAgExpandStateChange();
|
|
628
670
|
|
|
629
671
|
this.prevRs = newRs;
|
|
672
|
+
this.applyScrollOptimization();
|
|
630
673
|
}
|
|
631
674
|
|
|
632
675
|
syncSelection() {
|
package/core/HoistComponent.ts
CHANGED
|
@@ -43,8 +43,10 @@ import {
|
|
|
43
43
|
} from 'react';
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Type representing props passed to a HoistComponent's render function.
|
|
47
|
+
*
|
|
48
|
+
* This type removes from its base type several props that are used by HoistComponent itself and
|
|
49
|
+
* not provided to the render function.
|
|
48
50
|
*/
|
|
49
51
|
export type RenderPropsOf<P extends HoistProps> = P & {
|
|
50
52
|
/** Pre-processed by HoistComponent internals into a mounted model. Never passed to render. */
|
|
@@ -52,15 +54,12 @@ export type RenderPropsOf<P extends HoistProps> = P & {
|
|
|
52
54
|
|
|
53
55
|
/** Pre-processed by HoistComponent internals and attached to model. Never passed to render. */
|
|
54
56
|
modelRef: never;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* React Children. Populated on props by React internally, before rendering. Applications
|
|
58
|
-
* will typically provide children to a component via JSX or the `item(s)` property passed to
|
|
59
|
-
* an element factory.
|
|
60
|
-
*/
|
|
61
|
-
children?: ReactNode;
|
|
62
57
|
};
|
|
63
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Configuration for creating a Component. May be specified either as a render function,
|
|
61
|
+
* or an object containing a render function and associated metadata.
|
|
62
|
+
*/
|
|
64
63
|
export type ComponentConfig<P extends HoistProps> =
|
|
65
64
|
| ((props: RenderPropsOf<P>, ref?: ForwardedRef<any>) => ReactNode)
|
|
66
65
|
| {
|