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

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 (95) hide show
  1. package/CHANGELOG.md +57 -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/promise/Promise.d.ts +6 -5
  42. package/build/types/svc/GridAutosizeService.d.ts +2 -5
  43. package/build/types/svc/JsonBlobService.d.ts +45 -24
  44. package/cmp/filter/FilterChooserModel.ts +142 -125
  45. package/cmp/grid/Grid.ts +2 -10
  46. package/cmp/grid/GridModel.ts +18 -31
  47. package/cmp/grid/Types.ts +7 -21
  48. package/cmp/grid/columns/Column.ts +0 -1
  49. package/cmp/grid/impl/InitPersist.ts +71 -0
  50. package/cmp/grouping/GroupingChooserModel.ts +48 -57
  51. package/cmp/tab/TabContainerModel.ts +22 -36
  52. package/cmp/zoneGrid/Types.ts +6 -6
  53. package/cmp/zoneGrid/ZoneGridModel.ts +2 -7
  54. package/cmp/zoneGrid/impl/InitPersist.ts +70 -0
  55. package/core/HoistBase.ts +14 -22
  56. package/core/HoistBaseDecorators.ts +26 -28
  57. package/core/persist/CustomProvider.ts +7 -10
  58. package/core/persist/DashViewProvider.ts +8 -10
  59. package/core/persist/LocalStorageProvider.ts +9 -12
  60. package/core/persist/PersistOptions.ts +6 -4
  61. package/core/persist/Persistable.ts +23 -0
  62. package/core/persist/PersistenceProvider.ts +159 -79
  63. package/core/persist/PrefProvider.ts +9 -12
  64. package/core/persist/index.ts +2 -0
  65. package/core/persist/viewmanager/Types.ts +51 -0
  66. package/core/persist/viewmanager/ViewManagerModel.ts +515 -0
  67. package/core/persist/viewmanager/ViewManagerProvider.ts +51 -0
  68. package/core/persist/viewmanager/impl/ManageDialogModel.ts +274 -0
  69. package/core/persist/viewmanager/impl/SaveDialogModel.ts +112 -0
  70. package/core/persist/viewmanager/index.ts +2 -0
  71. package/desktop/cmp/button/ColAutosizeButton.ts +1 -1
  72. package/desktop/cmp/dash/DashConfig.ts +3 -1
  73. package/desktop/cmp/dash/DashModel.ts +1 -2
  74. package/desktop/cmp/dash/DashViewSpec.ts +1 -1
  75. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +31 -30
  76. package/desktop/cmp/dash/container/DashContainerModel.ts +68 -43
  77. package/desktop/cmp/dash/container/impl/DashContainerUtils.ts +13 -4
  78. package/desktop/cmp/leftrightchooser/LeftRightChooserFilter.ts +1 -1
  79. package/desktop/cmp/panel/PanelModel.ts +33 -53
  80. package/desktop/cmp/store/impl/StoreFilterField.ts +1 -1
  81. package/desktop/cmp/viewmanager/ViewManager.scss +58 -0
  82. package/desktop/cmp/viewmanager/ViewManager.ts +274 -0
  83. package/desktop/cmp/viewmanager/cmp/ManageDialog.ts +197 -0
  84. package/desktop/cmp/viewmanager/cmp/SaveDialog.ts +89 -0
  85. package/desktop/cmp/viewmanager/index.ts +3 -0
  86. package/mobile/cmp/button/ColAutosizeButton.ts +1 -1
  87. package/package.json +1 -1
  88. package/promise/Promise.ts +6 -7
  89. package/svc/GridAutosizeService.ts +73 -36
  90. package/svc/JsonBlobService.ts +64 -31
  91. package/tsconfig.tsbuildinfo +1 -1
  92. package/build/types/cmp/grid/impl/GridPersistenceModel.d.ts +0 -41
  93. package/build/types/cmp/zoneGrid/impl/ZoneGridPersistenceModel.d.ts +0 -39
  94. package/cmp/grid/impl/GridPersistenceModel.ts +0 -174
  95. package/cmp/zoneGrid/impl/ZoneGridPersistenceModel.ts +0 -149
