@xh/hoist 70.0.0-SNAPSHOT.1731083521069 → 70.0.0-SNAPSHOT.1731374612473

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/build/types/cmp/filter/FilterChooserModel.d.ts +17 -12
  3. package/build/types/cmp/grid/GridModel.d.ts +5 -9
  4. package/build/types/cmp/grid/Types.d.ts +7 -19
  5. package/build/types/cmp/grid/columns/Column.d.ts +0 -1
  6. package/build/types/cmp/grid/impl/InitPersist.d.ts +7 -0
  7. package/build/types/cmp/grouping/GroupingChooserModel.d.ts +6 -8
  8. package/build/types/cmp/tab/TabContainerModel.d.ts +10 -4
  9. package/build/types/cmp/zoneGrid/Types.d.ts +6 -6
  10. package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +0 -2
  11. package/build/types/cmp/zoneGrid/impl/InitPersist.d.ts +7 -0
  12. package/build/types/core/HoistBase.d.ts +1 -1
  13. package/build/types/core/persist/CustomProvider.d.ts +5 -6
  14. package/build/types/core/persist/DashViewProvider.d.ts +6 -6
  15. package/build/types/core/persist/LocalStorageProvider.d.ts +4 -5
  16. package/build/types/core/persist/PersistOptions.d.ts +5 -4
  17. package/build/types/core/persist/Persistable.d.ts +14 -0
  18. package/build/types/core/persist/PersistenceProvider.d.ts +47 -34
  19. package/build/types/core/persist/PrefProvider.d.ts +5 -5
  20. package/build/types/core/persist/index.d.ts +2 -0
  21. package/build/types/core/persist/viewmanager/Types.d.ts +46 -0
  22. package/build/types/core/persist/viewmanager/ViewManagerModel.d.ts +149 -0
  23. package/build/types/core/persist/viewmanager/ViewManagerProvider.d.ts +10 -0
  24. package/build/types/core/persist/viewmanager/impl/ManageDialogModel.d.ts +30 -0
  25. package/build/types/core/persist/viewmanager/impl/SaveDialogModel.d.ts +23 -0
  26. package/build/types/core/persist/viewmanager/index.d.ts +2 -0
  27. package/build/types/desktop/cmp/button/ColAutosizeButton.d.ts +1 -1
  28. package/build/types/desktop/cmp/dash/DashConfig.d.ts +3 -1
  29. package/build/types/desktop/cmp/dash/DashModel.d.ts +1 -2
  30. package/build/types/desktop/cmp/dash/DashViewSpec.d.ts +1 -1
  31. package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +10 -2
  32. package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +26 -10
  33. package/build/types/desktop/cmp/dash/container/impl/DashContainerUtils.d.ts +4 -2
  34. package/build/types/desktop/cmp/panel/PanelModel.d.ts +8 -4
  35. package/build/types/desktop/cmp/viewmanager/ViewManager.d.ts +22 -0
  36. package/build/types/desktop/cmp/viewmanager/cmp/ManageDialog.d.ts +6 -0
  37. package/build/types/desktop/cmp/viewmanager/cmp/SaveDialog.d.ts +2 -0
  38. package/build/types/desktop/cmp/viewmanager/index.d.ts +3 -0
  39. package/build/types/kit/blueprint/Wrappers.d.ts +1 -1
  40. package/build/types/mobile/cmp/button/ColAutosizeButton.d.ts +1 -1
  41. package/build/types/svc/GridAutosizeService.d.ts +2 -5
  42. package/build/types/svc/JsonBlobService.d.ts +45 -24
  43. package/cmp/filter/FilterChooserModel.ts +142 -125
  44. package/cmp/grid/Grid.ts +2 -10
  45. package/cmp/grid/GridModel.ts +18 -31
  46. package/cmp/grid/Types.ts +7 -21
  47. package/cmp/grid/columns/Column.ts +0 -1
  48. package/cmp/grid/impl/InitPersist.ts +71 -0
  49. package/cmp/grouping/GroupingChooserModel.ts +48 -57
  50. package/cmp/tab/TabContainerModel.ts +22 -36
  51. package/cmp/zoneGrid/Types.ts +6 -6
  52. package/cmp/zoneGrid/ZoneGridModel.ts +2 -7
  53. package/cmp/zoneGrid/impl/InitPersist.ts +70 -0
  54. package/core/HoistBase.ts +14 -22
  55. package/core/HoistBaseDecorators.ts +26 -28
  56. package/core/persist/CustomProvider.ts +7 -10
  57. package/core/persist/DashViewProvider.ts +8 -10
  58. package/core/persist/LocalStorageProvider.ts +9 -12
  59. package/core/persist/PersistOptions.ts +6 -4
  60. package/core/persist/Persistable.ts +23 -0
  61. package/core/persist/PersistenceProvider.ts +159 -79
  62. package/core/persist/PrefProvider.ts +9 -12
  63. package/core/persist/index.ts +2 -0
  64. package/core/persist/viewmanager/Types.ts +51 -0
  65. package/core/persist/viewmanager/ViewManagerModel.ts +515 -0
  66. package/core/persist/viewmanager/ViewManagerProvider.ts +51 -0
  67. package/core/persist/viewmanager/impl/ManageDialogModel.ts +274 -0
  68. package/core/persist/viewmanager/impl/SaveDialogModel.ts +112 -0
  69. package/core/persist/viewmanager/index.ts +2 -0
  70. package/desktop/cmp/button/ColAutosizeButton.ts +1 -1
  71. package/desktop/cmp/dash/DashConfig.ts +3 -1
  72. package/desktop/cmp/dash/DashModel.ts +1 -2
  73. package/desktop/cmp/dash/DashViewSpec.ts +1 -1
  74. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +31 -30
  75. package/desktop/cmp/dash/container/DashContainerModel.ts +68 -43
  76. package/desktop/cmp/dash/container/impl/DashContainerUtils.ts +13 -4
  77. package/desktop/cmp/leftrightchooser/LeftRightChooserFilter.ts +1 -1
  78. package/desktop/cmp/panel/PanelModel.ts +33 -53
  79. package/desktop/cmp/store/impl/StoreFilterField.ts +1 -1
  80. package/desktop/cmp/viewmanager/ViewManager.scss +58 -0
  81. package/desktop/cmp/viewmanager/ViewManager.ts +274 -0
  82. package/desktop/cmp/viewmanager/cmp/ManageDialog.ts +197 -0
  83. package/desktop/cmp/viewmanager/cmp/SaveDialog.ts +89 -0
  84. package/desktop/cmp/viewmanager/index.ts +3 -0
  85. package/mobile/cmp/button/ColAutosizeButton.ts +1 -1
  86. package/package.json +1 -1
  87. package/svc/GridAutosizeService.ts +73 -36
  88. package/svc/JsonBlobService.ts +64 -31
  89. package/tsconfig.tsbuildinfo +1 -1
  90. package/build/types/cmp/grid/impl/GridPersistenceModel.d.ts +0 -41
  91. package/build/types/cmp/zoneGrid/impl/ZoneGridPersistenceModel.d.ts +0 -39
  92. package/cmp/grid/impl/GridPersistenceModel.ts +0 -174
  93. package/cmp/zoneGrid/impl/ZoneGridPersistenceModel.ts +0 -149
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changelog
2
2
 
