@xh/hoist 72.0.0-SNAPSHOT.1737676613505 → 72.0.0-SNAPSHOT.1737733122023
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 +2 -1
- package/admin/tabs/cluster/instances/InstancesTabModel.ts +17 -12
- package/build/types/admin/tabs/cluster/instances/InstancesTabModel.d.ts +1 -2
- package/build/types/cmp/grid/Grid.d.ts +9 -10
- package/build/types/cmp/grid/GridModel.d.ts +2 -2
- package/cmp/ag-grid/AgGridModel.ts +1 -1
- package/cmp/grid/Grid.ts +43 -48
- package/cmp/grid/GridModel.ts +15 -11
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
### 🐞 Bug Fixes
|
|
16
16
|
|
|
17
17
|
* Fixed `ViewManagerModel` unique name validation.
|
|
18
|
-
* `GridModel.restoreDefaultsAsync()`
|
|
18
|
+
* Fixed `GridModel.restoreDefaultsAsync()` to restore any default filter, rather than simply clearing it.
|
|
19
|
+
* Improved suboptimal column state synchronization between `GridModel` and AG Grid.
|
|
19
20
|
|
|
20
21
|
### ⚙️ Technical
|
|
21
22
|
|
|
@@ -17,12 +17,11 @@ import {memoryMonitorPanel} from '@xh/hoist/admin/tabs/cluster/instances/memory/
|
|
|
17
17
|
import {servicePanel} from '@xh/hoist/admin/tabs/cluster/instances/services/ServicePanel';
|
|
18
18
|
import {webSocketPanel} from '@xh/hoist/admin/tabs/cluster/instances/websocket/WebSocketPanel';
|
|
19
19
|
import {badge} from '@xh/hoist/cmp/badge';
|
|
20
|
-
import {GridModel, numberCol} from '@xh/hoist/cmp/grid';
|
|
20
|
+
import {GridContextMenuSpec, GridModel, numberCol} from '@xh/hoist/cmp/grid';
|
|
21
21
|
import {hbox} from '@xh/hoist/cmp/layout';
|
|
22
22
|
import {getRelativeTimestamp} from '@xh/hoist/cmp/relativetimestamp';
|
|
23
23
|
import {TabContainerModel, TabModel} from '@xh/hoist/cmp/tab';
|
|
24
24
|
import {HoistModel, LoadSpec, lookup, managed, PlainObject, XH} from '@xh/hoist/core';
|
|
25
|
-
import {RecordActionSpec} from '@xh/hoist/data';
|
|
26
25
|
import {Icon} from '@xh/hoist/icon';
|
|
27
26
|
import {makeObservable} from '@xh/hoist/mobx';
|
|
28
27
|
import {Timer} from '@xh/hoist/utils/async';
|
|
@@ -38,15 +37,6 @@ export class InstancesTabModel extends HoistModel {
|
|
|
38
37
|
@managed readonly tabContainerModel: TabContainerModel = this.createTabContainerModel();
|
|
39
38
|
@managed readonly timer: Timer;
|
|
40
39
|
|
|
41
|
-
shutdownAction: RecordActionSpec = {
|
|
42
|
-
icon: Icon.skull(),
|
|
43
|
-
text: 'Shutdown Instance',
|
|
44
|
-
intent: 'danger',
|
|
45
|
-
actionFn: ({record}) => this.shutdownInstanceAsync(record.data),
|
|
46
|
-
displayFn: () => ({hidden: AppModel.readonly}),
|
|
47
|
-
recordsRequired: 1
|
|
48
|
-
};
|
|
49
|
-
|
|
50
40
|
get instance(): PlainObject {
|
|
51
41
|
return this.gridModel.selectedRecord?.data;
|
|
52
42
|
}
|
|
@@ -182,10 +172,25 @@ export class InstancesTabModel extends HoistModel {
|
|
|
182
172
|
rendererIsComplex: true
|
|
183
173
|
}
|
|
184
174
|
],
|
|
185
|
-
contextMenu:
|
|
175
|
+
contextMenu: this.createContextMenu()
|
|
186
176
|
});
|
|
187
177
|
}
|
|
188
178
|
|
|
179
|
+
private createContextMenu(): GridContextMenuSpec {
|
|
180
|
+
return [
|
|
181
|
+
{
|
|
182
|
+
icon: Icon.skull(),
|
|
183
|
+
text: 'Shutdown Instance',
|
|
184
|
+
intent: 'danger',
|
|
185
|
+
actionFn: ({record}) => this.shutdownInstanceAsync(record.data),
|
|
186
|
+
displayFn: () => ({hidden: AppModel.readonly}),
|
|
187
|
+
recordsRequired: 1
|
|
188
|
+
},
|
|
189
|
+
'-',
|
|
190
|
+
...GridModel.defaultContextMenu
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
|
|
189
194
|
private createTabContainerModel() {
|
|
190
195
|
return new TabContainerModel({
|
|
191
196
|
route: 'default.cluster.instances',
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { GridModel } from '@xh/hoist/cmp/grid';
|
|
2
2
|
import { TabContainerModel } from '@xh/hoist/cmp/tab';
|
|
3
3
|
import { HoistModel, LoadSpec, PlainObject } from '@xh/hoist/core';
|
|
4
|
-
import { RecordActionSpec } from '@xh/hoist/data';
|
|
5
4
|
import { Timer } from '@xh/hoist/utils/async';
|
|
6
5
|
import { ReactNode } from 'react';
|
|
7
6
|
export declare class InstancesTabModel extends HoistModel {
|
|
@@ -12,7 +11,6 @@ export declare class InstancesTabModel extends HoistModel {
|
|
|
12
11
|
readonly gridModel: GridModel;
|
|
13
12
|
readonly tabContainerModel: TabContainerModel;
|
|
14
13
|
readonly timer: Timer;
|
|
15
|
-
shutdownAction: RecordActionSpec;
|
|
16
14
|
get instance(): PlainObject;
|
|
17
15
|
get instanceName(): string;
|
|
18
16
|
get isMultiInstance(): boolean;
|
|
@@ -21,6 +19,7 @@ export declare class InstancesTabModel extends HoistModel {
|
|
|
21
19
|
constructor();
|
|
22
20
|
formatInstance(instance: PlainObject): ReactNode;
|
|
23
21
|
private createGridModel;
|
|
22
|
+
private createContextMenu;
|
|
24
23
|
private createTabContainerModel;
|
|
25
24
|
private shutdownInstanceAsync;
|
|
26
25
|
private get autoRefreshInterval();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
/// <reference types="lodash" />
|
|
3
|
-
import {
|
|
3
|
+
import { GridApi } from '@ag-grid-community/core';
|
|
4
|
+
import { ColumnState } from '@xh/hoist/cmp/grid';
|
|
5
|
+
import { HoistModel, HoistProps, LayoutProps, PlainObject, ReactionSpec, TestSupportProps } from '@xh/hoist/core';
|
|
4
6
|
import { RecordSet } from '@xh/hoist/data/impl/RecordSet';
|
|
5
7
|
import type { ColDef, ColGroupDef, GetContextMenuItemsParams, GridOptions, GridReadyEvent, ProcessCellForExportParams } from '@xh/hoist/kit/ag-grid';
|
|
6
8
|
import './Grid.scss';
|
|
@@ -53,7 +55,7 @@ export declare class GridLocalModel extends HoistModel {
|
|
|
53
55
|
onLinked(): void;
|
|
54
56
|
private createDefaultAgOptions;
|
|
55
57
|
getColumnDefs(): Array<ColDef | ColGroupDef>;
|
|
56
|
-
getContextMenuItems: (params: GetContextMenuItemsParams) => (string | import("@
|
|
58
|
+
getContextMenuItems: (params: GetContextMenuItemsParams) => (string | import("@ag-grid-community/core").MenuItemDef<any, any>)[];
|
|
57
59
|
dataReaction(): {
|
|
58
60
|
track: () => (boolean | import("@xh/hoist/core").VSide | import("../../data").StoreRecord[] | RecordSet)[];
|
|
59
61
|
run: () => void;
|
|
@@ -63,11 +65,11 @@ export declare class GridLocalModel extends HoistModel {
|
|
|
63
65
|
run: () => void;
|
|
64
66
|
};
|
|
65
67
|
sortReaction(): {
|
|
66
|
-
track: () => (
|
|
68
|
+
track: () => (GridApi<any> | import("@xh/hoist/cmp/grid").GridSorter[])[];
|
|
67
69
|
run: ([agApi, sortBy]: [any, any]) => void;
|
|
68
70
|
};
|
|
69
71
|
groupReaction(): {
|
|
70
|
-
track: () => (string[] |
|
|
72
|
+
track: () => (string[] | GridApi<any>)[];
|
|
71
73
|
run: ([agApi, groupBy]: [any, any]) => void;
|
|
72
74
|
};
|
|
73
75
|
get calculatedRowHeight(): any;
|
|
@@ -83,13 +85,10 @@ export declare class GridLocalModel extends HoistModel {
|
|
|
83
85
|
get useScrollOptimization(): boolean;
|
|
84
86
|
applyScrollOptimization(): void;
|
|
85
87
|
columnsReaction(): {
|
|
86
|
-
track: () => (
|
|
88
|
+
track: () => (GridApi<any> | (import("@xh/hoist/cmp/grid").Column | import("@xh/hoist/cmp/grid").ColumnGroup)[])[];
|
|
87
89
|
run: ([api]: [any]) => void;
|
|
88
90
|
};
|
|
89
|
-
columnStateReaction():
|
|
90
|
-
track: () => (import("@xh/hoist/kit/ag-grid").GridApi<any> | import("@xh/hoist/cmp/grid").ColumnState[])[];
|
|
91
|
-
run: ([api, colState]: [any, any]) => void;
|
|
92
|
-
};
|
|
91
|
+
columnStateReaction(): ReactionSpec<[GridApi, ColumnState[]]>;
|
|
93
92
|
sizingModeReaction(): {
|
|
94
93
|
track: () => import("@xh/hoist/core").SizingMode;
|
|
95
94
|
run: () => void;
|
|
@@ -126,7 +125,7 @@ export declare class GridLocalModel extends HoistModel {
|
|
|
126
125
|
readFilterState(): import("@ag-grid-community/core").FilterModel;
|
|
127
126
|
writeFilterState(filterState: any): void;
|
|
128
127
|
processCellForClipboard: ({ value, node, column }: ProcessCellForExportParams) => any;
|
|
129
|
-
navigateToNextCell: (agParams: any) => import("@
|
|
128
|
+
navigateToNextCell: (agParams: any) => import("@ag-grid-community/core").CellPosition;
|
|
130
129
|
onCellMouseDown: (evt: any) => void;
|
|
131
130
|
onKeyDown: (evt: any) => void;
|
|
132
131
|
onRowClicked: (evt: any) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, RowClickedEvent, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
|
1
|
+
import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, ColumnState as AgColumnState, RowClickedEvent, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
|
2
2
|
import { AgGridModel } from '@xh/hoist/cmp/ag-grid';
|
|
3
3
|
import { Column, ColumnGroup, ColumnGroupSpec, ColumnSpec, GridAutosizeMode, GridFilterModelConfig, GridGroupSortFn, TreeStyle } from '@xh/hoist/cmp/grid';
|
|
4
4
|
import { GridFilterModel } from '@xh/hoist/cmp/grid/filter/GridFilterModel';
|
|
@@ -430,7 +430,7 @@ export declare class GridModel extends HoistModel {
|
|
|
430
430
|
setColumns(colConfigs: Array<ColumnSpec | ColumnGroupSpec>): void;
|
|
431
431
|
setColumnState(colState: Partial<ColumnState>[]): void;
|
|
432
432
|
showColChooser(): void;
|
|
433
|
-
noteAgColumnStateChanged(agColState:
|
|
433
|
+
noteAgColumnStateChanged(agColState: AgColumnState[]): void;
|
|
434
434
|
setExpandState(expandState: any): void;
|
|
435
435
|
noteAgExpandStateChange(): void;
|
|
436
436
|
noteAgSelectionStateChanged(): void;
|
|
@@ -395,7 +395,7 @@ export class AgGridModel extends HoistModel {
|
|
|
395
395
|
];
|
|
396
396
|
|
|
397
397
|
let {isPivot, columns} = colState;
|
|
398
|
-
agApi.
|
|
398
|
+
agApi.setGridOption('pivotMode', isPivot);
|
|
399
399
|
|
|
400
400
|
if (isPivot && columns.some(it => !isNil(it.pivotIndex) && it.pivotIndex >= 0)) {
|
|
401
401
|
// Exclude the auto group column as this causes issues with ag-grid when in pivot mode
|
package/cmp/grid/Grid.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {ColumnState as AgColumnState, GridApi} from '@ag-grid-community/core';
|
|
7
8
|
import composeRefs from '@seznam/compose-react-refs';
|
|
8
9
|
import {agGrid, AgGrid} from '@xh/hoist/cmp/ag-grid';
|
|
9
|
-
import {getTreeStyleClasses} from '@xh/hoist/cmp/grid';
|
|
10
|
+
import {ColumnState, getTreeStyleClasses} from '@xh/hoist/cmp/grid';
|
|
10
11
|
import {gridHScrollbar} from '@xh/hoist/cmp/grid/impl/GridHScrollbar';
|
|
11
12
|
import {getAgGridMenuItems} from '@xh/hoist/cmp/grid/impl/MenuSupport';
|
|
12
13
|
import {div, fragment, frame, vframe} from '@xh/hoist/cmp/layout';
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
LayoutProps,
|
|
18
19
|
lookup,
|
|
19
20
|
PlainObject,
|
|
21
|
+
ReactionSpec,
|
|
20
22
|
TestSupportProps,
|
|
21
23
|
useLocalModel,
|
|
22
24
|
uses,
|
|
@@ -44,7 +46,7 @@ import {wait} from '@xh/hoist/promise';
|
|
|
44
46
|
import {consumeEvent, isDisplayed, logWithDebug} from '@xh/hoist/utils/js';
|
|
45
47
|
import {createObservableRef, getLayoutProps} from '@xh/hoist/utils/react';
|
|
46
48
|
import classNames from 'classnames';
|
|
47
|
-
import {debounce, isEmpty, isEqual, isNil, max, maxBy, merge} from 'lodash';
|
|
49
|
+
import {compact, debounce, isBoolean, isEmpty, isEqual, isNil, max, maxBy, merge} from 'lodash';
|
|
48
50
|
import './Grid.scss';
|
|
49
51
|
import {GridModel} from './GridModel';
|
|
50
52
|
import {columnGroupHeader} from './impl/ColumnGroupHeader';
|
|
@@ -463,7 +465,7 @@ export class GridLocalModel extends HoistModel {
|
|
|
463
465
|
};
|
|
464
466
|
}
|
|
465
467
|
|
|
466
|
-
columnStateReaction() {
|
|
468
|
+
columnStateReaction(): ReactionSpec<[GridApi, ColumnState[]]> {
|
|
467
469
|
const {model} = this;
|
|
468
470
|
return {
|
|
469
471
|
track: () => [model.agApi, model.columnState],
|
|
@@ -472,65 +474,57 @@ export class GridLocalModel extends HoistModel {
|
|
|
472
474
|
|
|
473
475
|
const agColState = api.getColumnState();
|
|
474
476
|
|
|
475
|
-
//
|
|
477
|
+
// Insert the auto group col state if it exists, since we won't have it in our column state list
|
|
476
478
|
const autoColState = agColState.find(c => c.colId === 'ag-Grid-AutoColumn');
|
|
477
479
|
if (autoColState) {
|
|
478
|
-
|
|
480
|
+
const {colId, width, hide, pinned} = autoColState;
|
|
481
|
+
colState.splice(agColState.indexOf(autoColState), 0, {
|
|
482
|
+
colId,
|
|
483
|
+
width,
|
|
484
|
+
hidden: hide,
|
|
485
|
+
pinned: isBoolean(pinned) ? (pinned ? 'left' : null) : pinned
|
|
486
|
+
});
|
|
479
487
|
}
|
|
480
488
|
|
|
481
|
-
//
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
colState.
|
|
490
|
-
const agCol = agColState
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
489
|
+
// Determine if column order has changed
|
|
490
|
+
const applyOrder = !isEqual(
|
|
491
|
+
colState.map(c => c.colId),
|
|
492
|
+
agColState.map(c => c.colId)
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
// Build a list of column state changes
|
|
496
|
+
colState = compact(
|
|
497
|
+
colState.map(({colId, width, hidden, pinned}) => {
|
|
498
|
+
const agCol: AgColumnState = agColState.find(c => c.colId === colId) || {
|
|
499
|
+
colId
|
|
500
|
+
},
|
|
501
|
+
ret: any = {colId};
|
|
502
|
+
|
|
503
|
+
let hasChanges = applyOrder;
|
|
504
|
+
|
|
505
|
+
if (agCol.width !== width) {
|
|
506
|
+
ret.width = width;
|
|
495
507
|
hasChanges = true;
|
|
496
508
|
}
|
|
497
|
-
|
|
498
|
-
|
|
509
|
+
|
|
510
|
+
if (agCol.hide !== hidden) {
|
|
511
|
+
ret.hide = hidden;
|
|
499
512
|
hasChanges = true;
|
|
500
513
|
}
|
|
501
|
-
|
|
502
|
-
|
|
514
|
+
|
|
515
|
+
if (agCol.pinned !== pinned) {
|
|
516
|
+
ret.pinned = pinned;
|
|
503
517
|
hasChanges = true;
|
|
504
518
|
}
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
// We need to tell agGrid to refresh its flexed column sizes due to
|
|
508
|
-
// a regression introduced in 25.1.0. See #2341
|
|
509
|
-
if (hasChanges) {
|
|
510
|
-
api.columnModel.refreshFlexedColumns({
|
|
511
|
-
updateBodyWidths: true,
|
|
512
|
-
fireResizedEvent: true
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
519
|
|
|
516
|
-
|
|
517
|
-
|
|
520
|
+
return hasChanges ? ret : null;
|
|
521
|
+
})
|
|
522
|
+
);
|
|
518
523
|
|
|
519
|
-
|
|
520
|
-
// Merge our state onto the ag column state to get any state which we do not yet support
|
|
521
|
-
colState = colState.map(({colId, width, hidden, pinned}) => {
|
|
522
|
-
const agCol = agColState.find(c => c.colId === colId) || {};
|
|
523
|
-
return {
|
|
524
|
-
colId,
|
|
525
|
-
...agCol,
|
|
526
|
-
width,
|
|
527
|
-
pinned,
|
|
528
|
-
hide: hidden
|
|
529
|
-
};
|
|
530
|
-
});
|
|
524
|
+
if (isEmpty(colState)) return;
|
|
531
525
|
|
|
532
526
|
this.doWithPreservedState({expansion: false}, () => {
|
|
533
|
-
api.applyColumnState({state: colState, applyOrder
|
|
527
|
+
api.applyColumnState({state: colState, applyOrder});
|
|
534
528
|
});
|
|
535
529
|
}
|
|
536
530
|
};
|
|
@@ -870,6 +864,7 @@ export class GridLocalModel extends HoistModel {
|
|
|
870
864
|
* by conditionally stopping the focus event from propagating.
|
|
871
865
|
*/
|
|
872
866
|
private static didAddFocusFixListener = false;
|
|
867
|
+
|
|
873
868
|
static addFocusFixListener() {
|
|
874
869
|
if (this.didAddFocusFixListener) return;
|
|
875
870
|
document.addEventListener(
|
package/cmp/grid/GridModel.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
CellContextMenuEvent,
|
|
10
10
|
CellDoubleClickedEvent,
|
|
11
11
|
ColumnEvent,
|
|
12
|
+
ColumnState as AgColumnState,
|
|
12
13
|
RowClickedEvent,
|
|
13
14
|
RowDoubleClickedEvent
|
|
14
15
|
} from '@ag-grid-community/core';
|
|
@@ -77,6 +78,7 @@ import {
|
|
|
77
78
|
first,
|
|
78
79
|
forEach,
|
|
79
80
|
isArray,
|
|
81
|
+
isBoolean,
|
|
80
82
|
isEmpty,
|
|
81
83
|
isFunction,
|
|
82
84
|
isNil,
|
|
@@ -1073,17 +1075,19 @@ export class GridModel extends HoistModel {
|
|
|
1073
1075
|
(this.colChooserModel as any)?.open();
|
|
1074
1076
|
}
|
|
1075
1077
|
|
|
1076
|
-
noteAgColumnStateChanged(agColState) {
|
|
1077
|
-
const colStateChanges = agColState.map(
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1078
|
+
noteAgColumnStateChanged(agColState: AgColumnState[]) {
|
|
1079
|
+
const colStateChanges: Partial<ColumnState>[] = agColState.map(
|
|
1080
|
+
({colId, width, hide, pinned}) => {
|
|
1081
|
+
const col = this.findColumn(this.columns, colId);
|
|
1082
|
+
if (!col) return null;
|
|
1083
|
+
return {
|
|
1084
|
+
colId,
|
|
1085
|
+
pinned: isBoolean(pinned) ? (pinned ? 'left' : null) : pinned,
|
|
1086
|
+
hidden: !!hide,
|
|
1087
|
+
width: col.flex ? undefined : width
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1087
1091
|
|
|
1088
1092
|
pull(colStateChanges, null);
|
|
1089
1093
|
this.applyColumnStateChanges(colStateChanges);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "72.0.0-SNAPSHOT.
|
|
3
|
+
"version": "72.0.0-SNAPSHOT.1737733122023",
|
|
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",
|