@xh/hoist 71.0.0-SNAPSHOT.1733262000771 → 71.0.0-SNAPSHOT.1733347475493
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 +53 -229
- package/desktop/cmp/viewmanager/ViewMenu.ts +201 -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,30 @@
|
|
|
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 {box, fragment, hbox} from '@xh/hoist/cmp/layout';
|
|
9
|
+
import {spinner} from '@xh/hoist/cmp/spinner';
|
|
2
10
|
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';
|
|
11
|
+
import {ViewManagerModel} from '@xh/hoist/cmp/viewmanager';
|
|
6
12
|
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
13
|
import {Icon} from '@xh/hoist/icon';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
14
|
+
import {popover} from '@xh/hoist/kit/blueprint';
|
|
15
|
+
import {startCase} from 'lodash';
|
|
16
|
+
import {viewMenu} from './ViewMenu';
|
|
17
|
+
import {manageDialog} from './dialog/ManageDialog';
|
|
18
|
+
import {saveAsDialog} from './dialog/SaveAsDialog';
|
|
19
|
+
|
|
20
|
+
import './ViewManager.scss';
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
23
|
* Visibility options for save/revert button.
|
|
18
24
|
*
|
|
19
25
|
* 'never' to hide button.
|
|
20
26
|
* '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.
|
|
27
|
+
* 'always' will always show button.
|
|
25
28
|
*/
|
|
26
29
|
export type ViewManagerStateButtonMode = 'whenDirty' | 'always' | 'never';
|
|
27
30
|
|
|
@@ -34,16 +37,17 @@ export interface ViewManagerProps extends HoistProps<ViewManagerModel> {
|
|
|
34
37
|
showSaveButton?: ViewManagerStateButtonMode;
|
|
35
38
|
/** Default 'never' */
|
|
36
39
|
showRevertButton?: ViewManagerStateButtonMode;
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
/** Side the save and revert buttons should appear on (default 'right') */
|
|
41
|
+
buttonSide?: 'left' | 'right';
|
|
42
|
+
/** True to render private views in sub-menu (Default false) */
|
|
39
43
|
showPrivateViewsInSubMenu?: boolean;
|
|
40
|
-
/** True to render
|
|
41
|
-
|
|
44
|
+
/** True to render global views in sub-menu (Default false) */
|
|
45
|
+
showGlobalViewsInSubMenu?: boolean;
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
/**
|
|
45
49
|
* Desktop ViewManager component - a button-based menu for saving and swapping between named
|
|
46
|
-
* bundles of persisted component state (
|
|
50
|
+
* bundles of persisted component state (e.g. grid views, dashboards, and similar).
|
|
47
51
|
*
|
|
48
52
|
* See {@link ViewManagerModel} for additional details and configuration options.
|
|
49
53
|
*/
|
|
@@ -60,45 +64,41 @@ export const [ViewManager, viewManager] = hoistCmp.withFactory<ViewManagerProps>
|
|
|
60
64
|
revertButtonProps,
|
|
61
65
|
showSaveButton = 'whenDirty',
|
|
62
66
|
showRevertButton = 'never',
|
|
67
|
+
buttonSide = 'right',
|
|
63
68
|
showPrivateViewsInSubMenu = false,
|
|
64
|
-
|
|
69
|
+
showGlobalViewsInSubMenu = false
|
|
65
70
|
}: ViewManagerProps) {
|
|
71
|
+
const save = saveButton({mode: showSaveButton, ...saveButtonProps}),
|
|
72
|
+
revert = revertButton({mode: showRevertButton, ...revertButtonProps}),
|
|
73
|
+
menu = popover({
|
|
74
|
+
item: menuButton(menuButtonProps),
|
|
75
|
+
content: viewMenu({showPrivateViewsInSubMenu, showGlobalViewsInSubMenu}),
|
|
76
|
+
placement: 'bottom-start',
|
|
77
|
+
popoverClassName: 'xh-view-manager__popover'
|
|
78
|
+
});
|
|
66
79
|
return fragment(
|
|
67
80
|
hbox({
|
|
68
81
|
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
|
-
]
|
|
82
|
+
items: buttonSide == 'left' ? [revert, save, menu] : [menu, save, revert]
|
|
85
83
|
}),
|
|
86
|
-
manageDialog({
|
|
87
|
-
|
|
88
|
-
onClose: () => model.closeManageDialog()
|
|
89
|
-
}),
|
|
90
|
-
saveDialog()
|
|
84
|
+
manageDialog({omit: !model.manageDialogOpen}),
|
|
85
|
+
saveAsDialog()
|
|
91
86
|
);
|
|
92
87
|
}
|
|
93
88
|
});
|
|
94
89
|
|
|
95
90
|
const menuButton = hoistCmp.factory<ViewManagerModel>({
|
|
96
91
|
render({model, ...rest}) {
|
|
97
|
-
const {
|
|
92
|
+
const {view, typeDisplayName, isLoading} = model;
|
|
98
93
|
return button({
|
|
99
94
|
className: 'xh-view-manager__menu-button',
|
|
100
|
-
text:
|
|
101
|
-
icon:
|
|
95
|
+
text: view.info?.name ?? `Default ${startCase(typeDisplayName)}`,
|
|
96
|
+
icon: !isLoading
|
|
97
|
+
? Icon.bookmark()
|
|
98
|
+
: box({
|
|
99
|
+
item: spinner({width: 13, height: 13, style: {margin: 'auto'}}),
|
|
100
|
+
width: 16.25
|
|
101
|
+
}),
|
|
102
102
|
rightIcon: Icon.chevronDown(),
|
|
103
103
|
outlined: true,
|
|
104
104
|
...rest
|
|
@@ -112,11 +112,11 @@ const saveButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
112
112
|
return button({
|
|
113
113
|
className: 'xh-view-manager__save-button',
|
|
114
114
|
icon: Icon.save(),
|
|
115
|
-
tooltip: `Save changes to this ${model.
|
|
115
|
+
tooltip: `Save changes to this ${model.typeDisplayName}`,
|
|
116
116
|
intent: 'primary',
|
|
117
|
-
disabled: !model.
|
|
117
|
+
disabled: !model.isValueDirty || model.isLoading,
|
|
118
118
|
onClick: () => {
|
|
119
|
-
model.
|
|
119
|
+
model.isViewSavable ? model.saveAsync() : model.saveAsAsync();
|
|
120
120
|
},
|
|
121
121
|
...rest
|
|
122
122
|
});
|
|
@@ -129,9 +129,9 @@ const revertButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
129
129
|
return button({
|
|
130
130
|
className: 'xh-view-manager__revert-button',
|
|
131
131
|
icon: Icon.reset(),
|
|
132
|
-
tooltip: `Revert changes to this ${model.
|
|
132
|
+
tooltip: `Revert changes to this ${model.typeDisplayName}`,
|
|
133
133
|
intent: 'danger',
|
|
134
|
-
disabled: !model.
|
|
134
|
+
disabled: !model.isValueDirty || model.isLoading,
|
|
135
135
|
onClick: () => model.resetAsync(),
|
|
136
136
|
...rest
|
|
137
137
|
});
|
|
@@ -139,183 +139,7 @@ const revertButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
139
139
|
});
|
|
140
140
|
|
|
141
141
|
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
|
-
}
|
|
142
|
+
return (
|
|
143
|
+
mode === 'never' || (mode === 'whenDirty' && !model.isValueDirty) || model.isViewAutoSavable
|
|
144
|
+
);
|
|
295
145
|
}
|
|
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
|
-
});
|