3
+ ## v70.0.0-SNAPSHOT
4
+
5
+ ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - changes to advanced persistence APIs)
6
+
7
+ * Upgraded the `PersistenceProvider` API as noted in `New Features`. Could require updates in apps
8
+ with advanced direct usages of this API (uncommon).
9
+ * Updated `GridModel` persistence to omit the widths of autosized columns from its persisted state.
10
+ This helps to keep persisted state more stable, avoiding spurious diffs due to autosize updates.
11
+ Note this can result in more visible column resizing for large grids without in-code default
12
+ widths. Please let XH know if this is a noticeable annoyance for your app.
13
+ * Removed the following persistence-related model classes, properties, and methods:
14
+ * `GridPersistenceModel` and `ZoneGridPersistenceModel`
15
+ * `GridModel|ZoneGridModel.persistenceModel`
16
+ * `GridModel.autosizeState`
17
+ * `Column.manuallySized`
18
+ * `GroupingChooserModel|FilterChooserModel.persistValue`
19
+ * `DashModel|GroupingChooserModel|FilterChooserModel|PanelModel|TabContainerModel.provider`
20
+ * `PersistenceProvider.clearRaw()`
21
+ * Renamed `ZoneGridModelPersistOptions.persistMappings`, adding the trailing `s` for consistency.
22
+ * Updated `JsonBlobService.listAsync` to inline `loadSpec` with all other args in a single object.
23
+
24
+ ### 🎁 New Features
25
+
26
+ * Introduced a new `ViewManager` component and backing model to support user-driven management of
27
+ persisted component state - e.g. saved grid views.
28
+ * Bundled with a desktop-only menu button based component, but designed to be extensible.
29
+ * Bindable to any persistable component with `persistWith: {viewManagerModel: myViewManager}`.
30
+ * Detects changes to any bound components and syncs them back to saved views, with support for
31
+ an autosave option or user-driven saving with a clear "dirty" indicator.
32
+ * Saves persisted state back to the server using Hoist Core `JSONBlob`s for storage.
33
+ * Includes a simple sharing model - if enabled for all or some users, allows those users to
34
+ publish saved views to everyone else in the application.
35
+ * Users can rename views, nest them into folders, and mark them as favorites for quick access.
36
+ * Generally enhanced Hoist's persistence-related APIs:
37
+ * Added new `Persistable` interface to formalize the contract for objects that can be persisted.
38
+ * `PersistenceProvider` now targets a `Persistable` and is responsible for setting persisted
39
+ state on its bound `Persistable` when the provider is constructed and persisting state from
40
+ its bound `Persistable` when changes are detected.
41
+ * In its constructor, `PersistenceProvider` also stores the initial state of its bound
42
+ `Persistable` and clears its persisted state when structurally equal to the initial state.
43
+ * Updated persistable components to support specifying distinct `PersistOptions` for individual
44
+ bits of persisted state. E.g. you can now configure a `GroupingChooserModel` used within a
45
+ dashboard widget to persist its value to that particular widget's `DashViewModel` while saving the
46
+ user's favorites to a global preference.
47
+
48
+ ### ⚙️ Typescript API Adjustments
49
+
50
+ * Tightened `FilterChooserFilterLike` union type to remove the generic `Filter` type, as filter
51
+ chooser supports only `FieldFilter` and `CompoundFilter`.
52
+ * Improved `HoistBase.markPersist()` signature to ensure the provided property name is a known key
53
+ of the model.
54
+ * Expanded the `JsonBlob` interface to include additional properties present on all blobs.
55
+ * Corrected `DashViewSpec.title` to be optional - it can be defaulted from the `id`.
56
+
3
57
  ## 69.1.0 - 2024-11-07
