@xh/hoist 71.0.0-SNAPSHOT.1733372979467 → 71.0.0-SNAPSHOT.1733425883722
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/build/types/cmp/viewmanager/View.d.ts +7 -3
- package/build/types/cmp/viewmanager/ViewInfo.d.ts +1 -1
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +4 -4
- package/build/types/cmp/viewmanager/ViewToBlobApi.d.ts +3 -1
- package/cmp/viewmanager/SaveAsDialogModel.ts +1 -1
- package/cmp/viewmanager/View.ts +22 -7
- package/cmp/viewmanager/ViewInfo.ts +1 -1
- package/cmp/viewmanager/ViewManagerModel.ts +51 -51
- package/cmp/viewmanager/ViewToBlobApi.ts +41 -6
- package/desktop/cmp/viewmanager/ViewManager.ts +1 -1
- package/desktop/cmp/viewmanager/ViewMenu.ts +1 -1
- package/desktop/cmp/viewmanager/dialog/ManageDialogModel.ts +1 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -17,12 +17,16 @@ export declare class View<T extends PlainObject = PlainObject> {
|
|
|
17
17
|
* state of the components is captured.
|
|
18
18
|
*/
|
|
19
19
|
readonly value: Partial<T>;
|
|
20
|
+
private readonly model;
|
|
21
|
+
get name(): string;
|
|
22
|
+
get token(): string;
|
|
23
|
+
get type(): string;
|
|
20
24
|
get isDefault(): boolean;
|
|
21
25
|
get isGlobal(): boolean;
|
|
22
26
|
get lastUpdated(): number;
|
|
23
|
-
get
|
|
27
|
+
get typedName(): string;
|
|
24
28
|
static fromBlob<T>(blob: JsonBlob, model: ViewManagerModel): View<T>;
|
|
25
|
-
static createDefault<T>(): View<T>;
|
|
29
|
+
static createDefault<T>(model: ViewManagerModel): View<T>;
|
|
26
30
|
withUpdatedValue(value: Partial<T>): View<T>;
|
|
27
|
-
constructor(info: ViewInfo, value: Partial<T
|
|
31
|
+
constructor(info: ViewInfo, value: Partial<T>, model: ViewManagerModel);
|
|
28
32
|
}
|
|
@@ -6,7 +6,7 @@ import { JsonBlob } from '@xh/hoist/svc';
|
|
|
6
6
|
export declare class ViewInfo {
|
|
7
7
|
/** Unique Id */
|
|
8
8
|
readonly token: string;
|
|
9
|
-
/** App-defined type discriminator, as per {@link ViewManagerConfig.
|
|
9
|
+
/** App-defined type discriminator, as per {@link ViewManagerConfig.type}. */
|
|
10
10
|
readonly type: string;
|
|
11
11
|
/** User-supplied descriptive name. */
|
|
12
12
|
readonly name: string;
|
|
@@ -47,10 +47,10 @@ export interface ViewManagerConfig {
|
|
|
47
47
|
* different viewManagers to be added to your app in the future - e.g. `portfolioGridView` or
|
|
48
48
|
* `tradeBlotterDashboard`.
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
type: string;
|
|
51
51
|
/**
|
|
52
52
|
* Optional user-facing display name for the view type, displayed in the ViewManager menu
|
|
53
|
-
* and associated management dialogs and prompts. Defaulted from `
|
|
53
|
+
* and associated management dialogs and prompts. Defaulted from `type` if not provided.
|
|
54
54
|
*/
|
|
55
55
|
typeDisplayName?: string;
|
|
56
56
|
/**
|
|
@@ -96,7 +96,7 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
96
96
|
static createAsync(config: ViewManagerConfig): Promise<ViewManagerModel>;
|
|
97
97
|
/** Immutable configuration for this model. */
|
|
98
98
|
persistWith: ViewManagerPersistOptions;
|
|
99
|
-
readonly
|
|
99
|
+
readonly type: string;
|
|
100
100
|
readonly typeDisplayName: string;
|
|
101
101
|
readonly globalDisplayName: string;
|
|
102
102
|
readonly enableAutoSave: boolean;
|
|
@@ -156,7 +156,6 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
156
156
|
* initial load before binding to persistable components.
|
|
157
157
|
*/
|
|
158
158
|
private constructor();
|
|
159
|
-
private initAsync;
|
|
160
159
|
doLoadAsync(loadSpec: LoadSpec): Promise<void>;
|
|
161
160
|
selectViewAsync(info: ViewInfo): Promise<void>;
|
|
162
161
|
saveAsync(): Promise<void>;
|
|
@@ -171,6 +170,7 @@ export declare class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
171
170
|
openManageDialog(): void;
|
|
172
171
|
closeManageDialog(): void;
|
|
173
172
|
validateViewNameAsync(name: string, existing?: ViewInfo): Promise<string>;
|
|
173
|
+
private initAsync;
|
|
174
174
|
private loadViewAsync;
|
|
175
175
|
private maybeAutoSaveAsync;
|
|
176
176
|
private setAsView;
|
|
@@ -13,6 +13,8 @@ export declare class ViewToBlobApi<T> {
|
|
|
13
13
|
fetchViewInfosAsync(): Promise<ViewInfo[]>;
|
|
14
14
|
fetchViewAsync(info: ViewInfo): Promise<View<T>>;
|
|
15
15
|
createViewAsync(name: string, description: string, value: PlainObject): Promise<View<T>>;
|
|
16
|
-
|
|
16
|
+
updateViewInfoAsync(view: ViewInfo, name: string, description: string, isGlobal: boolean): Promise<View<T>>;
|
|
17
|
+
updateViewValueAsync(view: View<T>, value: Partial<T>): Promise<View<T>>;
|
|
17
18
|
deleteViewAsync(view: ViewInfo): Promise<void>;
|
|
19
|
+
private trackChange;
|
|
18
20
|
}
|
package/cmp/viewmanager/View.ts
CHANGED
|
@@ -21,6 +21,20 @@ export class View<T extends PlainObject = PlainObject> {
|
|
|
21
21
|
*/
|
|
22
22
|
readonly value: Partial<T> = null;
|
|
23
23
|
|
|
24
|
+
private readonly model: ViewManagerModel;
|
|
25
|
+
|
|
26
|
+
get name(): string {
|
|
27
|
+
return this.info?.name ?? 'Default';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get token(): string {
|
|
31
|
+
return this.info?.token ?? null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get type(): string {
|
|
35
|
+
return this.model.type;
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
get isDefault(): boolean {
|
|
25
39
|
return !this.info;
|
|
26
40
|
}
|
|
@@ -33,24 +47,25 @@ export class View<T extends PlainObject = PlainObject> {
|
|
|
33
47
|
return this.info?.lastUpdated ?? null;
|
|
34
48
|
}
|
|
35
49
|
|
|
36
|
-
get
|
|
37
|
-
return this.
|
|
50
|
+
get typedName(): string {
|
|
51
|
+
return `${this.model.typeDisplayName} '${this.name}'`;
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
static fromBlob<T>(blob: JsonBlob, model: ViewManagerModel): View<T> {
|
|
41
|
-
return new View(new ViewInfo(blob, model), blob.value);
|
|
55
|
+
return new View(new ViewInfo(blob, model), blob.value, model);
|
|
42
56
|
}
|
|
43
57
|
|
|
44
|
-
static createDefault<T>(): View<T> {
|
|
45
|
-
return new View(null, {});
|
|
58
|
+
static createDefault<T>(model: ViewManagerModel): View<T> {
|
|
59
|
+
return new View(null, {}, model);
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
withUpdatedValue(value: Partial<T>): View<T> {
|
|
49
|
-
return new View(this.info, value);
|
|
63
|
+
return new View(this.info, value, this.model);
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
constructor(info: ViewInfo, value: Partial<T
|
|
66
|
+
constructor(info: ViewInfo, value: Partial<T>, model: ViewManagerModel) {
|
|
53
67
|
this.info = info;
|
|
54
68
|
this.value = value;
|
|
69
|
+
this.model = model;
|
|
55
70
|
}
|
|
56
71
|
}
|
|
@@ -9,7 +9,7 @@ export class ViewInfo {
|
|
|
9
9
|
/** Unique Id */
|
|
10
10
|
readonly token: string;
|
|
11
11
|
|
|
12
|
-
/** App-defined type discriminator, as per {@link ViewManagerConfig.
|
|
12
|
+
/** App-defined type discriminator, as per {@link ViewManagerConfig.type}. */
|
|
13
13
|
readonly type: string;
|
|
14
14
|
|
|
15
15
|
/** User-supplied descriptive name. */
|
|
@@ -82,11 +82,11 @@ export interface ViewManagerConfig {
|
|
|
82
82
|
* different viewManagers to be added to your app in the future - e.g. `portfolioGridView` or
|
|
83
83
|
* `tradeBlotterDashboard`.
|
|
84
84
|
*/
|
|
85
|
-
|
|
85
|
+
type: string;
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
88
|
* Optional user-facing display name for the view type, displayed in the ViewManager menu
|
|
89
|
-
* and associated management dialogs and prompts. Defaulted from `
|
|
89
|
+
* and associated management dialogs and prompts. Defaulted from `type` if not provided.
|
|
90
90
|
*/
|
|
91
91
|
typeDisplayName?: string;
|
|
92
92
|
|
|
@@ -141,7 +141,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
141
141
|
|
|
142
142
|
/** Immutable configuration for this model. */
|
|
143
143
|
declare persistWith: ViewManagerPersistOptions;
|
|
144
|
-
readonly
|
|
144
|
+
readonly type: string;
|
|
145
145
|
readonly typeDisplayName: string;
|
|
146
146
|
readonly globalDisplayName: string;
|
|
147
147
|
readonly enableAutoSave: boolean;
|
|
@@ -250,7 +250,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
250
250
|
* initial load before binding to persistable components.
|
|
251
251
|
*/
|
|
252
252
|
private constructor({
|
|
253
|
-
|
|
253
|
+
type,
|
|
254
254
|
persistWith,
|
|
255
255
|
typeDisplayName,
|
|
256
256
|
globalDisplayName = 'global',
|
|
@@ -269,8 +269,8 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
269
269
|
"ViewManagerModel requires 'initialViewSpec' if `enableDefault` is false."
|
|
270
270
|
);
|
|
271
271
|
|
|
272
|
-
this.
|
|
273
|
-
this.typeDisplayName = lowerCase(typeDisplayName ?? genDisplayName(
|
|
272
|
+
this.type = type;
|
|
273
|
+
this.typeDisplayName = lowerCase(typeDisplayName ?? genDisplayName(type));
|
|
274
274
|
this.globalDisplayName = globalDisplayName;
|
|
275
275
|
this.persistWith = persistWith;
|
|
276
276
|
this.manageGlobal = executeIfFunction(manageGlobal) ?? false;
|
|
@@ -291,34 +291,6 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
291
291
|
this.api = new ViewToBlobApi(this);
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
private async initAsync() {
|
|
295
|
-
try {
|
|
296
|
-
const views = await this.api.fetchViewInfosAsync();
|
|
297
|
-
runInAction(() => (this.views = views));
|
|
298
|
-
|
|
299
|
-
if (this.persistWith) {
|
|
300
|
-
this.initPersist(this.persistWith);
|
|
301
|
-
await when(() => !this.selectTask.isPending);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// If the initial view not initialized from persistence, assign it.
|
|
305
|
-
if (!this.view) {
|
|
306
|
-
await this.loadViewAsync(this.initialViewSpec?.(views), this.pendingValue);
|
|
307
|
-
}
|
|
308
|
-
} catch (e) {
|
|
309
|
-
// Always ensure at least default view is installed.
|
|
310
|
-
if (!this.view) this.loadViewAsync(null, this.pendingValue);
|
|
311
|
-
|
|
312
|
-
this.handleException(e, {showAlert: false, logOnServer: true});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
this.addReaction({
|
|
316
|
-
track: () => [this.pendingValue, this.autoSave],
|
|
317
|
-
run: () => this.maybeAutoSaveAsync(),
|
|
318
|
-
debounce: 5 * SECONDS
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
|
|
322
294
|
override async doLoadAsync(loadSpec: LoadSpec) {
|
|
323
295
|
try {
|
|
324
296
|
// 1) Update all view info
|
|
@@ -358,21 +330,20 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
358
330
|
this.logError('Unexpected conditions for call to save, skipping');
|
|
359
331
|
return;
|
|
360
332
|
}
|
|
361
|
-
const {pendingValue} = this
|
|
362
|
-
{info} = this.view;
|
|
333
|
+
const {pendingValue, view, api} = this;
|
|
363
334
|
try {
|
|
364
|
-
if (!(await this.maybeConfirmSaveAsync(
|
|
335
|
+
if (!(await this.maybeConfirmSaveAsync(view, pendingValue))) {
|
|
365
336
|
return;
|
|
366
337
|
}
|
|
367
|
-
const
|
|
368
|
-
.
|
|
338
|
+
const updated = await api
|
|
339
|
+
.updateViewValueAsync(view, pendingValue.value)
|
|
369
340
|
.linkTo(this.saveTask);
|
|
370
341
|
|
|
371
|
-
this.setAsView(
|
|
372
|
-
this.noteSuccess(`Saved ${
|
|
342
|
+
this.setAsView(updated);
|
|
343
|
+
this.noteSuccess(`Saved ${view.typedName}`);
|
|
373
344
|
} catch (e) {
|
|
374
345
|
this.handleException(e, {
|
|
375
|
-
message: `Failed to save ${
|
|
346
|
+
message: `Failed to save ${view.typedName}. If this persists consider \`Save As...\`.`
|
|
376
347
|
});
|
|
377
348
|
}
|
|
378
349
|
this.refreshAsync();
|
|
@@ -382,7 +353,7 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
382
353
|
const view = (await this.saveAsDialogModel.openAsync()) as View<T>;
|
|
383
354
|
if (view) {
|
|
384
355
|
this.setAsView(view);
|
|
385
|
-
this.noteSuccess(`Saved ${view.
|
|
356
|
+
this.noteSuccess(`Saved ${view.typedName}`);
|
|
386
357
|
}
|
|
387
358
|
this.refreshAsync();
|
|
388
359
|
}
|
|
@@ -468,6 +439,34 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
468
439
|
//------------------
|
|
469
440
|
// Implementation
|
|
470
441
|
//------------------
|
|
442
|
+
private async initAsync() {
|
|
443
|
+
try {
|
|
444
|
+
const views = await this.api.fetchViewInfosAsync();
|
|
445
|
+
runInAction(() => (this.views = views));
|
|
446
|
+
|
|
447
|
+
if (this.persistWith) {
|
|
448
|
+
this.initPersist(this.persistWith);
|
|
449
|
+
await when(() => !this.selectTask.isPending);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// If the initial view not initialized from persistence, assign it.
|
|
453
|
+
if (!this.view) {
|
|
454
|
+
await this.loadViewAsync(this.initialViewSpec?.(views), this.pendingValue);
|
|
455
|
+
}
|
|
456
|
+
} catch (e) {
|
|
457
|
+
// Always ensure at least default view is installed.
|
|
458
|
+
if (!this.view) this.loadViewAsync(null, this.pendingValue);
|
|
459
|
+
|
|
460
|
+
this.handleException(e, {showAlert: false, logOnServer: true});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
this.addReaction({
|
|
464
|
+
track: () => [this.pendingValue, this.autoSave],
|
|
465
|
+
run: () => this.maybeAutoSaveAsync(),
|
|
466
|
+
debounce: 5 * SECONDS
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
471
470
|
private async loadViewAsync(
|
|
472
471
|
info: ViewInfo,
|
|
473
472
|
pendingValue: PendingValue<T> = null
|
|
@@ -483,18 +482,19 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
483
482
|
}
|
|
484
483
|
|
|
485
484
|
private async maybeAutoSaveAsync() {
|
|
486
|
-
const {pendingValue, isViewAutoSavable, view} = this;
|
|
485
|
+
const {pendingValue, isViewAutoSavable, view, api} = this;
|
|
487
486
|
if (isViewAutoSavable && pendingValue) {
|
|
488
487
|
try {
|
|
489
|
-
const
|
|
490
|
-
.
|
|
488
|
+
const updated = await api
|
|
489
|
+
.updateViewValueAsync(view, pendingValue.value)
|
|
491
490
|
.linkTo(this.saveTask);
|
|
492
|
-
|
|
491
|
+
|
|
492
|
+
this.setAsView(updated);
|
|
493
493
|
} catch (e) {
|
|
494
494
|
// TODO: How to alert but avoid for flaky or spam when user editing a deleted view
|
|
495
495
|
// Keep count and alert server and user once at count n?
|
|
496
496
|
XH.handleException(e, {
|
|
497
|
-
message: `Failing AutoSave for ${
|
|
497
|
+
message: `Failing AutoSave for ${view.info.typedName}`,
|
|
498
498
|
showAlert: false,
|
|
499
499
|
logOnServer: false
|
|
500
500
|
});
|
|
@@ -542,16 +542,16 @@ export class ViewManagerModel<T = PlainObject> extends HoistModel {
|
|
|
542
542
|
});
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
-
private async maybeConfirmSaveAsync(
|
|
545
|
+
private async maybeConfirmSaveAsync(view: View, pendingValue: PendingValue<T>) {
|
|
546
546
|
// Get latest from server for reference
|
|
547
|
-
const latest = await this.api.fetchViewAsync(info),
|
|
547
|
+
const latest = await this.api.fetchViewAsync(view.info),
|
|
548
548
|
isGlobal = latest.isGlobal,
|
|
549
549
|
isStale = latest.lastUpdated > pendingValue.baseUpdated;
|
|
550
550
|
if (!isStale && !isGlobal) return true;
|
|
551
551
|
|
|
552
552
|
const latestInfo = latest.info,
|
|
553
553
|
{typeDisplayName, globalDisplayName} = this,
|
|
554
|
-
msgs: ReactNode[] = [`Save ${
|
|
554
|
+
msgs: ReactNode[] = [`Save ${view.typedName}?`];
|
|
555
555
|
if (isGlobal) {
|
|
556
556
|
msgs.push(
|
|
557
557
|
span(
|
|
@@ -30,7 +30,7 @@ export class ViewToBlobApi<T> {
|
|
|
30
30
|
const {owner} = this;
|
|
31
31
|
try {
|
|
32
32
|
const blobs = await XH.jsonBlobService.listAsync({
|
|
33
|
-
type: owner.
|
|
33
|
+
type: owner.type,
|
|
34
34
|
includeValue: false
|
|
35
35
|
});
|
|
36
36
|
return blobs.map(b => new ViewInfo(b, owner));
|
|
@@ -43,7 +43,7 @@ export class ViewToBlobApi<T> {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
async fetchViewAsync(info: ViewInfo): Promise<View<T>> {
|
|
46
|
-
if (!info) return View.createDefault();
|
|
46
|
+
if (!info) return View.createDefault(this.owner);
|
|
47
47
|
try {
|
|
48
48
|
const blob = await XH.jsonBlobService.getAsync(info.token);
|
|
49
49
|
return View.fromBlob(blob, this.owner);
|
|
@@ -59,34 +59,69 @@ export class ViewToBlobApi<T> {
|
|
|
59
59
|
const {owner} = this;
|
|
60
60
|
try {
|
|
61
61
|
const blob = await XH.jsonBlobService.createAsync({
|
|
62
|
-
type: owner.
|
|
62
|
+
type: owner.type,
|
|
63
63
|
name: name.trim(),
|
|
64
64
|
description: description?.trim(),
|
|
65
65
|
value
|
|
66
66
|
});
|
|
67
|
-
|
|
67
|
+
const ret = View.fromBlob(blob, owner);
|
|
68
|
+
this.trackChange('Created View', ret);
|
|
69
|
+
return ret;
|
|
68
70
|
} catch (e) {
|
|
69
71
|
throw XH.exception({message: `Unable to create ${owner.typeDisplayName}`, cause: e});
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
async
|
|
75
|
+
async updateViewInfoAsync(
|
|
76
|
+
view: ViewInfo,
|
|
77
|
+
name: string,
|
|
78
|
+
description: string,
|
|
79
|
+
isGlobal: boolean
|
|
80
|
+
): Promise<View<T>> {
|
|
74
81
|
try {
|
|
75
|
-
await XH.jsonBlobService.updateAsync(view.token, {
|
|
82
|
+
const blob = await XH.jsonBlobService.updateAsync(view.token, {
|
|
76
83
|
name: name.trim(),
|
|
77
84
|
description: description?.trim(),
|
|
78
85
|
acl: isGlobal ? '*' : null
|
|
79
86
|
});
|
|
87
|
+
const ret = View.fromBlob(blob, this.owner);
|
|
88
|
+
this.trackChange('Updated View Info', ret);
|
|
89
|
+
return ret;
|
|
80
90
|
} catch (e) {
|
|
81
91
|
throw XH.exception({message: `Unable to update ${view.typedName}`, cause: e});
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
|
|
95
|
+
async updateViewValueAsync(view: View<T>, value: Partial<T>): Promise<View<T>> {
|
|
96
|
+
try {
|
|
97
|
+
const blob = await XH.jsonBlobService.updateAsync(view.token, {value});
|
|
98
|
+
const ret = View.fromBlob(blob, this.owner);
|
|
99
|
+
if (ret.isGlobal) {
|
|
100
|
+
this.trackChange('Updated Global View definition', ret);
|
|
101
|
+
}
|
|
102
|
+
return ret;
|
|
103
|
+
} catch (e) {
|
|
104
|
+
throw XH.exception({
|
|
105
|
+
message: `Unable to update value for ${view.typedName}`,
|
|
106
|
+
cause: e
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
85
111
|
async deleteViewAsync(view: ViewInfo) {
|
|
86
112
|
try {
|
|
87
113
|
await XH.jsonBlobService.archiveAsync(view.token);
|
|
114
|
+
this.trackChange('Deleted View', view);
|
|
88
115
|
} catch (e) {
|
|
89
116
|
throw XH.exception({message: `Unable to delete ${view.typedName}`, cause: e});
|
|
90
117
|
}
|
|
91
118
|
}
|
|
119
|
+
|
|
120
|
+
private trackChange(message: string, v: View | ViewInfo) {
|
|
121
|
+
XH.track({
|
|
122
|
+
message,
|
|
123
|
+
category: 'Views',
|
|
124
|
+
data: {name: v.name, token: v.token, isGlobal: v.isGlobal, type: v.type}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
92
127
|
}
|
|
@@ -92,7 +92,7 @@ const menuButton = hoistCmp.factory<ViewManagerModel>({
|
|
|
92
92
|
const {view, typeDisplayName, isLoading} = model;
|
|
93
93
|
return button({
|
|
94
94
|
className: 'xh-view-manager__menu-button',
|
|
95
|
-
text: view.
|
|
95
|
+
text: view.isDefault ? `Default ${startCase(typeDisplayName)}` : view.name,
|
|
96
96
|
icon: !isLoading
|
|
97
97
|
? Icon.bookmark()
|
|
98
98
|
: box({
|
|
@@ -50,7 +50,7 @@ export const viewMenu = hoistCmp.factory<ViewManagerProps>({
|
|
|
50
50
|
...favoriteViews.map(info => {
|
|
51
51
|
return menuItem({
|
|
52
52
|
key: `${info.token}-favorite`,
|
|
53
|
-
icon: view.
|
|
53
|
+
icon: view.token === info.token ? Icon.check() : Icon.placeholder(),
|
|
54
54
|
text: textAndFaveToggle({info}),
|
|
55
55
|
onClick: () => model.selectViewAsync(info),
|
|
56
56
|
title: info.description
|
|
@@ -158,7 +158,7 @@ export class ManageDialogModel extends HoistModel {
|
|
|
158
158
|
) {
|
|
159
159
|
const {viewManagerModel} = this;
|
|
160
160
|
|
|
161
|
-
await viewManagerModel.api.
|
|
161
|
+
await viewManagerModel.api.updateViewInfoAsync(view, name, description, isGlobal);
|
|
162
162
|
await viewManagerModel.refreshAsync();
|
|
163
163
|
await this.refreshAsync();
|
|
164
164
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "71.0.0-SNAPSHOT.
|
|
3
|
+
"version": "71.0.0-SNAPSHOT.1733425883722",
|
|
4
4
|
"description": "Hoist add-on for building and deploying React Applications.",
|
|
5
5
|
"repository": "github:xh/hoist-react",
|
|
6
6
|
"homepage": "https://xh.io",
|