@xh/hoist 71.0.0-SNAPSHOT.1735586653168 → 71.0.0-SNAPSHOT.1735588181793

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 CHANGED
@@ -4,35 +4,43 @@
4
4
 
5
5
  ### 💥 Breaking Changes
6
6
 
7
- * `ErrorMessage` is now cross-platform. Its import paths has changed from `@xh/hoist/desktop/cmp/error`
8
- and `@xh/hoist/mobile/cmp/error` to `@xh/hoist/cmp/error`.
9
- * `Mask` is now cross-platform. Its import paths has changed from `@xh/hoist/desktop/cmp/mask`
10
- and `@xh/hoist/mobile/cmp/mask` to `@xh/hoist/cmp/mask`.
11
- * `LoadingIndicator` is now cross-platform. Its import paths has changed from
12
- `@xh/hoist/desktop/cmp/loadingindicator` and `@xh/hoist/mobile/cmp/loadingindicator` to
7
+ * Requires `hoist-core >= 26.1` with new APIs to support `ViewManager`.
8
+ * `ErrorMessage` is now cross-platform - update imports from `@xh/hoist/desktop/cmp/error`
9
+ or `@xh/hoist/mobile/cmp/error` to `@xh/hoist/cmp/error`.
10
+ * `Mask` is now cross-platform - update imports from `@xh/hoist/desktop/cmp/mask` or
11
+ `@xh/hoist/mobile/cmp/mask` to `@xh/hoist/cmp/mask`.
12
+ * `LoadingIndicator` is now cross-platform - update imports from
13
+ `@xh/hoist/desktop/cmp/loadingindicator` or `@xh/hoist/mobile/cmp/loadingindicator` to
13
14
  `@xh/hoist/cmp/loadingindicator`.
14
15
  * `TreeMap` and `SplitTreeMap` are now cross-platform and can be used in mobile applications.
15
- Their import paths have changed from `@xh/hoist/desktop/cmp/treemap` to `@xh/hoist/cmp/treemap`.
16
- * The `RefreshButton` `model` prop has been renamed `target` for clarity and consistency.
16
+ Update imports from `@xh/hoist/desktop/cmp/treemap` to `@xh/hoist/cmp/treemap`.
17
+ * Renamed `RefreshButton.model` prop to `target` for clarity and consistency.
17
18
 
18
19
  ### 🎁 New Features
19
20
 
20
- * Major Improvements to ViewManager component
21
- * Support for persisting pending value.
22
- * Handle delete and update collisions more gracefully.
23
- * Support for `settleTime`,
24
- * Improved management UI Dialog.
25
- * Support for "global" views.
26
- * New `SessionStorageService` and associated persistence provider provides support for saving
27
- tab local data across reloads.
28
- * Added support for `AuthZeroClientConfig.audience` to support improved configuration of Auth0 OAuth
29
- clients requesting access tokens, covering cases when third-party cookies are blocked.
21
+ * Major improvements to ViewManager component, including:
22
+ * A clearer, better organized view management dialog.
23
+ * Support for persisting a view's pending value, to avoid users losing changes when e.g. an app
24
+ goes into idle mode and requires a page refresh to restore.
25
+ * Improved handling of delete / update collisions.
26
+ * New `ViewManagerModel.settleTime` config, to allow persisted components such as dashboards to
27
+ fully resolve their rendered state before capturing a baseline for dirty checks.
28
+ * Added `SessionStorageService` and associated persistence provider to support saving tab-local
29
+ data across reloads. Exact analog to `LocalStorageService`, but scoped to lifetime of current tab.
30
+ * Added `AuthZeroClientConfig.audience` config to support improved flow for Auth0 OAuth clients that
31
+ request access tokens. Specify your access token audience here to allow the client to fetch both
32
+ ID and access tokens in a single request and to use refresh tokens to maintain access without
33
+ relying on third-party cookies.
34
+ * Updated sorting on grouped grids to place ungrouped items at the bottom.
30
35
 
31
36
  ### 🐞 Bug Fixes
32
37
 
33
38
  * Fixed sizing and position of mobile `TabContainer` switcher, particularly when the switcher is
34
39
  positioned with `top` orientation.
35
40
  * Fixed styling of `ButtonGroup` in vertical orientations.
41
+ * Improved handling of calls to `DashContainerModel.loadStateAsync()` when the component has yet
42
+ to be rendered. Requested state updates are no longer dropped, and will be applied as soon as the
43
+ component is ready to do so.
36
44
 