4
58
 
5
59
  ### 🐞 Bug Fixes
@@ -1,4 +1,4 @@
1
- import { HoistModel, PersistenceProvider, PersistOptions, PlainObject, TaskObserver } from '@xh/hoist/core';
1
+ import { HoistModel, PersistOptions, TaskObserver, Thunkable } from '@xh/hoist/core';
2
2
  import { CompoundFilter, FieldFilter, Filter, Store, View } from '@xh/hoist/data';
3
3
  import { CompoundFilterSpec, FieldFilterSpec, FilterLike } from '@xh/hoist/data/filter/Types';
4
4
  import { ReactNode } from 'react';
@@ -30,11 +30,11 @@ export interface FilterChooserConfig {
30
30
  * to produce the same. Note that FilterChooser currently can only edit and create a flat collection
31
31
  * of FieldFilters, to be 'AND'ed together.
32
32
  */
33
- initialValue?: FilterChooserFilterLike | (() => FilterChooserFilterLike);
33
+ initialValue?: Thunkable<FilterChooserFilterLike>;
34
34
  /**
35
35
  * Initial favorites as an array of filter configurations, or a function to produce such an array.
36
36
  */
37
- initialFavorites?: FilterChooserFilterLike[] | (() => FilterChooserFilterLike[]);
37
+ initialFavorites?: Thunkable<FilterChooserFilterLike[]>;
38
38
  /**
39
39
  * true to offer all field suggestions when the control is focused with an empty query,
40
40
  * to aid discoverability.
@@ -70,8 +70,6 @@ export declare class FilterChooserModel extends HoistModel {
70
70
  maxTags: number;
71
71
  maxResults: number;
72
72
  introHelpText: ReactNode;
73
- provider: PersistenceProvider;
74
- persistValue: boolean;
75
73
  persistFavorites: boolean;
76
74
  /** Tracks execution of filtering operation on bound object.*/
77
75
  filterTask: TaskObserver;
@@ -106,25 +104,32 @@ export declare class FilterChooserModel extends HoistModel {
106
104
  }[];
107
105
  openFavoritesMenu(): void;
108
106
  closeFavoritesMenu(): void;
109
- setFavorites(favorites: Filter[]): void;
107
+ setFavorites(favorites: FilterChooserFilterLike[]): void;
110
108
  addFavorite(filter: FilterChooserFilter): void;
111
109
  removeFavorite(filter: FilterChooserFilter): void;
112
110
  findFavorite(filter: FilterChooserFilter): Filter;
113
111
  isFavorite(filter: FilterChooserFilter): boolean;
114
- get persistState(): PlainObject;
115
112
  parseFieldSpecs(specs: Array<FilterChooserFieldSpecConfig | string>, fieldSpecDefaults: Partial<FilterChooserFieldSpecConfig>): Array<FilterChooserFieldSpec>;
116
113
  getFieldSpec(fieldName: string): FilterChooserFieldSpec;
117
114
  validateFilter(f: Filter): f is FilterChooserFilter;
118
115
  getDefaultIntroHelpText(): string;
116
+ private initPersist;
117
+ private setValueInternal;
118
+ /**
119
+ * Update the select value and bind the filter to the bound model. Runs asynchronously after
120
+ * selectOptions are set to ensure the component is ready to render the tags correctly.
121
+ */
122
+ private updateSelectValueAndBind;
119
123
  }
120
124
  interface FilterChooserPersistOptions extends PersistOptions {
121
- /** True (default) to save value to state. */
122
- persistValue?: boolean;
123
- /** True (default) to include favorites. */
124
- persistFavorites?: boolean;
125
+ /** True (default) to include value or provide value-specific PersistOptions. */
126
+ persistValue?: boolean | PersistOptions;
127
+ /** True (default) to include favorites or provide favorites-specific PersistOptions. */
128
+ persistFavorites?: boolean | PersistOptions;
125
129
  }
126
130
  /** A variant of {@link Filter} that excludes FunctionFilter (unsupported by FilterChooser). */
127
131
  export type FilterChooserFilter = CompoundFilter | FieldFilter;
