@xh/hoist 71.0.0-SNAPSHOT.1733262000771 → 71.0.0-SNAPSHOT.1733266596001
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 +8 -2
- package/appcontainer/AppContainerModel.ts +2 -1
- package/build/types/cmp/viewmanager/SaveAsDialogModel.d.ts +23 -0
- package/build/types/cmp/viewmanager/View.d.ts +28 -0
- package/build/types/cmp/viewmanager/ViewInfo.d.ts +30 -0
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +185 -0
- package/build/types/cmp/viewmanager/index.d.ts +4 -0
- package/build/types/core/XH.d.ts +2 -1
- package/build/types/core/persist/PersistOptions.d.ts +3 -1
- package/build/types/core/persist/index.d.ts +6 -5
- package/build/types/core/persist/{CustomProvider.d.ts → provider/CustomProvider.d.ts} +1 -1
- package/build/types/core/persist/{DashViewProvider.d.ts → provider/DashViewProvider.d.ts} +2 -2
- package/build/types/core/persist/{LocalStorageProvider.d.ts → provider/LocalStorageProvider.d.ts} +1 -1
- package/build/types/core/persist/{PrefProvider.d.ts → provider/PrefProvider.d.ts} +1 -2
- package/build/types/core/persist/provider/SessionStorageProvider.d.ts +10 -0
- package/build/types/core/persist/{viewmanager → provider}/ViewManagerProvider.d.ts +3 -3
- package/build/types/desktop/cmp/viewmanager/ViewManager.d.ts +9 -10
- package/build/types/desktop/cmp/viewmanager/ViewMenu.d.ts +5 -0
- package/build/types/desktop/cmp/viewmanager/dialog/EditForm.d.ts +5 -0
- package/build/types/desktop/cmp/viewmanager/dialog/EditFormModel.d.ts +18 -0
- package/build/types/desktop/cmp/viewmanager/dialog/ManageDialog.d.ts +5 -0
- package/build/types/desktop/cmp/viewmanager/dialog/ManageDialogModel.d.ts +38 -0
- package/build/types/desktop/cmp/viewmanager/dialog/SaveAsDialog.d.ts +5 -0
- package/build/types/svc/JsonBlobService.d.ts +1 -1
- package/build/types/svc/index.d.ts +2 -1
- package/build/types/svc/storage/BaseStorageService.d.ts +21 -0
- package/build/types/svc/storage/LocalStorageService.d.ts +12 -0
- package/build/types/svc/storage/SessionStorageService.d.ts +12 -0
- package/cmp/viewmanager/SaveAsDialogModel.ts +97 -0
- package/cmp/viewmanager/View.ts +56 -0
- package/cmp/viewmanager/ViewInfo.ts +58 -0
- package/cmp/viewmanager/ViewManagerModel.ts +710 -0
- package/cmp/viewmanager/index.ts +4 -0
- package/core/XH.ts +2 -0
- package/core/persist/PersistOptions.ts +4 -1
- package/core/persist/PersistenceProvider.ts +5 -0
- package/core/persist/index.ts +6 -5
- package/core/persist/{CustomProvider.ts → provider/CustomProvider.ts} +1 -1
- package/core/persist/{DashViewProvider.ts → provider/DashViewProvider.ts} +1 -1
- package/core/persist/{LocalStorageProvider.ts → provider/LocalStorageProvider.ts} +1 -1
- package/core/persist/{PrefProvider.ts → provider/PrefProvider.ts} +2 -2
- package/core/persist/provider/SessionStorageProvider.ts +35 -0
- package/core/persist/{viewmanager → provider}/ViewManagerProvider.ts +5 -9
- package/desktop/cmp/viewmanager/ViewManager.ts +47 -229
- package/desktop/cmp/viewmanager/ViewMenu.ts +191 -0
- package/desktop/cmp/viewmanager/dialog/EditForm.ts +126 -0
- package/desktop/cmp/viewmanager/dialog/EditFormModel.ts +125 -0
- package/desktop/cmp/viewmanager/dialog/ManageDialog.ts +98 -0
- package/desktop/cmp/viewmanager/dialog/ManageDialogModel.ts +279 -0
- package/desktop/cmp/viewmanager/{impl/SaveDialog.ts → dialog/SaveAsDialog.ts} +20 -12
- package/package.json +1 -1
- package/svc/JsonBlobService.ts +1 -1
- package/svc/index.ts +2 -1
- package/svc/{LocalStorageService.ts → storage/BaseStorageService.ts} +13 -23
- package/svc/storage/LocalStorageService.ts +23 -0
- package/svc/storage/SessionStorageService.ts +23 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/types/core/persist/viewmanager/Types.d.ts +0 -48
- package/build/types/core/persist/viewmanager/ViewManagerModel.d.ts +0 -145
- package/build/types/core/persist/viewmanager/impl/BuildViewTree.d.ts +0 -8
- package/build/types/core/persist/viewmanager/impl/ManageDialogModel.d.ts +0 -30
- package/build/types/core/persist/viewmanager/impl/SaveDialogModel.d.ts +0 -23
- package/build/types/core/persist/viewmanager/index.d.ts +0 -2
- package/build/types/desktop/cmp/viewmanager/impl/ManageDialog.d.ts +0 -6
- package/build/types/desktop/cmp/viewmanager/impl/SaveDialog.d.ts +0 -2
- package/build/types/svc/LocalStorageService.d.ts +0 -24
- package/core/persist/viewmanager/Types.ts +0 -53
- package/core/persist/viewmanager/ViewManagerModel.ts +0 -481
- package/core/persist/viewmanager/impl/BuildViewTree.ts +0 -68
- package/core/persist/viewmanager/impl/ManageDialogModel.ts +0 -276
- package/core/persist/viewmanager/impl/SaveDialogModel.ts +0 -112
- package/core/persist/viewmanager/index.ts +0 -2
- package/desktop/cmp/viewmanager/impl/ManageDialog.ts +0 -197
package/core/XH.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
JsonBlobService,
|
|
27
27
|
LocalStorageService,
|
|
28
28
|
PrefService,
|
|
29
|
+
SessionStorageService,
|
|
29
30
|
TrackService,
|
|
30
31
|
WebSocketService
|
|
31
32
|
} from '@xh/hoist/svc';
|
|
@@ -140,6 +141,7 @@ export class XHApi {
|
|
|
140
141
|
jsonBlobService: JsonBlobService;
|
|
141
142
|
localStorageService: LocalStorageService;
|
|
142
143
|
prefService: PrefService;
|
|
144
|
+
sessionStorageService: SessionStorageService;
|
|
143
145
|
trackService: TrackService;
|
|
144
146
|
webSocketService: WebSocketService;
|
|
145
147
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import {DebounceSpec} from '../';
|
|
9
9
|
import type {DashViewModel} from '@xh/hoist/desktop/cmp/dash'; // Import type only
|
|
10
|
-
import type {ViewManagerModel} from '@xh/hoist/
|
|
10
|
+
import type {ViewManagerModel} from '@xh/hoist/cmp/viewmanager'; // Import type only
|
|
11
11
|
|
|
12
12
|
export interface PersistOptions {
|
|
13
13
|
/** Dot delimited path to store state. */
|
|
@@ -28,6 +28,9 @@ export interface PersistOptions {
|
|
|
28
28
|
/** Browser local storage key used to store state. */
|
|
29
29
|
localStorageKey?: string;
|
|
30
30
|
|
|
31
|
+
/** Session (tab-specific) storage key used to store state. */
|
|
32
|
+
sessionStorageKey?: string;
|
|
33
|
+
|
|
31
34
|
/** DashViewModel used to read / write view state. */
|
|
32
35
|
dashViewModel?: DashViewModel;
|
|
33
36
|
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
CustomProvider,
|
|
23
23
|
DashViewProvider,
|
|
24
24
|
LocalStorageProvider,
|
|
25
|
+
SessionStorageProvider,
|
|
25
26
|
PersistOptions,
|
|
26
27
|
PrefProvider,
|
|
27
28
|
ViewManagerProvider
|
|
@@ -91,6 +92,7 @@ export abstract class PersistenceProvider<S> {
|
|
|
91
92
|
if (!type) {
|
|
92
93
|
if (rest.prefKey) type = 'pref';
|
|
93
94
|
if (rest.localStorageKey) type = 'localStorage';
|
|
95
|
+
if (rest.sessionStorageKey) type = 'sessionStorage';
|
|
94
96
|
if (rest.dashViewModel) type = 'dashView';
|
|
95
97
|
if (rest.viewManagerModel) type = 'viewManager';
|
|
96
98
|
if (rest.getData || rest.setData) type = 'custom';
|
|
@@ -103,6 +105,9 @@ export abstract class PersistenceProvider<S> {
|
|
|
103
105
|
case 'localStorage':
|
|
104
106
|
ret = new LocalStorageProvider(cfg);
|
|
105
107
|
break;
|
|
108
|
+
case 'sessionStorage':
|
|
109
|
+
ret = new SessionStorageProvider(cfg);
|
|
110
|
+
break;
|
|
106
111
|
case `dashView`:
|
|
107
112
|
ret = new DashViewProvider(cfg);
|
|
108
113
|
break;
|
package/core/persist/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export * from './Persistable';
|
|
2
2
|
export * from './PersistOptions';
|
|
3
3
|
export * from './PersistenceProvider';
|
|
4
|
-
export * from './LocalStorageProvider';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
4
|
+
export * from './provider/LocalStorageProvider';
|
|
5
|
+
export * from './provider/SessionStorageProvider';
|
|
6
|
+
export * from './provider/DashViewProvider';
|
|
7
|
+
export * from './provider/PrefProvider';
|
|
8
|
+
export * from './provider/CustomProvider';
|
|
9
|
+
export * from './provider/ViewManagerProvider';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {PersistenceProvider, PersistenceProviderConfig} from '
|
|
8
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
9
9
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type {DashViewModel} from '@xh/hoist/desktop/cmp/dash'; // Import type only
|
|
9
9
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
10
|
-
import {PersistenceProvider, PersistenceProviderConfig} from '
|
|
10
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* PersistenceProvider that stores state within a DashViewModel.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import {XH} from '@xh/hoist/core';
|
|
9
9
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
10
|
-
import {PersistenceProvider, PersistenceProviderConfig} from '
|
|
10
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* PersistenceProvider that stores state within the Browser's LocalStorage.
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import {PersistenceProvider} from '
|
|
8
|
+
import {XH} from '@xh/hoist/core/';
|
|
9
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
10
10
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file belongs to Hoist, an application development toolkit
|
|
3
|
+
* developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
|
|
4
|
+
*
|
|
5
|
+
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {XH} from '@xh/hoist/core';
|
|
9
|
+
import {throwIf} from '@xh/hoist/utils/js';
|
|
10
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* PersistenceProvider that stores state within the Browser's SessionStorage.
|
|
14
|
+
*/
|
|
15
|
+
export class SessionStorageProvider<S> extends PersistenceProvider<S> {
|
|
16
|
+
readonly key: string;
|
|
17
|
+
|
|
18
|
+
constructor(cfg: PersistenceProviderConfig<S>) {
|
|
19
|
+
super(cfg);
|
|
20
|
+
const {sessionStorageKey} = cfg.persistOptions;
|
|
21
|
+
throwIf(!sessionStorageKey, `SessionStorageProvider requires a 'sessionStorageKey'.`);
|
|
22
|
+
this.key = sessionStorageKey;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//----------------
|
|
26
|
+
// Implementation
|
|
27
|
+
//----------------
|
|
28
|
+
override readRaw() {
|
|
29
|
+
return XH.sessionStorageService.get(this.key, {});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override writeRaw(data) {
|
|
33
|
+
XH.sessionStorageService.set(this.key, data);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import {throwIf} from '@xh/hoist/utils/js';
|
|
9
9
|
import {pull} from 'lodash';
|
|
10
|
-
import {PersistenceProvider, PersistenceProviderConfig} from '../
|
|
11
|
-
import type {ViewManagerModel} from '
|
|
10
|
+
import {PersistenceProvider, PersistenceProviderConfig} from '../PersistenceProvider';
|
|
11
|
+
import type {ViewManagerModel} from '@xh/hoist/cmp/viewmanager/ViewManagerModel';
|
|
12
12
|
|
|
13
13
|
export class ViewManagerProvider<S> extends PersistenceProvider<S> {
|
|
14
14
|
readonly viewManagerModel: ViewManagerModel;
|
|
@@ -23,22 +23,18 @@ export class ViewManagerProvider<S> extends PersistenceProvider<S> {
|
|
|
23
23
|
|
|
24
24
|
pushStateToTarget() {
|
|
25
25
|
const state = this.read();
|
|
26
|
-
|
|
27
|
-
this.target.setPersistableState(state);
|
|
28
|
-
} else {
|
|
29
|
-
this.target.setPersistableState(this.defaultState);
|
|
30
|
-
}
|
|
26
|
+
this.target.setPersistableState(state ? state : this.defaultState);
|
|
31
27
|
}
|
|
32
28
|
|
|
33
29
|
//----------------
|
|
34
30
|
// Implementation
|
|
35
31
|
//----------------
|
|
36
32
|
override readRaw() {
|
|
37
|
-
return this.viewManagerModel.
|
|
33
|
+
return this.viewManagerModel.getValue();
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
override writeRaw(data: Record<typeof this.path, S>) {
|
|
41
|
-
this.viewManagerModel.
|
|
37
|
+
this.viewManagerModel.setValue(data);
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
override destroy() {
|
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
/*
|
|
2
|
+
* This file belongs to Hoist, an application development toolkit
|
|
3
|
+
* developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
|
|
4
|
+
*
|
|
5
|
+
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {fragment, hbox} from '@xh/hoist/cmp/layout';
|
|
2
9
|
import {hoistCmp, HoistProps, uses} from '@xh/hoist/core';
|
|
3
|
-
import '
|
|
4
|
-
import {ViewTree} from '@xh/hoist/core/persist/viewmanager';
|
|
5
|
-
import {ViewManagerModel} from '@xh/hoist/core/persist/viewmanager/ViewManagerModel';
|
|
10
|
+
import {ViewManagerModel} from '@xh/hoist/cmp/viewmanager';
|
|
6
11
|
import {button, ButtonProps} from '@xh/hoist/desktop/cmp/button';
|
|
7
|
-
import {switchInput} from '@xh/hoist/desktop/cmp/input';
|
|
8
|
-
import {manageDialog} from './impl/ManageDialog';
|
|
9
|
-
import {saveDialog} from './impl/SaveDialog';
|
|
10
12
|
import {Icon} from '@xh/hoist/icon';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import {popover} from '@xh/hoist/kit/blueprint';
|
|
14
|
+
import {startCase} from 'lodash';
|
|
15
|
+
import {viewMenu} from './ViewMenu';
|
|
16
|
+
import {manageDialog} from './dialog/ManageDialog';
|
|
17
|
+
import {saveAsDialog} from './dialog/SaveAsDialog';
|
|
18
|
+
|
|
19
|
+
import './ViewManager.scss';
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
22
|
* Visibility options for save/revert button.
|
|
18
23
|
*
|
|
19
24
|
* 'never' to hide button.
|
|
20
25
|
* 'whenDirty' to only show when persistence state is dirty and button is therefore enabled.
|
|
21
|
-
* 'always' will always show button
|
|
22
|
-
*
|
|
23
|
-
* Note that we never show the button when 'autoSave' is active because it would never be enabled
|
|
24
|
-
* for more than a flash.
|
|
26
|
+
* 'always' will always show button.
|
|
25
27
|
*/
|
|
26
28
|
export type ViewManagerStateButtonMode = 'whenDirty' | 'always' | 'never';
|
|
27
29
|
|
|
@@ -34,16 +36,17 @@ export interface ViewManagerProps extends HoistProps<ViewManagerModel> {
|
|
|
34
36
|
showSaveButton?: ViewManagerStateButtonMode;
|
|
35
37
|
/** Default 'never' */
|
|
36
38
|
showRevertButton?: ViewManagerStateButtonMode;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
/** Side the save and revert buttons should appear on (default 'right') */
|
|
40
|
+
buttonSide?: 'left' | 'right';
|
|
41
|
+
/** True to render private views in sub-menu (Default false) */
|
|
39
42
|
showPrivateViewsInSubMenu?: boolean;
|
|
40
|
-
/** True to render
|
|
41
|
-
|
|
43
|
+
/** True to render global views in sub-menu (Default false) */
|
|
44
|
+
showGlobalViewsInSubMenu?: boolean;
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
* Desktop ViewManager component - a button-based menu for saving and swapping between named
|
|
46
|
-
* bundles of persisted component state (
|
|
49
|
+
* bundles of persisted component state (e.g. grid views, dashboards, and similar).
|
|
47
50
|
*
|
|
48
51
|
* See {@link ViewManagerModel} for additional details and configuration options.
|
|
49
52
|
*/
|
|
@@ -60,45 +63,36 @@ export const [ViewManager, viewManager] = hoistCmp.withFactory<ViewManagerProps>
|
|
|
60
63
|
revertButtonProps,
|
|
61
64
|
showSaveButton = 'whenDirty',
|
|
62
65
|
showRevertButton = 'never',
|
|
66
|
+
buttonSide = 'right',
|
|
63
67
|
showPrivateViewsInSubMenu = false,
|
|
64
|
-
|
|
68
|
+
showGlobalViewsInSubMenu = false
|
|
65
69
|
}: ViewManagerProps) {
|
|
70
|
+
const save = saveButton({mode: showSaveButton, ...saveButtonProps}),
|
|
71
|
+
revert = revertButton({mode: showRevertButton, ...revertButtonProps}),
|
|
72
|
+
menu = popover({
|
|
73
|
+
item: menuButton(menuButtonProps),
|
|
74
|
+
content: viewMenu({showPrivateViewsInSubMenu, showGlobalViewsInSubMenu}),
|
|
75
|
+
placement: 'bottom-start',
|
|
76
|
+
popoverClassName: 'xh-view-manager__popover'
|
|
77
|
+
});
|
|
66
78
|
return fragment(
|
|
67
79
|
hbox({
|
|
68
80
|
className,
|
|
69
|
-
items: [
|
|
70
|
-
popover({
|
|
71
|
-
item: menuButton(menuButtonProps),
|
|
72
|
-
content: viewMenu({showPrivateViewsInSubMenu, showSharedViewsInSubMenu}),
|
|
73
|
-
placement: 'bottom-start',
|
|
74
|
-
popoverClassName: 'xh-view-manager__popover'
|
|
75
|
-
}),
|
|
76
|
-
saveButton({
|
|
77
|
-
mode: showSaveButton,
|
|
78
|
-
...saveButtonProps
|
|
79
|
-
}),
|
|
80
|
-
revertButton({
|
|
81
|
-
mode: showRevertButton,
|
|
82
|
-
...revertButtonProps
|
|
83
|
-
})
|
|
84
|
-
]
|
|
81
|
+
items: buttonSide == 'left' ? [revert, save, menu] : [menu, save, revert]
|
|
85
82
|
}),
|
|
86
|
-
manageDialog({
|
|
87
|
-
|
|
88
|
-
onClose: () => model.closeManageDialog()
|
|
89
|
-
}),
|
|
90
|
-
saveDialog()
|
|
83
|
+
manageDialog({omit: !model.manageDialogOpen}),
|
|
84
|
+
saveAsDialog()
|
|
91
85
|
);
|
|
92
86
|
}
|
|
93
87
|
});
|
|
94
88
|
|
|
95
89
|
const menuButton = hoistCmp.factory<ViewManagerModel>({
|
|
96
90
|
render({model, ...rest}) {
|
|
97
|
-
const {
|
|
91
|
+
const {view, typeDisplayName, isLoading} = model;
|
|
98
92
|
return button({
|
|
99
93
|
className: 'xh-view-manager__menu-button',
|
|
100
|
-
text:
|
|
101
|
-
icon: Icon.bookmark(),
|
|
94
|
+
text: view.info?.name ?? `Default ${startCase(typeDisplayName)}`,
|
|
95
|
+
icon: !isLoading ? Icon.bookmark() : Icon.spinner({className: 'fa-spin'}),
|
|
102
96
|
rightIcon: Icon.chevronDown(),
|
|
103
97
|
outlined: true,
|
|
104
98
|
...rest
|
|
@@ -112,11 +106,11 @@ const saveButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
112
106
|
return button({
|
|
113
107
|
className: 'xh-view-manager__save-button',
|
|
114
108
|
icon: Icon.save(),
|
|
115
|
-
tooltip: `Save changes to this ${model.
|
|
109
|
+
tooltip: `Save changes to this ${model.typeDisplayName}`,
|
|
116
110
|
intent: 'primary',
|
|
117
|
-
disabled: !model.
|
|
111
|
+
disabled: !model.isValueDirty || model.isLoading,
|
|
118
112
|
onClick: () => {
|
|
119
|
-
model.
|
|
113
|
+
model.isViewSavable ? model.saveAsync() : model.saveAsAsync();
|
|
120
114
|
},
|
|
121
115
|
...rest
|
|
122
116
|
});
|
|
@@ -129,9 +123,9 @@ const revertButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
129
123
|
return button({
|
|
130
124
|
className: 'xh-view-manager__revert-button',
|
|
131
125
|
icon: Icon.reset(),
|
|
132
|
-
tooltip: `Revert changes to this ${model.
|
|
126
|
+
tooltip: `Revert changes to this ${model.typeDisplayName}`,
|
|
133
127
|
intent: 'danger',
|
|
134
|
-
disabled: !model.
|
|
128
|
+
disabled: !model.isValueDirty || model.isLoading,
|
|
135
129
|
onClick: () => model.resetAsync(),
|
|
136
130
|
...rest
|
|
137
131
|
});
|
|
@@ -139,183 +133,7 @@ const revertButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
139
133
|
});
|
|
140
134
|
|
|
141
135
|
function hideStateButton(model: ViewManagerModel, mode: ViewManagerStateButtonMode): boolean {
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const viewMenu = hoistCmp.factory<ViewManagerProps>({
|
|
146
|
-
render({model, showPrivateViewsInSubMenu, showSharedViewsInSubMenu}) {
|
|
147
|
-
const {
|
|
148
|
-
autoSaveUnavailableReason,
|
|
149
|
-
enableDefault,
|
|
150
|
-
canSave,
|
|
151
|
-
selectedToken,
|
|
152
|
-
enableAutoSave,
|
|
153
|
-
DisplayName,
|
|
154
|
-
autoSave,
|
|
155
|
-
privateViewTree,
|
|
156
|
-
sharedViewTree,
|
|
157
|
-
favoriteViews,
|
|
158
|
-
views,
|
|
159
|
-
isDirty
|
|
160
|
-
} = model;
|
|
161
|
-
|
|
162
|
-
const pluralDisp = pluralize(DisplayName),
|
|
163
|
-
items = [];
|
|
164
|
-
if (!isEmpty(favoriteViews)) {
|
|
165
|
-
items.push(
|
|
166
|
-
menuDivider({title: 'Favorites'}),
|
|
167
|
-
...favoriteViews.map(it => {
|
|
168
|
-
return menuItem({
|
|
169
|
-
key: `${it.token}-favorite`,
|
|
170
|
-
icon: model.selectedToken === it.token ? Icon.check() : Icon.placeholder(),
|
|
171
|
-
text: menuItemTextAndFaveToggle({
|
|
172
|
-
view: {...it, text: it.shortName}
|
|
173
|
-
}),
|
|
174
|
-
onClick: () => model.selectViewAsync(it.token),
|
|
175
|
-
title: it.description
|
|
176
|
-
});
|
|
177
|
-
})
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (!isEmpty(privateViewTree)) {
|
|
182
|
-
if (showPrivateViewsInSubMenu) {
|
|
183
|
-
items.push(
|
|
184
|
-
menuDivider({omit: isEmpty(items)}),
|
|
185
|
-
menuItem({
|
|
186
|
-
text: `My ${pluralDisp}`,
|
|
187
|
-
shouldDismissPopover: false,
|
|
188
|
-
items: privateViewTree.map(it => buildMenuItem(it, model))
|
|
189
|
-
})
|
|
190
|
-
);
|
|
191
|
-
} else {
|
|
192
|
-
items.push(
|
|
193
|
-
menuDivider({title: `My ${pluralDisp}`}),
|
|
194
|
-
...privateViewTree.map(it => buildMenuItem(it, model))
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!isEmpty(sharedViewTree)) {
|
|
200
|
-
if (showSharedViewsInSubMenu) {
|
|
201
|
-
items.push(
|
|
202
|
-
menuDivider({omit: isEmpty(items)}),
|
|
203
|
-
menuItem({
|
|
204
|
-
text: `Shared ${pluralDisp}`,
|
|
205
|
-
shouldDismissPopover: false,
|
|
206
|
-
items: sharedViewTree.map(it => buildMenuItem(it, model))
|
|
207
|
-
})
|
|
208
|
-
);
|
|
209
|
-
} else {
|
|
210
|
-
items.push(
|
|
211
|
-
menuDivider({title: `Shared ${pluralDisp}`}),
|
|
212
|
-
...sharedViewTree.map(it => buildMenuItem(it, model))
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return menu({
|
|
218
|
-
className: 'xh-view-manager__menu',
|
|
219
|
-
items: [
|
|
220
|
-
...items,
|
|
221
|
-
menuDivider({omit: !enableDefault || isEmpty(items)}),
|
|
222
|
-
menuItem({
|
|
223
|
-
icon: selectedToken ? Icon.placeholder() : Icon.check(),
|
|
224
|
-
text: `Default ${DisplayName}`,
|
|
225
|
-
omit: !enableDefault,
|
|
226
|
-
onClick: () => model.selectViewAsync(null)
|
|
227
|
-
}),
|
|
228
|
-
menuDivider(),
|
|
229
|
-
menuItem({
|
|
230
|
-
icon: Icon.save(),
|
|
231
|
-
text: 'Save',
|
|
232
|
-
disabled: !canSave || !isDirty,
|
|
233
|
-
onClick: () => model.saveAsync()
|
|
234
|
-
}),
|
|
235
|
-
menuItem({
|
|
236
|
-
icon: Icon.copy(),
|
|
237
|
-
text: 'Save As...',
|
|
238
|
-
onClick: () => model.saveAsAsync()
|
|
239
|
-
}),
|
|
240
|
-
menuItem({
|
|
241
|
-
icon: Icon.reset(),
|
|
242
|
-
text: `Revert`,
|
|
243
|
-
disabled: !isDirty,
|
|
244
|
-
onClick: () => model.resetAsync()
|
|
245
|
-
}),
|
|
246
|
-
menuDivider({omit: !enableAutoSave}),
|
|
247
|
-
menuItem({
|
|
248
|
-
omit: !enableAutoSave,
|
|
249
|
-
text: switchInput({
|
|
250
|
-
label: 'Auto Save',
|
|
251
|
-
value: !autoSaveUnavailableReason && autoSave,
|
|
252
|
-
disabled: !!autoSaveUnavailableReason,
|
|
253
|
-
onChange: v => (model.autoSave = v),
|
|
254
|
-
inline: true
|
|
255
|
-
}),
|
|
256
|
-
title: autoSaveUnavailableReason,
|
|
257
|
-
shouldDismissPopover: false
|
|
258
|
-
}),
|
|
259
|
-
menuDivider(),
|
|
260
|
-
menuItem({
|
|
261
|
-
icon: Icon.gear(),
|
|
262
|
-
disabled: isEmpty(views),
|
|
263
|
-
text: `Manage ${pluralDisp}...`,
|
|
264
|
-
onClick: () => model.openManageDialog()
|
|
265
|
-
})
|
|
266
|
-
]
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
function buildMenuItem(viewOrFolder: ViewTree, model: ViewManagerModel): ReactNode {
|
|
272
|
-
const {type, text, selected} = viewOrFolder,
|
|
273
|
-
icon = selected ? Icon.check() : Icon.placeholder();
|
|
274
|
-
|
|
275
|
-
switch (type) {
|
|
276
|
-
case 'folder':
|
|
277
|
-
return menuItem({
|
|
278
|
-
text,
|
|
279
|
-
icon,
|
|
280
|
-
shouldDismissPopover: false,
|
|
281
|
-
items: viewOrFolder.items
|
|
282
|
-
? viewOrFolder.items.map(child => buildMenuItem(child, model))
|
|
283
|
-
: []
|
|
284
|
-
});
|
|
285
|
-
case 'view':
|
|
286
|
-
return menuItem({
|
|
287
|
-
className: 'xh-view-manager__menu-item',
|
|
288
|
-
key: viewOrFolder.token,
|
|
289
|
-
icon,
|
|
290
|
-
text: menuItemTextAndFaveToggle({model, view: viewOrFolder}),
|
|
291
|
-
title: viewOrFolder.description,
|
|
292
|
-
onClick: () => model.selectViewAsync(viewOrFolder.token)
|
|
293
|
-
});
|
|
294
|
-
}
|
|
136
|
+
return (
|
|
137
|
+
mode === 'never' || (mode === 'whenDirty' && !model.isValueDirty) || model.isViewAutoSavable
|
|
138
|
+
);
|
|
295
139
|
}
|
|
296
|
-
|
|
297
|
-
const menuItemTextAndFaveToggle = hoistCmp.factory<ViewManagerModel>({
|
|
298
|
-
render({model, view}) {
|
|
299
|
-
const isFavorite = model.isFavorite(view.token);
|
|
300
|
-
return hbox({
|
|
301
|
-
alignItems: 'center',
|
|
302
|
-
items: [
|
|
303
|
-
span({style: {paddingRight: 5}, item: view.text}),
|
|
304
|
-
fragment({
|
|
305
|
-
omit: !model.enableFavorites,
|
|
306
|
-
items: [
|
|
307
|
-
filler(),
|
|
308
|
-
div({
|
|
309
|
-
className: `xh-view-manager__menu-item__fave-toggle ${isFavorite ? 'xh-view-manager__menu-item__fave-toggle--active' : ''}`,
|
|
310
|
-
item: Icon.favorite({prefix: isFavorite ? 'fas' : 'far'}),
|
|
311
|
-
onClick: e => {
|
|
312
|
-
consumeEvent(e);
|
|
313
|
-
model.toggleFavorite(view.token);
|
|
314
|
-
}
|
|
315
|
-
})
|
|
316
|
-
]
|
|
317
|
-
})
|
|
318
|
-
]
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
});
|