37
45
  ### ⚙️ Technical
38
46
 
@@ -1,26 +1,6 @@
1
- import { PlainObject } from '@xh/hoist/core';
2
1
  import { ViewInfo } from './ViewInfo';
3
2
  import { View } from './View';
4
- import { ViewManagerModel } from './ViewManagerModel';
5
- export interface ViewCreateSpec {
6
- name: string;
7
- group: string;
8
- description: string;
9
- isShared: boolean;
10
- value?: PlainObject;
11
- }
12
- export interface ViewUpdateSpec {
13
- name: string;
14
- group: string;
15
- description: string;
16
- isShared?: boolean;
17
- isDefaultPinned?: boolean;
18
- }
19
- export interface ViewUserState {
20
- currentView?: string;
21
- userPinned: Record<string, boolean>;
22
- autoSave: boolean;
23
- }
3
+ import { ViewManagerModel, ViewUserState, ViewUpdateSpec, ViewCreateSpec } from './ViewManagerModel';
24
4
  /**
25
5
  * Supporting class for accessing and updating ViewManager and View data.
26
6
  *
@@ -45,6 +25,6 @@ export declare class DataAccess<T> {
45
25
  /** Update a view's value. */
46
26
  updateViewValueAsync(view: View<T>, value: Partial<T>): Promise<View<T>>;
47
27
  deleteViewsAsync(views: ViewInfo[]): Promise<void>;
48
- updateStateAsync(update: Partial<ViewUserState>): Promise<void>;
28
+ updateStateAsync(update: Partial<ViewUserState>): Promise<ViewUserState>;
49
29
  private ensureEditable;
50
30
  }
@@ -2,7 +2,26 @@ import { HoistModel, LoadSpec, PlainObject, TaskObserver, Thunkable } from '@xh/
2
2
  import type { ViewManagerProvider } from '@xh/hoist/core';
3
3
  import { ViewInfo } from './ViewInfo';
4
4
  import { View } from './View';