132
+ export type FilterChooserFilterSpec = CompoundFilterSpec | FieldFilterSpec;
128
133
  /** A variant of {@link FilterLike} that excludes FunctionFilters and FilterTestFn. */
129
- export type FilterChooserFilterLike = Filter | CompoundFilterSpec | FieldFilterSpec | FilterChooserFilterLike[];
134
+ export type FilterChooserFilterLike = FilterChooserFilter | FilterChooserFilterSpec | FilterChooserFilterLike[];
130
135
  export {};
@@ -9,8 +9,7 @@ import { ReactNode } from 'react';
9
9
  import { GridAutosizeOptions } from './GridAutosizeOptions';
10
10
  import { GridContextMenuSpec } from './GridContextMenu';
11
11
  import { GridSorter, GridSorterLike } from './GridSorter';
12
- import { GridPersistenceModel } from './impl/GridPersistenceModel';
13
- import { AutosizeState, ColChooserConfig, ColumnState, GridModelPersistOptions, GroupRowRenderer, RowClassFn, RowClassRuleFn } from './Types';
12
+ import { ColChooserConfig, ColumnState, GridModelPersistOptions, GroupRowRenderer, RowClassFn, RowClassRuleFn } from './Types';
14
13
  export interface GridConfig {
15
14
  /** Columns for this grid. */
16
15
  columns?: Array<ColumnSpec | ColumnGroupSpec>;
@@ -245,9 +244,9 @@ export declare class GridModel extends HoistModel {
245
244
  columns: Array<ColumnGroup | Column>;
246
245
  columnState: ColumnState[];
247
246
  expandState: any;
248
- autosizeState: AutosizeState;
249
247
  sortBy: GridSorter[];
250
248
  groupBy: string[];
249
+ get persistableColumnState(): ColumnState[];
251
250
  showSummary: boolean | VSide;
252
251
  emptyText: ReactNode;
253
252
  treeStyle: TreeStyle;
@@ -265,7 +264,6 @@ export declare class GridModel extends HoistModel {
265
264
  isInEditingMode: boolean;
266
265
  static defaultContextMenu: string[];
267
266
  private _defaultState;
268
- persistenceModel: GridPersistenceModel;
269
267
  /**
270
268
  * Is autosizing enabled on this grid?
271
269
  * To disable autosizing, set autosizeOptions.mode to GridAutosizeMode.DISABLED.
@@ -436,9 +434,7 @@ export declare class GridModel extends HoistModel {
436
434
  setExpandState(expandState: any): void;
437
435
  noteAgExpandStateChange(): void;
438
436
  noteAgSelectionStateChanged(): void;
439
- setAutosizeState(autosizeState: any): void;
440
437
  noteColumnManuallySized(colId: any, width: any): void;
441
- noteColumnsAutosized(colIds: any): void;
442
438
  /**
443
439
  * This method will update the current column definition if it has changed.
444
440
  * Throws an exception if any of the columns provided in colStateChanges are not
@@ -499,12 +495,12 @@ export declare class GridModel extends HoistModel {
499
495
  * columns are also ignored unless {@link GridAutosizeOptions.includeHiddenColumns} has been
500
496
  * set to true.
501
497
  *
502
- * @param options - optional overrides of this model's configured {@link autosizeOptions}.
498
+ * @param overrideOpts - optional overrides of this model's {@link GridAutosizeOptions}.
503
499
  */
504
- autosizeAsync(options?: GridAutosizeOptions): Promise<void>;
500
+ autosizeAsync(overrideOpts?: Omit<GridAutosizeOptions, 'mode'>): Promise<void>;
505
501
  /**
506
502
  * Begin an inline editing session.
507
- * @param recOrId - StoreRecord/ID to edit. If unspecified, the first selected StoreRecord
503
+ * @param record - StoreRecord/ID to edit. If unspecified, the first selected StoreRecord
508
504
  * will be used, if any, or the first overall StoreRecord in the grid.
509
505
  * @param colId - ID of column on which to start editing. If unspecified, the first
510
506
  * editable column will be used.
@@ -1,6 +1,6 @@
1
1
  import { IRowNode } from '@xh/hoist/kit/ag-grid';
2
2
  import { GridFilterFieldSpecConfig } from '@xh/hoist/cmp/grid/filter/GridFilterFieldSpec';
3
- import { HSide, PersistOptions, SizingMode, Some } from '@xh/hoist/core';
3
+ import { HSide, PersistOptions, Some } from '@xh/hoist/core';
4
4
  import { Store, StoreRecord, View } from '@xh/hoist/data';
5
5
  import { ReactElement, ReactNode } from 'react';
6
6
  import { Column } from './columns/Column';
@@ -16,10 +16,6 @@ export interface ColumnState {
16
16
  /** Side if pinned, null if not. */
17
17
  pinned?: HSide;
18
18
  }
19
- export interface AutosizeState {
20
- /** Sizing mode used last time the columns were autosized. */
21
- sizingMode?: SizingMode;
22
- }
23
19
  /**
24
20
  * Comparator for custom grid group sorting, provided to GridModel.
25
21
  * @param groupAVal - first group value to be compared.
@@ -51,20 +47,12 @@ export type RowClassFn = (record: StoreRecord) => Some<string>;
51
47
  */
52
48
  export type RowClassRuleFn = (agParams: RowClassParams) => boolean;
53
49
  export interface GridModelPersistOptions extends PersistOptions {
54
- /** True to include column information (default true) */
55
- persistColumns?: boolean;
56
- /** True to include grouping information (default true) */
57
- persistGrouping?: boolean;
58
- /** True to include sorting information (default true) */
59
- persistSort?: boolean;
60
- /**
61
- * Key to be used to identify location of legacy grid state from LocalStorage.
62
- * This key will identify the pre-v35 location for grid state, and will be used
63
- * as an initial source of grid state after an upgrade to v35.0.0 or greater.
64
- * Defaults to the new value of 'key'. If no legacy state is available at this
65
- * location, the key is ignored.
66
- */
67
- legacyStateKey?: string;
50
+ /** True (default) to include column state or provide column-specific PersistOptions. */
51
+ persistColumns?: boolean | PersistOptions;
52
+ /** True (default) to include grouping state or provide grouping-specific PersistOptions. */
53
+ persistGrouping?: boolean | PersistOptions;
54
+ /** True (default) to include sort state or provide sort-specific PersistOptions. */
55
+ persistSort?: boolean | PersistOptions;
68
56
  }
69
57
  export interface GridFilterModelConfig {
70
58
  /**
@@ -337,7 +337,6 @@ export declare class Column {
337
337
  actions?: Array<RecordActionSpec | RecordAction>;
338
338
  actionsShowOnHoverOnly?: boolean;
339
339
  fieldSpec: FieldSpec;
340
- manuallySized: boolean;
341
340
  omit: Thunkable<boolean>;
342
341
  gridModel: GridModel;
343
342
  agOptions: ColDef;
@@ -0,0 +1,7 @@
1
+ import { GridModel } from '../GridModel';
2
+ import { GridModelPersistOptions } from '../Types';
3
+ /**
4
+ * Initialize persistence for a {@link GridModel} by applying its `persistWith` config.
5
+ * @internal
6
+ */
7
+ export declare function initPersist(gridModel: GridModel, { persistColumns, persistGrouping, persistSort, path, ...rootPersistWith }: GridModelPersistOptions): void;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { HoistModel, PersistenceProvider, PersistOptions, PlainObject } from '@xh/hoist/core';
2
+ import { HoistModel, PersistOptions } from '@xh/hoist/core';
3
3
  export interface GroupingChooserConfig {
4
4
  /**
5
5
  * Dimensions available for selection. When using GroupingChooser to create Cube queries,
@@ -34,10 +34,10 @@ export interface DimensionSpec {
34
34
  displayName?: string;
35
35
  }
36
36
  export interface GroupingChooserPersistOptions extends PersistOptions {
37
- /** True (default) to save value to state. */
38
- persistValue?: boolean;
39
- /** True (default) to include favorites. */
40
- persistFavorites?: boolean;
37
+ /** True (default) to include value or provide value-specific PersistOptions. */
38
+ persistValue?: boolean | PersistOptions;
39
+ /** True (default) to include favorites or provide favorites-specific PersistOptions. */
40
+ persistFavorites?: boolean | PersistOptions;
41
41
  }
42
42
  export declare class GroupingChooserModel extends HoistModel {
43
43
  value: string[];
@@ -45,8 +45,6 @@ export declare class GroupingChooserModel extends HoistModel {
45
45
  allowEmpty: boolean;
46
46
  maxDepth: number;
47
47
  commitOnChange: boolean;
48
- provider: PersistenceProvider;
49
- persistValue: boolean;
50
48
  persistFavorites: boolean;
51
49
  pendingValue: string[];
52
50
  editorIsOpen: boolean;
@@ -81,7 +79,7 @@ export declare class GroupingChooserModel extends HoistModel {
81
79
  addFavorite(value: string[]): void;
82
80
  removeFavorite(value: string[]): void;
83
81
  isFavorite(value: string[]): boolean;
84
- get persistState(): PlainObject;
82
+ private initPersist;
85
83
  private normalizeDimensions;
86
84
  private createDimension;
87
85
  private removeUnknownDimsFromValue;
@@ -1,4 +1,4 @@
1
- import { HoistModel, PersistenceProvider, PersistOptions, RefreshContextModel, RefreshMode, RenderMode } from '@xh/hoist/core';
1
+ import { HoistModel, Persistable, PersistableState, PersistOptions, RefreshContextModel, RefreshMode, RenderMode } from '@xh/hoist/core';
2
2
  import { ReactNode } from 'react';
3
3
  import { TabConfig, TabModel } from './TabModel';
4
4
  import { TabSwitcherProps } from './TabSwitcherProps';
@@ -54,7 +54,9 @@ export interface TabContainerConfig {
54
54
  *
55
55
  * Note: Routing is currently enabled for desktop applications only.
56
56
  */
57
- export declare class TabContainerModel extends HoistModel {
57
+ export declare class TabContainerModel extends HoistModel implements Persistable<{
58
+ activeTabId: string;
59
+ }> {
58
60
  config: TabContainerConfig;
59
61
  tabs: TabModel[];
60
62
  activeTabId: string;
@@ -65,7 +67,6 @@ export declare class TabContainerModel extends HoistModel {
65
67
  renderMode: RenderMode;
66
68
  refreshMode: RefreshMode;
67
69
  emptyText: ReactNode;
68
- provider: PersistenceProvider;
69
70
  refreshContextModel: RefreshContextModel;
70
71
  private lastActiveTabId;
71
72
  constructor({ tabs, defaultTabId, route, switcher, track, renderMode, refreshMode, persistWith, emptyText, xhImpl }: TabContainerConfig);
@@ -103,11 +104,16 @@ export declare class TabContainerModel extends HoistModel {
103
104
  * @param cycle - true to loop back to first tab if necessary.
104
105
  */
105
106
  activateNextTab(cycle?: boolean): void;
107
+ getPersistableState(): PersistableState<{
108
+ activeTabId: string;
109
+ }>;
110
+ setPersistableState(state: PersistableState<{
111
+ activeTabId: string;
112
+ }>): void;
106
113
  private setActiveTabIdInternal;
107
114
  private syncWithRouter;
108
115
  private forwardRouterToTab;
109
116
  private calculateActiveTabId;
110
- private setupStateProvider;
111
117
  }
112
118
  export interface AddTabOptions {
113
119
  /** Index in tab collection where tab is to be added. */
@@ -26,10 +26,10 @@ export interface ZoneField {
26
26
  sortingOrder: ColumnSortSpec[];
27
27
  }
28
28
  export interface ZoneGridModelPersistOptions extends PersistOptions {
29
- /** True to include mapping information (default true) */
30
- persistMapping?: boolean;
31
- /** True to include grouping information (default true) */
32
- persistGrouping?: boolean;
33
- /** True to include sorting information (default true) */
34
- persistSort?: boolean;
29
+ /** True (default) to include mapping state or provide mapping-specific PersistOptions. */
30
+ persistMappings?: boolean | PersistOptions;
31
+ /** True (default) to include grouping state or provide grouping-specific PersistOptions. */
32
+ persistGrouping?: boolean | PersistOptions;
33
+ /** True (default) to include sort state or provide sort-specific PersistOptions. */
34
+ persistSort?: boolean | PersistOptions;
35
35
  }
@@ -3,7 +3,6 @@ import { ColumnRenderer, ColumnSpec, GridContextMenuSpec, GridGroupSortFn, GridM
3
3
  import { Awaitable, HoistModel, LoadSpec, PlainObject, Some, VSide } from '@xh/hoist/core';
4
4
  import { RecordAction, Store, StoreConfig, StoreRecordOrId, StoreSelectionConfig, StoreSelectionModel, StoreTransaction } from '@xh/hoist/data';
5
5
  import { ReactNode } from 'react';
6
- import { ZoneGridPersistenceModel } from './impl/ZoneGridPersistenceModel';
7
6
  import { ZoneMapperConfig, ZoneMapperModel } from './impl/ZoneMapperModel';
8
7
  import { Zone, ZoneGridModelPersistOptions, ZoneLimit, ZoneMapping } from './Types';
9
8
  export interface ZoneGridConfig {
@@ -203,7 +202,6 @@ export declare class ZoneGridModel extends HoistModel {
203
202
  restoreDefaultsFn: () => Awaitable<void>;
204
203
  restoreDefaultsWarning: ReactNode;
205
204
  private _defaultState;
206
- persistenceModel: ZoneGridPersistenceModel;
207
205
  constructor(config: ZoneGridConfig);
208
206
  /**
209
207
  * Restore the mapping, sorting, and grouping configs as specified by the application at
@@ -0,0 +1,7 @@
1
+ import { ZoneGridModel } from '../ZoneGridModel';
2
+ import { ZoneGridModelPersistOptions } from '../Types';
3
+ /**
4
+ * Initialize persistence for a {@link ZoneGridModel} by applying its `persistWith` config.
5
+ * @internal
6
+ */
7
+ export declare function initPersist(zoneGridModel: ZoneGridModel, { persistMappings, persistGrouping, persistSort, path, ...rootPersistWith }: ZoneGridModelPersistOptions): void;
@@ -134,7 +134,7 @@ export declare abstract class HoistBase {
134
134
  * @param options - options governing the persistence of this object. These will be applied
135
135
  * on top of any default persistWith options defined on the instance itself.
136
136
  */
137
- markPersist(property: string, options?: PersistOptions): void;
137
+ markPersist(property: keyof this & string, options?: PersistOptions): void;
138
138
  /** @returns true if this instance has been destroyed. */
139
139
  get isDestroyed(): boolean;
140
140
  /**
@@ -1,4 +1,4 @@
1
- import { PersistenceProvider, PersistOptions } from './';
1
+ import { PersistenceProvider, PersistenceProviderConfig } from './';
2
2
  /**
3
3
  * A minimal Persistence provider for use by apps that wish to implement the actual persistence
4
4
  * of the backing data via custom handlers.
@@ -6,11 +6,10 @@ import { PersistenceProvider, PersistOptions } from './';
6
6
  * This provider allows applications to use the Persistence API to populate and read state from
7
7
  * components without actually writing to any pre-defined storage.
8
8
  */
9
- export declare class CustomProvider extends PersistenceProvider {
10
- getData: any;
11
- setData: any;
12
- constructor({ getData, setData, ...rest }: PersistOptions);
9
+ export declare class CustomProvider<S> extends PersistenceProvider<S> {
10
+ readonly getData: any;
11
+ readonly setData: any;
12
+ constructor(cfg: PersistenceProviderConfig<S>);
13
13
  readRaw(): any;
14
14
  writeRaw(data: any): void;
15
- clearRaw(): void;
16
15
  }
@@ -1,11 +1,11 @@
1
- import { PersistenceProvider, PersistOptions } from './';
1
+ import type { DashViewModel } from '@xh/hoist/desktop/cmp/dash';
2
+ import { PersistenceProvider, PersistenceProviderConfig } from './';
2
3
  /**
3
4
  * PersistenceProvider that stores state within a DashViewModel.
4
5
  */
5
- export declare class DashViewProvider extends PersistenceProvider {
6
- dashViewModel: any;
7
- constructor({ dashViewModel, ...rest }: PersistOptions);
8
- readRaw(): any;
6
+ export declare class DashViewProvider<S> extends PersistenceProvider<S> {
7
+ readonly dashViewModel: DashViewModel;
8
+ constructor(cfg: PersistenceProviderConfig<S>);
9
+ readRaw(): import("..").PlainObject;
9
10
  writeRaw(data: any): void;
10
- clearRaw(): any;
11
11
  }
@@ -1,11 +1,10 @@
1
- import { PersistenceProvider, PersistOptions } from './';
1
+ import { PersistenceProvider, PersistenceProviderConfig } from './';
2
2
  /**
3
3
  * PersistenceProvider that stores state within the Browser's LocalStorage.
4
4
  */
5
- export declare class LocalStorageProvider extends PersistenceProvider {
6
- key: string;
7
- constructor({ localStorageKey: key, ...rest }: PersistOptions);
5
+ export declare class LocalStorageProvider<S> extends PersistenceProvider<S> {
6
+ readonly key: string;
7
+ constructor(cfg: PersistenceProviderConfig<S>);
8
8
  readRaw(): any;
9
9
  writeRaw(data: any): void;
10
- clearRaw(): void;
11
10
  }
@@ -1,7 +1,6 @@
1
1
  import { DebounceSpec } from '../';
2
- /**
3
- * Options governing persistence.
4
- */
2
+ import type { DashViewModel } from '@xh/hoist/desktop/cmp/dash';
3
+ import type { ViewManagerModel } from '@xh/hoist/core/persist/viewmanager';
5
4
  export interface PersistOptions {
6
5
  /** Dot delimited path to store state. */
7
6
  path?: string;
@@ -17,7 +16,9 @@ export interface PersistOptions {
17
16
  /** Browser local storage key used to store state. */
18
17
  localStorageKey?: string;
19
18
  /** DashViewModel used to read / write view state. */
20
- dashViewModel?: object;
19
+ dashViewModel?: DashViewModel;
20
+ /** ViewManagerModel used to read / write view state. */
21
+ viewManagerModel?: ViewManagerModel;
21
22
  /**
22
23
  * Function returning blob of data to be used for reading state.
23
24
  * Ignored if `prefKey`, `localStorageKey` or `dashViewModel` are provided.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Interface for objects that can be bound to a {@link PersistenceProvider}.
3
+ * @typeParam S - must be serializable to JSON and PersistableState<S> must be observable
4
+ */
5
+ export interface Persistable<S> {
6
+ getPersistableState(): PersistableState<S>;
7
+ setPersistableState(state: PersistableState<S>): void;
8
+ }
9
+ /** Wrapper for a serializable Persistable state object. */
10
+ export declare class PersistableState<S> {
11
+ value: S;
12
+ constructor(value: S);
13
+ equals(other: PersistableState<S>): boolean;
14
+ }
@@ -1,5 +1,14 @@
1
- import { DebounceSpec } from '../';
1
+ import { DebounceSpec, HoistBase, Persistable, PersistableState } from '../';
2
2
  import { PersistOptions } from './';
3
+ export type PersistenceProviderConfig<S> = {
4
+ persistOptions: PersistOptions;
5
+ target: Persistable<S>;
6
+ owner: HoistBase;
7
+ } | {
8
+ persistOptions: PersistOptions;
9
+ target: Persistable<S> & HoistBase;
10
+ owner?: HoistBase;
11
+ };
3
12
  /**
4
13
  * Abstract superclass for adaptor objects used by models and components to (re)store state to and
5
14
  * from a persistent location, typically a Hoist preference or key within browser local storage.
@@ -8,42 +17,46 @@ import { PersistOptions } from './';
8
17
  * Implementations should take care to incorporate any writes immediately into the readable state.
9
18
  *
10
19
  * Hoist-provided implementations include:
11
- * - {@link PrefProvider} - stores state in a predefined Hoist application Preference.
12
- * - {@link LocalStorageProvider} - stores state in browser local storage under a configured key.
13
- * - {@link DashViewProvider} - stores state with other Dashboard-specific state via a `DashViewModel`.
20
+ * - {@link PrefProvider} - persists to a predefined Hoist JSON Preference.
21
+ * - {@link LocalStorageProvider} - persists to browser local storage under a configured key.
22
+ * - {@link DashViewProvider} - persists to a bound `DashViewModel` to save state for components
23
+ * used within a dashboard widget. For this to be useful, the parent {@link DashModel} must
24
+ * itself be persisted via a different provider - it acts as a collector of the widget-level
25
+ * state managed by its DashViewModels and this provider.
26
+ * - {@link ViewManagerProvider} - persists to saved views managed by {@link ViewManagerModel}.
14
27
  * - {@link CustomProvider} - API for app and components to provide their own storage mechanism.
15
28
  */
16
- export declare class PersistenceProvider {
17
- get isPersistenceProvider(): boolean;
18
- path: string;
19
- debounce: DebounceSpec;
29
+ export declare abstract class PersistenceProvider<S> {
30
+ readonly path: string;
31
+ readonly debounce: DebounceSpec;
32
+ readonly owner: HoistBase;
33
+ protected target: Persistable<S>;
34
+ protected defaultState: PersistableState<S>;
35
+ private disposer;
20
36
  /**
21
37
  * Construct an instance of this class.
38
+ *
39
+ * Will fail gently, returning `null` and logging an error if the provider could not be created
40
+ * due to an unparseable config or failure on initial read.
41
+ *
42
+ * Note: Targets should initialize their default persistable state *before* creating a
43
+ * `PersistenceProvider` and defer creating reactions to persistable state until *after*. This
44
+ * allows the provider to capture the default state and then apply any persisted state to the
45
+ * target without thrashing.
22
46
  */
23
- static create({ type, ...rest }: PersistOptions): PersistenceProvider;
24
- /**
25
- * Called by implementations only. See create.
26
- */
27
- protected constructor({ path, debounce }: PersistOptions);
28
- /**
29
- * Read data at a path
30
- */
31
- read(): any;
32
- /**
33
- * Save data at a path
34
- * @param data - data to be written to the path, must be serializable to JSON.
35
- */
36
- write(data: any): void;
37
- /**
38
- * Clear any state saved by this object at a path
39
- */
40
- clear(path?: string): void;
41
- /**
42
- * Clear *all* state held by this object.
43
- */
44
- clearAll(): void;
45
- protected writeInternal(data: object): void;
46
- protected writeRaw(obj: object): void;
47
- protected readRaw(): object;
48
- protected clearRaw(): void;
47
+ static create<S>(cfg: PersistenceProviderConfig<S>): PersistenceProvider<S>;
48
+ /** Read persisted state at this provider's path. */
49
+ read(): PersistableState<S>;
50
+ /** Persist JSON-serializable state to this provider's path. */
51
+ write(state: S): void;
52
+ /** Clear any persisted data at a path. Also clears any parent objects that become empty. */
53
+ clear(): void;
54
+ destroy(): void;
55
+ /** Called by implementations only. Use the {@link create} factory instead. */
56
+ protected constructor(cfg: PersistenceProviderConfig<S>);
57
+ /** Called by factory method to bind this provider to its target. */
58
+ protected bindToTarget(target: Persistable<S>): void;
59
+ protected writeInternal(data: S): void;
60
+ protected writeRaw(obj: Record<typeof this.path, S>): void;
61
+ protected readRaw(): Record<typeof this.path, S>;
49
62
  }
@@ -1,11 +1,11 @@
1
- import { PersistenceProvider, PersistOptions } from './';
1
+ import { PersistenceProviderConfig } from '../';
2
+ import { PersistenceProvider } from './';
2
3
  /**
3
4
  * PersistenceProvider that stores state within the Hoist Preferences system.
4
5
  */
5
- export declare class PrefProvider extends PersistenceProvider {
6
- key: string;
7
- constructor({ prefKey: key, ...rest }: PersistOptions);
6
+ export declare class PrefProvider<S> extends PersistenceProvider<S> {
7
+ readonly key: string;
8
+ constructor(cfg: PersistenceProviderConfig<S>);
8
9
  readRaw(): any;
9
10
  writeRaw(data: any): void;
10
- clearRaw(): void;
11
11
  }
@@ -1,6 +1,8 @@
1
+ export * from './Persistable';
1
2
  export * from './PersistOptions';
2
3
  export * from './PersistenceProvider';
3
4
  export * from './LocalStorageProvider';
4
5
  export * from './DashViewProvider';
5
6
  export * from './PrefProvider';
6
7
  export * from './CustomProvider';
8
+ export * from './viewmanager/ViewManagerProvider';