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

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 (93) hide show
  1. package/CHANGELOG.md +54 -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/svc/GridAutosizeService.d.ts +2 -5
  42. package/build/types/svc/JsonBlobService.d.ts +45 -24
  43. package/cmp/filter/FilterChooserModel.ts +142 -125
  44. package/cmp/grid/Grid.ts +2 -10
  45. package/cmp/grid/GridModel.ts +18 -31
  46. package/cmp/grid/Types.ts +7 -21
  47. package/cmp/grid/columns/Column.ts +0 -1
  48. package/cmp/grid/impl/InitPersist.ts +71 -0
  49. package/cmp/grouping/GroupingChooserModel.ts +48 -57
  50. package/cmp/tab/TabContainerModel.ts +22 -36
  51. package/cmp/zoneGrid/Types.ts +6 -6
  52. package/cmp/zoneGrid/ZoneGridModel.ts +2 -7
  53. package/cmp/zoneGrid/impl/InitPersist.ts +70 -0
  54. package/core/HoistBase.ts +14 -22
  55. package/core/HoistBaseDecorators.ts +26 -28
  56. package/core/persist/CustomProvider.ts +7 -10
  57. package/core/persist/DashViewProvider.ts +8 -10
  58. package/core/persist/LocalStorageProvider.ts +9 -12
  59. package/core/persist/PersistOptions.ts +6 -4
  60. package/core/persist/Persistable.ts +23 -0
  61. package/core/persist/PersistenceProvider.ts +159 -79
  62. package/core/persist/PrefProvider.ts +9 -12
  63. package/core/persist/index.ts +2 -0
  64. package/core/persist/viewmanager/Types.ts +51 -0
  65. package/core/persist/viewmanager/ViewManagerModel.ts +515 -0
  66. package/core/persist/viewmanager/ViewManagerProvider.ts +51 -0
  67. package/core/persist/viewmanager/impl/ManageDialogModel.ts +274 -0
  68. package/core/persist/viewmanager/impl/SaveDialogModel.ts +112 -0
  69. package/core/persist/viewmanager/index.ts +2 -0
  70. package/desktop/cmp/button/ColAutosizeButton.ts +1 -1
  71. package/desktop/cmp/dash/DashConfig.ts +3 -1
  72. package/desktop/cmp/dash/DashModel.ts +1 -2
  73. package/desktop/cmp/dash/DashViewSpec.ts +1 -1
  74. package/desktop/cmp/dash/canvas/DashCanvasModel.ts +31 -30
  75. package/desktop/cmp/dash/container/DashContainerModel.ts +68 -43
  76. package/desktop/cmp/dash/container/impl/DashContainerUtils.ts +13 -4
  77. package/desktop/cmp/leftrightchooser/LeftRightChooserFilter.ts +1 -1
  78. package/desktop/cmp/panel/PanelModel.ts +33 -53
  79. package/desktop/cmp/store/impl/StoreFilterField.ts +1 -1
  80. package/desktop/cmp/viewmanager/ViewManager.scss +58 -0
  81. package/desktop/cmp/viewmanager/ViewManager.ts +274 -0
  82. package/desktop/cmp/viewmanager/cmp/ManageDialog.ts +197 -0
  83. package/desktop/cmp/viewmanager/cmp/SaveDialog.ts +89 -0
  84. package/desktop/cmp/viewmanager/index.ts +3 -0
  85. package/mobile/cmp/button/ColAutosizeButton.ts +1 -1
  86. package/package.json +1 -1
  87. package/svc/GridAutosizeService.ts +73 -36
  88. package/svc/JsonBlobService.ts +64 -31
  89. package/tsconfig.tsbuildinfo +1 -1
  90. package/build/types/cmp/grid/impl/GridPersistenceModel.d.ts +0 -41
  91. package/build/types/cmp/zoneGrid/impl/ZoneGridPersistenceModel.d.ts +0 -39
  92. package/cmp/grid/impl/GridPersistenceModel.ts +0 -174
  93. package/cmp/zoneGrid/impl/ZoneGridPersistenceModel.ts +0 -149
