@xh/hoist 71.0.0-SNAPSHOT.1733198772915 → 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/chart/impl/copyToClipboard.d.ts +1 -2
- 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/chart/impl/copyToClipboard.ts +1 -2
- 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
|
@@ -0,0 +1,97 @@
|
|
|
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 {FormModel} from '@xh/hoist/cmp/form';
|
|
9
|
+
import {HoistModel, managed, XH} from '@xh/hoist/core';
|
|
10
|
+
import {makeObservable, action, observable} from '@xh/hoist/mobx';
|
|
11
|
+
import {View} from './View';
|
|
12
|
+
import {ViewManagerModel} from './ViewManagerModel';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Backing model for ViewManagerModel's SaveAs
|
|
16
|
+
*/
|
|
17
|
+
export class SaveAsDialogModel extends HoistModel {
|
|
18
|
+
readonly parent: ViewManagerModel;
|
|
19
|
+
|
|
20
|
+
@managed readonly formModel: FormModel;
|
|
21
|
+
@observable isOpen: boolean = false;
|
|
22
|
+
|
|
23
|
+
private resolveOpen: (value: View) => void;
|
|
24
|
+
|
|
25
|
+
get type(): string {
|
|
26
|
+
return this.parent.viewType;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get typeDisplayName(): string {
|
|
30
|
+
return this.parent.typeDisplayName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get globalDisplayName(): string {
|
|
34
|
+
return this.parent.globalDisplayName;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
constructor(parent: ViewManagerModel) {
|
|
38
|
+
super();
|
|
39
|
+
makeObservable(this);
|
|
40
|
+
this.parent = parent;
|
|
41
|
+
this.formModel = this.createFormModel();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@action
|
|
45
|
+
openAsync(): Promise<View> {
|
|
46
|
+
this.formModel.init(this.parent.view.info ?? {});
|
|
47
|
+
this.isOpen = true;
|
|
48
|
+
|
|
49
|
+
return new Promise(resolve => (this.resolveOpen = resolve));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
cancel() {
|
|
53
|
+
this.close();
|
|
54
|
+
this.resolveOpen(null);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async saveAsAsync() {
|
|
58
|
+
return this.doSaveAsAsync().linkTo(this.parent.saveTask);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//------------------------
|
|
62
|
+
// Implementation
|
|
63
|
+
//------------------------
|
|
64
|
+
private createFormModel(): FormModel {
|
|
65
|
+
return new FormModel({
|
|
66
|
+
fields: [
|
|
67
|
+
{
|
|
68
|
+
name: 'name',
|
|
69
|
+
rules: [({value}) => this.parent.validateViewNameAsync(value)]
|
|
70
|
+
},
|
|
71
|
+
{name: 'description'}
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async doSaveAsAsync() {
|
|
77
|
+
const {formModel, parent} = this,
|
|
78
|
+
{name, description} = formModel.getData(),
|
|
79
|
+
isValid = await formModel.validateAsync();
|
|
80
|
+
|
|
81
|
+
if (!isValid) return;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const ret = await this.parent.createViewAsync(name, description, parent.getValue());
|
|
85
|
+
this.close();
|
|
86
|
+
this.resolveOpen(ret);
|
|
87
|
+
} catch (e) {
|
|
88
|
+
XH.handleException(e);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@action
|
|
93
|
+
private close() {
|
|
94
|
+
this.isOpen = false;
|
|
95
|
+
this.formModel.init();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {PlainObject} from '@xh/hoist/core';
|
|
2
|
+
import {ViewManagerModel} from './ViewManagerModel';
|
|
3
|
+
import {ViewInfo} from './ViewInfo';
|
|
4
|
+
import {JsonBlob} from '@xh/hoist/svc';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A named saved bundle of state for components.
|
|
8
|
+
*/
|
|
9
|
+
export class View<T extends PlainObject = PlainObject> {
|
|
10
|
+
/**
|
|
11
|
+
* Default View representing code state of all contained components.
|
|
12
|
+
* Available for all view managers where `enableDefault` is true.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Metadata about this View. Null for 'default' view */
|
|
16
|
+
readonly info: ViewInfo;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* State for the components in the view. Only state that differs from the initial "code"
|
|
20
|
+
* state of the components is captured.
|
|
21
|
+
*/
|
|
22
|
+
readonly value: Partial<T> = null;
|
|
23
|
+
|
|
24
|
+
get isDefault(): boolean {
|
|
25
|
+
return !this.info;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get isGlobal(): boolean {
|
|
29
|
+
return this.info?.isGlobal ?? false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get lastUpdated(): number {
|
|
33
|
+
return this.info?.lastUpdated ?? null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get token(): string {
|
|
37
|
+
return this.info?.token ?? null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static fromBlob<T>(blob: JsonBlob, model: ViewManagerModel): View<T> {
|
|
41
|
+
return new View(new ViewInfo(blob, model), blob.value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static createDefault<T>(): View<T> {
|
|
45
|
+
return new View(null, {});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
withUpdatedValue(value: Partial<T>): View<T> {
|
|
49
|
+
return new View(this.info, value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
constructor(info: ViewInfo, value: Partial<T>) {
|
|
53
|
+
this.info = info;
|
|
54
|
+
this.value = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {SECONDS} from '@xh/hoist/utils/datetime';
|
|
2
|
+
import {ViewManagerModel} from './ViewManagerModel';
|
|
3
|
+
import {JsonBlob} from '@xh/hoist/svc';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Metadata describing {@link View} managed by {@link ViewManagerModel}.
|
|
7
|
+
*/
|
|
8
|
+
export class ViewInfo {
|
|
9
|
+
/** Unique Id */
|
|
10
|
+
readonly token: string;
|
|
11
|
+
|
|
12
|
+
/** App-defined type discriminator, as per {@link ViewManagerConfig.viewType}. */
|
|
13
|
+
readonly type: string;
|
|
14
|
+
|
|
15
|
+
/** User-supplied descriptive name. */
|
|
16
|
+
readonly name: string;
|
|
17
|
+
|
|
18
|
+
/** Description of the view. **/
|
|
19
|
+
readonly description: string;
|
|
20
|
+
|
|
21
|
+
/** True if this view is global and visible to all users. */
|
|
22
|
+
readonly isGlobal: boolean;
|
|
23
|
+
|
|
24
|
+
/** Original creator of the view, and the only user with access to it if not global. */
|
|
25
|
+
readonly owner: string;
|
|
26
|
+
|
|
27
|
+
dateCreated: number;
|
|
28
|
+
lastUpdated: number;
|
|
29
|
+
lastUpdatedBy: string;
|
|
30
|
+
|
|
31
|
+
private readonly model: ViewManagerModel;
|
|
32
|
+
|
|
33
|
+
constructor(blob: JsonBlob, model: ViewManagerModel) {
|
|
34
|
+
this.token = blob.token;
|
|
35
|
+
this.type = blob.type;
|
|
36
|
+
this.owner = blob.owner;
|
|
37
|
+
this.name = blob.name;
|
|
38
|
+
this.description = blob.description;
|
|
39
|
+
this.isGlobal = blob.acl === '*';
|
|
40
|
+
// Round to seconds. See: https://github.com/xh/hoist-core/issues/423
|
|
41
|
+
this.dateCreated = Math.round(blob.dateCreated / SECONDS) * SECONDS;
|
|
42
|
+
this.lastUpdated = Math.round(blob.lastUpdated / SECONDS) * SECONDS;
|
|
43
|
+
this.lastUpdatedBy = blob.lastUpdatedBy;
|
|
44
|
+
this.model = model;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* True if user has tagged this view as a favorite. Note that a user's list of favorite views
|
|
49
|
+
* is persisted via `ViewManagerModel.persistWith` and *not* stored in the blob itself.
|
|
50
|
+
*/
|
|
51
|
+
get isFavorite(): boolean {
|
|
52
|
+
return this.model.isFavorite(this.token);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get typedName(): string {
|
|
56
|
+
return `${this.model.typeDisplayName} '${this.name}'`;
|
|
57
|
+
}
|
|
58
|
+
}
|