@@ -7,6 +7,8 @@
7
7
  import {
8
8
  managed,
9
9
  modelLookupContextProvider,
10
+ Persistable,
11
+ PersistableState,
10
12
  PersistenceProvider,
11
13
  PlainObject,
12
14
  RefreshMode,
@@ -37,7 +39,8 @@ import {
37
39
  } from './impl/DashContainerUtils';
38
40
  import {dashContainerView} from './impl/DashContainerView';
39
41
 
40
- export interface DashContainerConfig extends DashConfig<DashContainerViewSpec, DashViewState> {
42
+ export interface DashContainerConfig
43
+ extends DashConfig<DashContainerViewSpec, DashContainerViewState> {
41
44
  /** Strategy for rendering DashContainerViews. Can also be set per-view in `viewSpecs`*/
42
45
  renderMode?: RenderMode;
43
46
 
@@ -57,6 +60,16 @@ export interface DashContainerConfig extends DashConfig<DashContainerViewSpec, D
57
60
  goldenLayoutSettings?: PlainObject;
58
61
  }
59
62
 
63
+ // TODO - review other state inserted by library, determine if we want to model here
64
+ export interface DashContainerViewState {
65
+ type: 'row' | 'column' | 'stack' | 'view';
66
+ id?: string;
67
+ content?: DashContainerViewState[];
68
+ title?: string;
69
+ width?: number | string;
70
+ height?: number | string;
71
+ }
72
+
60
73
  /**
61
74
  * Model for a DashContainer, representing its contents and layout state.
62
75
  *
@@ -65,7 +78,7 @@ export interface DashContainerConfig extends DashConfig<DashContainerViewSpec, D
65
78
  *
66
79
  * State should be structured as nested arrays of container objects, according to
67
80
  * GoldenLayout's content config. Supported container types are `row`, `column` and `stack`.
68
- * Child containers and views should be provided as an array under the `contents` key.
81
+ * Child containers and views should be provided as an array under the `content` key.
69
82
  *
70
83
  * + `row` lay out its children horizontally.
71
84
  * + `column` lays out its children vertically.
@@ -86,20 +99,20 @@ export interface DashContainerConfig extends DashConfig<DashContainerViewSpec, D
86
99
  * ```
87
100
  * [{
88
101
  * type: 'row',
89
- * contents: [
102
+ * content: [
90
103
  * // The first child of this row has pixel width of '200px'.
91
104
  * // The column will take the remaining width.
92
105
  * {
93
106
  * type: 'stack',
94
107
  * width: '200px',
95
- * contents: [
108
+ * content: [
96
109
  * {type: 'view', id: 'viewId'},
97
110
  * {type: 'view', id: 'viewId'}
98
111
  * ]
99
112
  * },
100
113
  * {
101
114
  * type: 'column',
102
- * contents: [
115
+ * content: [
103
116
  * // Relative height of 40%. The remaining 60% will be split equally by the other views.
104
117
  * {type: 'view', id: 'viewId', height: 40},
105
118
  * {type: 'view', id: 'viewId'},
@@ -113,11 +126,10 @@ export interface DashContainerConfig extends DashConfig<DashContainerViewSpec, D
113
126
  * @see http://golden-layout.com/docs/ItemConfig.html
114
127
  * @see http://golden-layout.com/tutorials/getting-started-react.html
115
128
  */
116
- export class DashContainerModel extends DashModel<
117
- DashContainerViewSpec,
118
- DashViewState,
119
- DashViewModel
120
- > {
129
+ export class DashContainerModel
130
+ extends DashModel<DashContainerViewSpec, DashViewState, DashViewModel>
131
+ implements Persistable<{state: DashViewState[]}>
132
+ {
121
133
  //---------------------
122
134
  // Settable State
123
135
  //----------------------
@@ -187,32 +199,29 @@ export class DashContainerModel extends DashModel<
187
199
  this.emptyText = emptyText;
188
200
  this.addViewButtonText = addViewButtonText;
189
201
  this.extraMenuItems = extraMenuItems;
202
+ this.state = initialState;
190
203
 
191
- // Read state from provider -- fail gently
192
- let persistState = null;
193
204
  if (persistWith) {
194
- try {
195
- this.provider = PersistenceProvider.create({path: 'dashContainer', ...persistWith});
196
- persistState = this.provider.read();
197
- } catch (e) {
198
- this.logError(e);
199
- XH.safeDestroy(this.provider);
200
- this.provider = null;
201
- }
205
+ PersistenceProvider.create({
206
+ persistOptions: {
207
+ path: 'dashContainer',
208
+ ...persistWith
209
+ },
210
+ target: this
211
+ });
202
212
  }
203
213
 
204
- this.state = persistState?.state ?? initialState;
205
-
206
214
  // Initialize GoldenLayout with initial state once ref is ready
207
- this.addReaction({
208
- track: () => [this.containerRef.current, this.layoutLocked],
209
- run: () => this.loadStateAsync(this.state)
210
- });
211
-
212
- this.addReaction({
213
- track: () => this.viewState,
214
- run: () => this.updateState()
215
- });
215
+ this.addReaction(
216
+ {
217
+ track: () => [this.containerRef.current, this.layoutLocked],
218
+ run: () => this.loadStateAsync(this.state)
219
+ },
220
+ {
221
+ track: () => this.viewState,
222
+ run: () => this.updateState()
223
+ }
224
+ );
216
225
  }
217
226
 
218
227
  /**
@@ -228,14 +237,13 @@ export class DashContainerModel extends DashModel<
228
237
  this.contentLocked = restoreState.contentLocked;
229
238
  this.renameLocked = restoreState.renameLocked;
230
239
  await this.loadStateAsync(restoreState.initialState);
231
- this.provider?.clear();
232
240
  }
233
241
 
234
242
  /**
235
243
  * Load state into the DashContainer, recreating its layout and contents
236
244
  * @param state - State to load
237
245
  */
238
- async loadStateAsync(state) {
246
+ async loadStateAsync(state: DashViewState[]) {
239
247
  const containerEl = this.containerRef.current;
240
248
  if (!containerEl) {
241
249
  this.logWarn(
@@ -318,6 +326,32 @@ export class DashContainerModel extends DashModel<
318
326
  this.goldenLayout?.updateSize();
319
327
  }
320
328
 
329
+ getViewSpec(id: string): DashContainerViewSpec {
330
+ return this.viewSpecs.find(it => it.id === id);
331
+ }
332
+
333
+ getViewModel(id: string): DashViewModel<DashContainerViewSpec> {
334
+ return find(this.viewModels, {id});
335
+ }
336
+
337
+ //------------------------
338
+ // Persistable Interface
339
+ //------------------------
340
+ getPersistableState(): PersistableState<{state: DashViewState[]}> {
341
+ return new PersistableState({state: this.state});
342
+ }
343
+
344
+ setPersistableState(persistableState: PersistableState<{state: DashViewState[]}>) {
345
+ const {state} = persistableState.value;
346
+ if (!state) return;
347
+ if (this.containerRef.current) {
348
+ this.loadStateAsync(state);
349
+ } else {
350
+ // If the container is not yet rendered, store the state directly
351
+ this.state = state;
352
+ }
353
+ }
354
+
321
355
  //------------------------
322
356
  // Implementation
323
357
  //------------------------
@@ -342,7 +376,6 @@ export class DashContainerModel extends DashModel<
342
376
  runInAction(() => {
343
377
  this.state = convertGLToState(goldenLayout, this);
344
378
  });
345
- this.provider?.write({state: this.state});
346
379
  }
347
380
 
348
381
  private onItemDestroyed(item) {
@@ -351,10 +384,6 @@ export class DashContainerModel extends DashModel<
351
384
  if (id) this.removeViewModel(id);
352
385
  }
353
386
 
354
- private getViewSpec(id: string) {
355
- return this.viewSpecs.find(it => it.id === id);
356
- }
357
-
358
387
  //-----------------
359
388
  // Items
360
389
  //-----------------
@@ -386,10 +415,6 @@ export class DashContainerModel extends DashModel<
386
415
  return ret;
387
416
  }
388
417
 
389
- private getViewModel(id: string) {
390
- return find(this.viewModels, {id});
391
- }
392
-
393
418
  @action
394
419
  private addViewModel(viewModel: DashViewModel) {
395
420
  this.viewModels = [...this.viewModels, viewModel];
@@ -566,7 +591,7 @@ export class DashContainerModel extends DashModel<
566
591
  //-----------------
567
592
  // Misc
568
593
  //-----------------
569
- private createGoldenLayout(containerEl: HTMLElement, state: any): GoldenLayout {
594
+ private createGoldenLayout(containerEl: HTMLElement, state: DashViewState[]): GoldenLayout {
570
595
  const {viewSpecs} = this,
571
596
  ret = new GoldenLayout(
572
597
  {
@@ -5,10 +5,12 @@
5
5
  * Copyright © 2024 Extremely Heavy Industries Inc.
6
6
  */
7
7
  import {PlainObject} from '@xh/hoist/core';
8
+ import {DashContainerModel} from '@xh/hoist/desktop/cmp/dash';
8
9
  import {serializeIcon} from '@xh/hoist/icon';
9
10
  import {throwIf} from '@xh/hoist/utils/js';
10
11
  import {isArray, isEmpty, isFinite, isNil, isPlainObject, isString, round} from 'lodash';
11
12
  import {DashContainerViewSpec} from '../DashContainerViewSpec';
13
+ import GoldenLayout, {ContentItem} from 'golden-layout';
12
14
 
13
15
  /**
14
16
  * Lookup the DashViewModel id of a rendered view
@@ -21,21 +23,28 @@ export function getViewModelId(view) {
21
23
  /**
22
24
  * Convert the output from Golden Layouts into our serializable state
23
25
  */
24
- export function convertGLToState(goldenLayout, dashContainerModel) {
26
+ export function convertGLToState(
27
+ goldenLayout: GoldenLayout,
28
+ dashContainerModel: DashContainerModel
29
+ ) {
25
30
  const configItems = goldenLayout.toConfig().content,
26
31
  contentItems = goldenLayout.root.contentItems;
27
32
 
28
33
  return convertGLToStateInner(configItems, contentItems, dashContainerModel);
29
34
  }
30
35
 
31
- function convertGLToStateInner(configItems = [], contentItems = [], dashContainerModel) {
36
+ function convertGLToStateInner(
37
+ configItems = [],
38
+ contentItems: ContentItem[] = [],
39
+ dashContainerModel: DashContainerModel
40
+ ) {
32
41
  const ret = [];
33
42
 
34
43
  configItems.forEach((configItem, idx) => {
35
44
  const contentItem = contentItems[idx];
36
45
 
37
46
  if (configItem.type === 'component') {
38
- const viewSpecId = configItem.component,
47
+ const viewSpecId: string = configItem.component,
39
48
  viewSpec = dashContainerModel.getViewSpec(viewSpecId),
40
49
  viewModelId = getViewModelId(contentItem),
41
50
  viewModel = dashContainerModel.getViewModel(viewModelId),
@@ -70,7 +79,7 @@ function convertGLToStateInner(configItems = [], contentItems = [], dashContaine
70
79
  /**
71
80
  * Convert our serializable state into GoldenLayout config
72
81
  */
73
- export function convertStateToGL(state = [], dashContainerModel) {
82
+ export function convertStateToGL(state = [], dashContainerModel: DashContainerModel) {
74
83
  const {viewSpecs, containerRef} = dashContainerModel,
75
84
  containerSize = {
76
85
  width: containerRef.current?.offsetWidth,
@@ -32,7 +32,7 @@ export const [LeftRightChooserFilter, leftRightChooserFilter] =
32
32
  render() {
33
33
  const impl = useLocalModel(LeftRightChooserFilterLocalModel);
34
34
  return textInput({
35
- placeholder: 'Quick filter...',
35
+ placeholder: 'Filter...',
36
36
  bind: 'value',
37
37
  model: impl,
38
38
  commitOnChange: true,
@@ -9,17 +9,17 @@ import {
9
9
  HoistModel,
10
10
  managed,
11
11
  ManagedRefreshContextModel,
12
+ Persistable,
13
+ PersistableState,
12
14
  PersistenceProvider,
13
15
  PersistOptions,
14
- PrefProvider,
15
16
  RefreshContextModel,
16
17
  RefreshMode,
17
18
  RenderMode,
18
- Side,
19
- XH
19
+ Side
20
20
  } from '@xh/hoist/core';
21
21
  import '@xh/hoist/desktop/register';
22
- import {action, makeObservable, observable, comparer, bindable} from '@xh/hoist/mobx';
22
+ import {action, makeObservable, observable, bindable} from '@xh/hoist/mobx';
23
23
  import {wait} from '@xh/hoist/promise';
24
24
  import {throwIf} from '@xh/hoist/utils/js';
25
25
  import {isNil, isNumber, isString} from 'lodash';
@@ -107,11 +107,16 @@ export interface PanelConfig {
107
107
  xhImpl?;
108
108
  }
109
109
 
110
+ export interface PanelPersistState {
111
+ collapsed?: boolean;
112
+ size?: number | string;
113
+ }
114
+
110
115
  /**
111
116
  * PanelModel supports configuration and state-management for user-driven Panel resizing and
112
117
  * expand/collapse, along with support for saving this state via a configured PersistenceProvider.
113
118
  */
114
- export class PanelModel extends HoistModel {
119
+ export class PanelModel extends HoistModel implements Persistable<PanelPersistState> {
115
120
  declare config: PanelConfig;
116
121
 
117
122
  //-----------------------
@@ -134,7 +139,6 @@ export class PanelModel extends HoistModel {
134
139
  @managed modalSupportModel: ModalSupportModel;
135
140
  @managed refreshContextModel: RefreshContextModel;
136
141
  @managed errorBoundaryModel: ErrorBoundaryModel;
137
- @managed provider: PersistenceProvider;
138
142
 
139
143
  //----------------
140
144
  // Settable State
@@ -235,10 +239,10 @@ export class PanelModel extends HoistModel {
235
239
  this.collapsible = collapsible;
236
240
  this.resizable = resizable;
237
241
  this.resizeWhileDragging = resizeWhileDragging;
238
- this.defaultSize = defaultSize;
242
+ this.size = this.defaultSize = defaultSize;
239
243
  this.minSize = minSize;
240
244
  this.maxSize = maxSize;
241
- this.defaultCollapsed = defaultCollapsed;
245
+ this.collapsed = this.defaultCollapsed = defaultCollapsed;
242
246
  this.side = side;
243
247
  this.renderMode = renderMode;
244
248
  this.refreshMode = refreshMode;
@@ -270,36 +274,13 @@ export class PanelModel extends HoistModel {
270
274
  this._resizeRef = createRef();
271
275
  }
272
276
 
273
- // Read state from provider -- fail gently
274
- let state = null;
275
277
  if (persistWith) {
276
- try {
277
- this.provider = PersistenceProvider.create({path: 'panel', ...persistWith});
278
- state = this.provider.read() ?? this.legacyState();
279
- } catch (e) {
280
- this.logError(e);
281
- XH.safeDestroy(this.provider);
282
- this.provider = null;
283
- }
284
- }
285
-
286
- // Initialize state.
287
- this.size = resizable && !isNil(state?.size) ? state.size : defaultSize;
288
- this.setCollapsed(
289
- collapsible && !isNil(state?.collapsed) ? state.collapsed : defaultCollapsed
290
- );
291
-
292
- // Attach to provider last
293
- if (this.provider) {
294
- this.addReaction({
295
- equals: comparer.shallow,
296
- track: () => {
297
- const state: any = {};
298
- if (collapsible) state.collapsed = this.collapsed;
299
- if (resizable) state.size = this.size;
300
- return state;
278
+ PersistenceProvider.create({
279
+ persistOptions: {
280
+ path: 'panel',
281
+ ...persistWith
301
282
  },
302
- run: state => this.provider.write(state)
283
+ target: this
303
284
  });
304
285
  }
305
286
  }
@@ -352,6 +333,22 @@ export class PanelModel extends HoistModel {
352
333
  this.resizeWhileDragging = v;
353
334
  }
354
335
 
336
+ //---------------------------------------------
337
+ // Persistable Interface
338
+ //---------------------------------------------
339
+ getPersistableState(): PersistableState<PanelPersistState> {
340
+ const ret: PanelPersistState = {};
341
+ if (this.collapsible) ret.collapsed = this.collapsed;
342
+ if (this.resizable) ret.size = this.size;
343
+ return new PersistableState(ret);
344
+ }
345
+
346
+ setPersistableState(state: PersistableState<PanelPersistState>): void {
347
+ const {collapsed, size} = state.value;
348
+ if (this.resizable && !isNil(size)) this.size = size;
349
+ if (this.collapsible && !isNil(collapsed)) this.setCollapsed(collapsed);
350
+ }
351
+
355
352
  //---------------------------------------------
356
353
  // Implementation (for related private classes)
357
354
  //---------------------------------------------
@@ -396,23 +393,6 @@ export class PanelModel extends HoistModel {
396
393
  //---------------------------------------------
397
394
  // Implementation (internal)
398
395
  //---------------------------------------------
399
- private legacyState() {
400
- const {provider} = this;
401
- if (provider instanceof PrefProvider) {
402
- try {
403
- const data = XH.getPref(provider.key);
404
- if (data && !isNil(data.collapsed) && !isNil(data.size)) {
405
- provider.write(data);
406
- provider.clear('collapsed');
407
- provider.clear('size');
408
- return data;
409
- }
410
- } catch (e) {
411
- this.logError('Failed reading legacy state', e);
412
- }
413
- }
414
- return null;
415
- }
416
396
 
417
397
  private dispatchResize() {
418
398
  // Forces other components to redraw if required.
@@ -17,7 +17,7 @@ export function storeFilterFieldImpl(props) {
17
17
  commitOnChange: true,
18
18
  leftIcon: Icon.filter(),
19
19
  enableClear: true,
20
- placeholder: 'Filter',
20
+ placeholder: 'Filter...',
21
21
  selectOnFocus: true,
22
22
  width: 180,
23
23
  ...props
@@ -0,0 +1,58 @@
1
+ .xh-view-manager {
2
+ align-items: center;
3
+
4
+ &__menu-item {
5
+ &:hover {
6
+ .xh-view-manager__menu-item__fave-toggle {
7
+ opacity: 1;
8
+ color: var(--xh-yellow);
9
+ }
10
+ }
11
+
12
+ &__fave-toggle {
13
+ opacity: 0;
14
+
15
+ &:hover {
16
+ color: var(--xh-yellow-light) !important;
17
+ }
18
+
19
+ &--active {
20
+ opacity: 1;
21
+ color: var(--xh-yellow);
22
+ }
23
+
24
+ &--active:hover {
25
+ color: var(--xh-yellow-light) !important;
26
+ }
27
+ }
28
+ }
29
+
30
+ //------------------------
31
+ // Dialogs
32
+ //------------------------
33
+ &__manage-dialog,
34
+ &__save-dialog {
35
+ &__form {
36
+ padding: var(--xh-pad-px);
37
+
38
+ .xh-form-field.xh-form-field-readonly .xh-form-field-readonly-display {
39
+ padding: 0;
40
+ }
41
+
42
+ .xh-form-field .xh-form-field-info {
43
+ line-height: 1.5em;
44
+ margin-top: var(--xh-pad-half-px);
45
+ white-space: unset;
46
+
47
+ .xh-icon {
48
+ margin-right: 2px;
49
+ }
50
+ }
51
+ }
52
+
53
+ &__metadata {
54
+ color: var(--xh-text-color-muted);
55
+ font-size: var(--xh-font-size-small-px);
56
+ }
57
+ }
58
+ }