@@ -0,0 +1,274 @@
1
+ import {div, filler, fragment, hbox, span} from '@xh/hoist/cmp/layout';
2
+ import {hoistCmp, HoistProps, uses} from '@xh/hoist/core';
3
+ import './ViewManager.scss';
4
+ import {ViewTree} from '@xh/hoist/core/persist/viewmanager';
5
+ import {ViewManagerModel} from '@xh/hoist/core/persist/viewmanager/ViewManagerModel';
6
+ import {button, ButtonProps} from '@xh/hoist/desktop/cmp/button';
7
+ import {switchInput} from '@xh/hoist/desktop/cmp/input';
8
+ import {manageDialog} from '@xh/hoist/desktop/cmp/viewmanager/cmp/ManageDialog';
9
+ import {saveDialog} from '@xh/hoist/desktop/cmp/viewmanager/cmp/SaveDialog';
10
+ import {Icon} from '@xh/hoist/icon';
11
+ import {menu, menuDivider, menuItem, popover} from '@xh/hoist/kit/blueprint';
12
+ import {consumeEvent, pluralize} from '@xh/hoist/utils/js';
13
+ import {isEmpty} from 'lodash';
14
+ import {ReactNode} from 'react';
15
+
16
+ export interface ViewManagerProps extends HoistProps<ViewManagerModel> {
17
+ menuButtonProps?: Partial<ButtonProps>;
18
+ saveButtonProps?: Partial<ButtonProps>;
19
+ /** 'whenDirty' to only show saveButton when persistence state is dirty. (Default 'whenDirty') */
20
+ showSaveButton?: 'whenDirty' | 'always' | 'never';
21
+ /** True to render private views in sub-menu (Default false)*/
22
+ showPrivateViewsInSubMenu?: boolean;
23
+ /** True to render shared views in sub-menu (Default false)*/
24
+ showSharedViewsInSubMenu?: boolean;
25
+ }
26
+
27
+ /**
28
+ * Desktop ViewManager component - a button-based menu for saving and swapping between named
29
+ * bundles of persisted component state (eg grid views, dashboards, and similar).
30
+ *
31
+ * See {@link ViewManagerModel} for additional details and configuration options.
32
+ */
33
+ export const [ViewManager, viewManager] = hoistCmp.withFactory<ViewManagerProps>({
34
+ displayName: 'ViewManager',
35
+ className: 'xh-view-manager',
36
+ model: uses(ViewManagerModel),
37
+
38
+ render({
39
+ model,
40
+ className,
41
+ menuButtonProps,
42
+ saveButtonProps,
43
+ showSaveButton = 'whenDirty',
44
+ showPrivateViewsInSubMenu = false,
45
+ showSharedViewsInSubMenu = false
46
+ }: ViewManagerProps) {
47
+ return fragment(
48
+ hbox({
49
+ className,
50
+ items: [
51
+ popover({
52
+ item: menuButton(menuButtonProps),
53
+ content: viewMenu({showPrivateViewsInSubMenu, showSharedViewsInSubMenu}),
54
+ placement: 'bottom-start',
55
+ popoverClassName: 'xh-view-manager__popover'
56
+ }),
57
+ saveButton({
58
+ showSaveButton,
59
+ ...saveButtonProps
60
+ })
61
+ ]
62
+ }),
63
+ manageDialog({
64
+ omit: !model.manageDialogOpen,
65
+ onClose: () => model.closeManageDialog()
66
+ }),
67
+ saveDialog()
68
+ );
69
+ }
70
+ });
71
+
72
+ const menuButton = hoistCmp.factory<ViewManagerModel>({
73
+ render({model, ...rest}) {
74
+ const {selectedView, DisplayName} = model;
75
+ return button({
76
+ className: 'xh-view-manager__menu-button',
77
+ text: model.getHierarchyDisplayName(selectedView?.name) ?? `Default ${DisplayName}`,
78
+ icon: Icon.bookmark(),
79
+ rightIcon: Icon.chevronDown(),
80
+ outlined: true,
81
+ ...rest
82
+ });
83
+ }
84
+ });
85
+
86
+ const saveButton = hoistCmp.factory<ViewManagerModel>({
87
+ render({model, showSaveButton, ...rest}) {
88
+ if (
89
+ !model.canShowSaveButton ||
90
+ showSaveButton === 'never' ||
91
+ (showSaveButton === 'whenDirty' && !model.isDirty)
92
+ ) {
93
+ return null;
94
+ }
95
+
96
+ return button({
97
+ className: 'xh-view-manager__save-button',
98
+ icon: Icon.save(),
99
+ tooltip: `Save changes to this ${model.displayName}`,
100
+ intent: 'primary',
101
+ disabled: !model.canSave,
102
+ onClick: () => model.saveAsync(false).linkTo(model.loadModel),
103
+ ...rest
104
+ });
105
+ }
106
+ });
107
+
108
+ const viewMenu = hoistCmp.factory<ViewManagerProps>({
109
+ render({model, showPrivateViewsInSubMenu, showSharedViewsInSubMenu}) {
110
+ const {DisplayName} = model,
111
+ pluralDisp = pluralize(DisplayName),
112
+ items = [];
113
+
114
+ if (!isEmpty(model.favoriteViews)) {
115
+ items.push(
116
+ menuDivider({title: 'Favorites'}),
117
+ ...model.favoriteViews.map(it => {
118
+ return menuItem({
119
+ key: `${it.token}-favorite`,
120
+ icon: model.selectedToken === it.token ? Icon.check() : Icon.placeholder(),
121
+ text: menuItemTextAndFaveToggle({
122
+ view: {...it, text: model.getHierarchyDisplayName(it.name)}
123
+ }),
124
+ onClick: () => model.selectViewAsync(it.token).linkTo(model.loadModel),
125
+ title: it.description
126
+ });
127
+ })
128
+ );
129
+ }
130
+
131
+ if (!isEmpty(model.privateViewTree)) {
132
+ if (showPrivateViewsInSubMenu) {
133
+ items.push(
134
+ menuDivider({omit: isEmpty(items)}),
135
+ menuItem({
136
+ text: `My ${pluralDisp}`,
137
+ shouldDismissPopover: false,
138
+ children: model.privateViewTree.map(it => {
139
+ return buildMenuItem(it, model);
140
+ })
141
+ })
142
+ );
143
+ } else {
144
+ items.push(
145
+ menuDivider({title: `My ${pluralDisp}`}),
146
+ ...model.privateViewTree.map(it => buildMenuItem(it, model))
147
+ );
148
+ }
149
+ }
150
+
151
+ if (!isEmpty(model.sharedViewTree)) {
152
+ if (showSharedViewsInSubMenu) {
153
+ items.push(
154
+ menuDivider({omit: isEmpty(items)}),
155
+ menuItem({
156
+ text: `Shared ${pluralDisp}`,
157
+ shouldDismissPopover: false,
158
+ children: model.sharedViewTree.map(it => {
159
+ return buildMenuItem(it, model);
160
+ })
161
+ })
162
+ );
163
+ } else {
164
+ items.push(
165
+ menuDivider({title: `Shared ${pluralDisp}`}),
166
+ ...model.sharedViewTree.map(it => buildMenuItem(it, model))
167
+ );
168
+ }
169
+ }
170
+
171
+ return menu({
172
+ className: 'xh-view-manager__menu',
173
+ items: [
174
+ ...items,
175
+ menuDivider({omit: !model.enableDefault || isEmpty(items)}),
176
+ menuItem({
177
+ icon: model.selectedToken ? Icon.placeholder() : Icon.check(),
178
+ text: `Default ${DisplayName}`,
179
+ omit: !model.enableDefault,
180
+ onClick: () => model.selectViewAsync(null)
181
+ }),
182
+ menuDivider(),
183
+ menuItem({
184
+ icon: Icon.save(),
185
+ text: 'Save',
186
+ disabled: !model.canSave,
187
+ onClick: () => model.saveAsync(false)
188
+ }),
189
+ menuItem({
190
+ icon: Icon.copy(),
191
+ text: 'Save as...',
192
+ onClick: () => model.saveAsAsync()
193
+ }),
194
+ menuItem({
195
+ icon: Icon.reset(),
196
+ text: `Revert ${DisplayName}`,
197
+ disabled: !model.isDirty,
198
+ onClick: () => model.resetAsync()
199
+ }),
200
+ menuDivider({omit: !model.enableAutoSave}),
201
+ menuItem({
202
+ omit: !model.enableAutoSave,
203
+ text: switchInput({
204
+ label: 'Auto Save',
205
+ bind: 'autoSaveActive',
206
+ inline: true,
207
+ disabled: !model.enableAutoSaveToggle
208
+ }),
209
+ title: model.disabledAutoSaveReason,
210
+ shouldDismissPopover: false
211
+ }),
212
+ menuDivider(),
213
+ menuItem({
214
+ icon: Icon.gear(),
215
+ disabled: isEmpty(model.views),
216
+ text: `Manage ${pluralDisp}...`,
217
+ onClick: () => model.openManageDialog()
218
+ })
219
+ ]
220
+ });
221
+ }
222
+ });
223
+
224
+ function buildMenuItem(viewOrFolder: ViewTree, model: ViewManagerModel): ReactNode {
225
+ const {type, text, selected} = viewOrFolder,
226
+ icon = selected ? Icon.check() : Icon.placeholder();
227
+
228
+ switch (type) {
229
+ case 'folder':
230
+ return menuItem({
231
+ text,
232
+ icon,
233
+ shouldDismissPopover: false,
234
+ children: viewOrFolder.items
235
+ ? viewOrFolder.items.map(child => buildMenuItem(child, model))
236
+ : []
237
+ });
238
+ case 'view':
239
+ return menuItem({
240
+ className: 'xh-view-manager__menu-item',
241
+ key: viewOrFolder.token,
242
+ icon,
243
+ text: menuItemTextAndFaveToggle({model, view: viewOrFolder}),
244
+ title: viewOrFolder.description,
245
+ onClick: () => model.selectViewAsync(viewOrFolder.token).linkTo(model.loadModel)
246
+ });
247
+ }
248
+ }
249
+
250
+ const menuItemTextAndFaveToggle = hoistCmp.factory<ViewManagerModel>({
251
+ render({model, view}) {
252
+ const isFavorite = model.isFavorite(view.token);
253
+ return hbox({
254
+ alignItems: 'center',
255
+ items: [
256
+ span({style: {paddingRight: 5}, item: view.text}),
257
+ fragment({
258
+ omit: !model.enableFavorites,
259
+ items: [
260
+ filler(),
261
+ div({
262
+ className: `xh-view-manager__menu-item__fave-toggle ${isFavorite ? 'xh-view-manager__menu-item__fave-toggle--active' : ''}`,
263
+ item: Icon.favorite({prefix: isFavorite ? 'fas' : 'far'}),
264
+ onClick: e => {
265
+ consumeEvent(e);
266
+ model.toggleFavorite(view.token);
267
+ }
268
+ })
269
+ ]
270
+ })
271
+ ]
272
+ });
273
+ }
274
+ });
@@ -0,0 +1,197 @@
1
+ import {form} from '@xh/hoist/cmp/form';
2
+ import {grid} from '@xh/hoist/cmp/grid';
3
+ import {div, filler, hbox, hframe, hspacer, placeholder, span, vframe} from '@xh/hoist/cmp/layout';
4
+ import {storeFilterField} from '@xh/hoist/cmp/store';
5
+ import {creates, hoistCmp, HoistProps, XH} from '@xh/hoist/core';
6
+ import {ManageDialogModel} from '@xh/hoist/core/persist/viewmanager/impl/ManageDialogModel';
7
+ import {button} from '@xh/hoist/desktop/cmp/button';
8
+ import {formField} from '@xh/hoist/desktop/cmp/form';
9
+ import {select, textArea, textInput} from '@xh/hoist/desktop/cmp/input';
10
+ import {panel} from '@xh/hoist/desktop/cmp/panel';
11
+ import {toolbar} from '@xh/hoist/desktop/cmp/toolbar';
12
+ import {fmtCompactDate} from '@xh/hoist/format';
13
+ import {Icon} from '@xh/hoist/icon';
14
+ import {dialog} from '@xh/hoist/kit/blueprint';
15
+ import {pluralize} from '@xh/hoist/utils/js';
16
+ import {capitalize} from 'lodash';
17
+
18
+ export interface ManageDialogProps extends HoistProps<ManageDialogModel> {
19
+ onClose: () => void;
20
+ }
21
+
22
+ export const manageDialog = hoistCmp.factory<ManageDialogProps>({
23
+ displayName: 'ManageDialog',
24
+ className: 'xh-view-manager__manage-dialog',
25
+ model: creates(ManageDialogModel),
26
+
27
+ render({model, className, onClose}) {
28
+ const {displayName, saveTask, deleteTask} = model;
29
+ return dialog({
30
+ title: `Manage ${capitalize(pluralize(displayName))}`,
31
+ icon: Icon.gear(),
32
+ className,
33
+ isOpen: true,
34
+ style: {width: '800px', maxWidth: '90vm', minHeight: '430px'},
35
+ canOutsideClickClose: false,
36
+ onClose,
37
+ item: panel({
38
+ item: hframe(gridPanel(), formPanel({onClose})),
39
+ mask: [saveTask, deleteTask]
40
+ })
41
+ });
42
+ }
43
+ });
44
+
45
+ const gridPanel = hoistCmp.factory({
46
+ render() {
47
+ return panel({
48
+ modelConfig: {defaultSize: 350, side: 'left', collapsible: false},
49
+ item: grid(),
50
+ bbar: [storeFilterField()]
51
+ });
52
+ }
53
+ });
54
+
55
+ const formPanel = hoistCmp.factory<ManageDialogProps>({
56
+ render({model, onClose}) {
57
+ const {displayName, formModel} = model,
58
+ {values} = formModel,
59
+ isOwnView = values.owner === XH.getUsername();
60
+
61
+ if (model.hasMultiSelection) {
62
+ return multiSelectionPanel();
63
+ }
64
+
65
+ if (!model.selectedId)
66
+ return panel({
67
+ item: placeholder(Icon.gears(), `Select a ${displayName}`),
68
+ bbar: bbar({onClose})
69
+ });
70
+
71
+ return panel({
72
+ item: form({
73
+ fieldDefaults: {
74
+ commitOnChange: true
75
+ },
76
+ item: vframe({
77
+ className: 'xh-view-manager__manage-dialog__form',
78
+ items: [
79
+ formField({
80
+ field: 'name',
81
+ item: textInput(),
82
+ info: model.canEdit
83
+ ? `Organize your ${pluralize(displayName)} into folders by including the "\\" character in their names - e.g. "My folder\\My ${displayName}".`
84
+ : null
85
+ }),
86
+ formField({
87
+ field: 'description',
88
+ item: textArea({
89
+ selectOnFocus: true,
90
+ height: 70
91
+ }),
92
+ readonlyRenderer: v =>
93
+ v
94
+ ? v
95
+ : span({
96
+ item: 'None provided',
97
+ className: 'xh-text-color-muted'
98
+ })
99
+ }),
100
+ formField({
101
+ field: 'isShared',
102
+ label: 'Visibility',
103
+ item: select({
104
+ options: [
105
+ {value: true, label: 'Shared with all users'},
106
+ {
107
+ value: false,
108
+ label: `Private to ${isOwnView ? 'me' : values.owner}`
109
+ }
110
+ ],
111
+ enableFilter: false
112
+ }),
113
+ omit: !model.enableSharing
114
+ }),
115
+ hbox({
116
+ omit: !model.showSaveButton,
117
+ style: {margin: '10px 20px'},
118
+ items: [
119
+ button({
120
+ text: 'Save Changes',
121
+ icon: Icon.check(),
122
+ intent: 'success',
123
+ minimal: false,
124
+ flex: 1,
125
+ onClick: () => model.saveAsync()
126
+ }),
127
+ hspacer(),
128
+ button({
129
+ icon: Icon.reset(),
130
+ tooltip: 'Revert changes',
131
+ minimal: false,
132
+ onClick: () => formModel.reset()
133
+ })
134
+ ]
135
+ }),
136
+ filler(),
137
+ div({
138
+ className: 'xh-view-manager__manage-dialog__metadata',
139
+ items: [
140
+ `Created ${fmtCompactDate(values.dateCreated)} by ${
141
+ values.owner === XH.getUsername() ? 'you' : values.owner
142
+ }. `,
143
+ `Updated ${fmtCompactDate(values.lastUpdated)} by ${
144
+ values.lastUpdatedBy === XH.getUsername()
145
+ ? 'you'
146
+ : values.lastUpdatedBy
147
+ }.`
148
+ ]
149
+ })
150
+ ]
151
+ })
152
+ }),
153
+ bbar: bbar({onClose})
154
+ });
155
+ }
156
+ });
157
+
158
+ const multiSelectionPanel = hoistCmp.factory<ManageDialogProps>({
159
+ render({model, onClose}) {
160
+ const {selectedIds} = model;
161
+ return panel({
162
+ item: vframe({
163
+ alignItems: 'center',
164
+ justifyContent: 'center',
165
+ item: button({
166
+ text: `Delete ${selectedIds.length} ${pluralize(model.displayName)}`,
167
+ icon: Icon.delete(),
168
+ intent: 'danger',
169
+ outlined: true,
170
+ disabled: !model.canDelete,
171
+ onClick: () => model.deleteAsync()
172
+ })
173
+ }),
174
+ bbar: bbar({onClose})
175
+ });
176
+ }
177
+ });
178
+
179
+ const bbar = hoistCmp.factory<ManageDialogProps>({
180
+ render({model, onClose}) {
181
+ return toolbar(
182
+ button({
183
+ text: 'Delete',
184
+ icon: Icon.delete(),
185
+ intent: 'danger',
186
+ disabled: !model.canDelete,
187
+ omit: model.hasMultiSelection,
188
+ onClick: () => model.deleteAsync()
189
+ }),
190
+ filler(),
191
+ button({
192
+ text: 'Close',
193
+ onClick: onClose
194
+ })
195
+ );
196
+ }
197
+ });
@@ -0,0 +1,89 @@
1
+ import {form} from '@xh/hoist/cmp/form';
2
+ import {filler, vframe} from '@xh/hoist/cmp/layout';
3
+ import {hoistCmp, uses} from '@xh/hoist/core';
4
+ import {SaveDialogModel} from '@xh/hoist/core/persist/viewmanager/impl/SaveDialogModel';
5
+ import {button} from '@xh/hoist/desktop/cmp/button';
6
+ import {formField} from '@xh/hoist/desktop/cmp/form';
7
+ import {textArea, textInput} from '@xh/hoist/desktop/cmp/input';
8
+ import {panel} from '@xh/hoist/desktop/cmp/panel';
9
+ import {toolbar} from '@xh/hoist/desktop/cmp/toolbar';
10
+ import {Icon} from '@xh/hoist/icon';
11
+ import {dialog} from '@xh/hoist/kit/blueprint';
12
+
13
+ export const saveDialog = hoistCmp.factory<SaveDialogModel>({
14
+ displayName: 'SaveDialog',
15
+ className: 'xh-view-manager__save-dialog',
16
+ model: uses(SaveDialogModel),
17
+
18
+ render({model, className}) {
19
+ if (!model.isOpen) return null;
20
+
21
+ return dialog({
22
+ title: `Save as...`,
23
+ icon: Icon.copy(),
24
+ className,
25
+ isOpen: true,
26
+ style: {width: 500},
27
+ canOutsideClickClose: false,
28
+ onClose: () => model.cancel(),
29
+ item: formPanel()
30
+ });
31
+ }
32
+ });
33
+
34
+ const formPanel = hoistCmp.factory<SaveDialogModel>({
35
+ render({model}) {
36
+ return panel({
37
+ item: form({
38
+ fieldDefaults: {
39
+ commitOnChange: true
40
+ },
41
+ item: vframe({
42
+ className: 'xh-view-manager__save-dialog__form',
43
+ items: [
44
+ formField({
45
+ field: 'name',
46
+ item: textInput({
47
+ autoFocus: true,
48
+ selectOnFocus: true,
49
+ onKeyDown: e => {
50
+ if (e.key === 'Enter') model.saveAsAsync();
51
+ }
52
+ })
53
+ }),
54
+ formField({
55
+ field: 'description',
56
+ item: textArea({
57
+ selectOnFocus: true,
58
+ height: 90
59
+ })
60
+ })
61
+ ]
62
+ })
63
+ }),
64
+ bbar: bbar(),
65
+ mask: model.saveTask
66
+ });
67
+ }
68
+ });
69
+
70
+ const bbar = hoistCmp.factory<SaveDialogModel>({
71
+ render({model}) {
72
+ const {formModel, DisplayName} = model;
73
+ return toolbar(
74
+ filler(),
75
+ button({
76
+ text: 'Cancel',
77
+ onClick: () => model.cancel()
78
+ }),
79
+ button({
80
+ text: `Save as new ${DisplayName}`,
81
+ icon: Icon.copy(),
82
+ outlined: true,
83
+ intent: 'success',
84
+ disabled: !formModel.isValid,
85
+ onClick: () => model.saveAsAsync()
86
+ })
87
+ );
88
+ }
89
+ });
@@ -0,0 +1,3 @@
1
+ export * from './ViewManager';
2
+ export * from './cmp/ManageDialog';
3
+ export * from './cmp/SaveDialog';
@@ -17,7 +17,7 @@ export interface ColAutosizeButtonProps extends ButtonProps {
17
17
  gridModel?: GridModel;
18
18
 
19
19
  /** Options for the grid autosize. */
20
- autosizeOptions?: GridAutosizeOptions;
20
+ autosizeOptions?: Omit<GridAutosizeOptions, 'mode'>;
21
21
  }
22
22
 
23
23
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "70.0.0-SNAPSHOT.1731083521069",
3
+ "version": "70.0.0-SNAPSHOT.1731374612473",
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",