5
- import { ViewCreateSpec, ViewUpdateSpec } from './DataAccess';
5
+ export interface ViewCreateSpec {
6
+ name: string;
7
+ group: string;
8
+ description: string;
9
+ isShared: boolean;
10
+ isPinned: boolean;
11
+ value: PlainObject;
12
+ }
13
+ export interface ViewUpdateSpec {
14
+ name: string;
15
+ group: string;
16
+ description: string;
17
+ isShared?: boolean;
18
+ isDefaultPinned?: boolean;
19
+ }
20
+ export interface ViewUserState {
21
+ currentView?: string;
22
+ userPinned: Record<string, boolean>;
23
+ autoSave: boolean;
24
+ }
6
25
  export interface ViewManagerConfig {
7
26
  /**
8
27
  * True (default) to allow user to opt in to automatically saving changes to their current view.
@@ -170,7 +189,6 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
170
189
  resetAsync(): Promise<void>;
171
190
  getValue(): Partial<T>;
172
191
  setValue(value: Partial<T>): void;
173
- togglePinned(view: ViewInfo): void;
174
192
  userPin(view: ViewInfo): void;
175
193
  userUnpin(view: ViewInfo): void;
176
194
  isUserPinned(view: ViewInfo): boolean | null;
@@ -5,34 +5,12 @@
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
7
 
8
- import {PlainObject, XH} from '@xh/hoist/core';
8
+ import {XH} from '@xh/hoist/core';
9
9
  import {pluralize, throwIf} from '@xh/hoist/utils/js';
10
10
  import {map} from 'lodash';
11
11
  import {ViewInfo} from './ViewInfo';
12
12
  import {View} from './View';
13
- import {ViewManagerModel} from './ViewManagerModel';
14
-
15
- export interface ViewCreateSpec {
16
- name: string;
17
- group: string;
18
- description: string;
19
- isShared: boolean;
20
- value?: PlainObject;
21
- }
22
-
23
- export interface ViewUpdateSpec {
24
- name: string;
25
- group: string;
26
- description: string;
27
- isShared?: boolean;
28
- isDefaultPinned?: boolean;
29
- }
30
-
31
- export interface ViewUserState {
32
- currentView?: string;
33
- userPinned: Record<string, boolean>;
34
- autoSave: boolean;
35
- }
13
+ import {ViewManagerModel, ViewUserState, ViewUpdateSpec, ViewCreateSpec} from './ViewManagerModel';
36
14
 
37
15
  /**
38
16
  * Supporting class for accessing and updating ViewManager and View data.
@@ -100,7 +78,7 @@ export class DataAccess<T> {
100
78
  try {
101
79
  this.ensureEditable(view);
102
80
  const raw = await XH.postJson({
103
- url: 'xhView/updateViewInfo',
81
+ url: 'xhView/updateInfo',
104
82
  params: {token: view.token},
105
83
  body: updates
106
84
  });
@@ -157,9 +135,9 @@ export class DataAccess<T> {
157
135
  //--------------------------
158
136
  // State related changes
159
137
  //--------------------------
160
- async updateStateAsync(update: Partial<ViewUserState>) {
138
+ async updateStateAsync(update: Partial<ViewUserState>): Promise<ViewUserState> {
161
139
  const {type, instance} = this.model;
162
- await XH.postJson({
140
+ return XH.postJson({
163
141
  url: 'xhView/updateState',
164
142
  params: {type, viewInstance: instance},
165
143
  body: update
@@ -25,7 +25,30 @@ import {find, isEqual, isNil, isNull, isUndefined, lowerCase} from 'lodash';
25
25
  import {ReactNode} from 'react';
26
26
  import {ViewInfo} from './ViewInfo';
27
27
  import {View} from './View';
28
- import {DataAccess, ViewCreateSpec, ViewUpdateSpec, ViewUserState} from './DataAccess';
28
+ import {DataAccess} from './DataAccess';
29
+
30
+ export interface ViewCreateSpec {
31
+ name: string;
32
+ group: string;
33
+ description: string;
34
+ isShared: boolean;
35
+ isPinned: boolean;
36
+ value: PlainObject;
37
+ }
38
+
39
+ export interface ViewUpdateSpec {
40
+ name: string;
41
+ group: string;
42
+ description: string;
43
+ isShared?: boolean;
44
+ isDefaultPinned?: boolean;
45
+ }
46
+
47
+ export interface ViewUserState {
48
+ currentView?: string;
49
+ userPinned: Record<string, boolean>;
50
+ autoSave: boolean;
51
+ }
29
52
 
30
53
  export interface ViewManagerConfig {
31
54
  /**
@@ -338,9 +361,8 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
338
361
  }
339
362
 
340
363
  async saveAsAsync(spec: ViewCreateSpec): Promise<void> {
341
- const view = await this.dataAccess.createViewAsync({...spec, value: this.getValue()});
364
+ const view = await this.dataAccess.createViewAsync(spec);
342
365
  this.noteSuccess(`Created ${view.typedName}`);
343
- this.userPin(view.info);
344
366
  this.setAsView(view);
345
367
  }
346
368
 
@@ -404,10 +426,6 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
404
426
  //------------------
405
427
  // Pinning
406
428
  //------------------
407
- togglePinned(view: ViewInfo) {
408
- view.isPinned ? this.userUnpin(view) : this.userPin(view);
409
- }
410
-
411
429
  @action
412
430
  userPin(view: ViewInfo) {
413
431
  this.userPinned = {...this.userPinned, [view.token]: true};
@@ -78,7 +78,6 @@ function getOtherMenuItems(model: ViewManagerLocalModel): ReactNode[] {
78
78
  autoSaveUnavailableReason,
79
79
  autoSave,
80
80
  isViewSavable,
81
- views,
82
81
  isValueDirty,
83
82
  typeDisplayName
84
83
  } = parent;
@@ -119,7 +118,6 @@ function getOtherMenuItems(model: ViewManagerLocalModel): ReactNode[] {
119
118
  menuDivider(),
120
119
  menuItem({
121
120
  icon: Icon.gear(),
122
- disabled: isEmpty(views),
123
121
  text: `Manage ${pluralName}...`,
124
122
  onClick: () => model.manageDialogModel.open()
125
123
  })
@@ -86,7 +86,9 @@ export class SaveAsDialogModel extends HoistModel {
86
86
  name: name.trim(),
87
87
  group: group?.trim(),
88
88
  description: description?.trim(),
89
- isShared
89
+ isPinned: true,
90
+ isShared,
91
+ value: parent.getValue()
90
92
  });
91
93
  }
92
94
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "71.0.0-SNAPSHOT.1735586653168",
3
+ "version": "71.0.0-SNAPSHOT.1735588181793",
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",