@xh/hoist 87.1.1 → 87.2.0
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/.npmignore +39 -0
- package/CHANGELOG.md +92 -20
- package/admin/AdminUtils.ts +64 -0
- package/admin/App.scss +88 -0
- package/admin/columns/UserData.ts +30 -3
- package/admin/detail/RestDetailModel.ts +64 -0
- package/admin/detail/RestDetailPanel.ts +106 -0
- package/admin/tabs/activity/tracking/ActivityTrackingModel.ts +27 -94
- package/admin/tabs/activity/tracking/ActivityTrackingPanel.ts +23 -60
- package/admin/tabs/activity/tracking/detail/ActivityDetailView.ts +1 -2
- package/admin/tabs/general/alertBanner/AlertBannerPanel.ts +2 -13
- package/admin/tabs/general/config/ConfigDetailPanel.ts +72 -0
- package/admin/tabs/general/config/ConfigPanel.ts +41 -53
- package/admin/tabs/general/config/ConfigPanelModel.ts +3 -0
- package/admin/tabs/general/config/ConfigValue.scss +14 -0
- package/admin/tabs/general/config/ConfigValue.ts +104 -65
- package/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.ts +93 -0
- package/admin/tabs/userData/jsonblob/JsonBlobModel.ts +4 -0
- package/admin/tabs/userData/jsonblob/JsonBlobPanel.ts +2 -0
- package/admin/tabs/userData/prefs/UserPreferenceDetailPanel.ts +62 -0
- package/admin/tabs/userData/prefs/UserPreferenceModel.ts +10 -3
- package/admin/tabs/userData/prefs/UserPreferencePanel.ts +3 -1
- package/admin/tabs/userData/roles/details/RoleDetails.scss +2 -19
- package/admin/tabs/userData/roles/details/RoleDetails.ts +13 -13
- package/appcontainer/AboutDialogModel.ts +1 -0
- package/appcontainer/AppContainerModel.ts +3 -0
- package/appcontainer/AppStateModel.ts +1 -0
- package/appcontainer/BannerSourceModel.ts +1 -0
- package/appcontainer/ChangelogDialogModel.ts +1 -0
- package/appcontainer/ColChooserOptionsModel.ts +1 -0
- package/appcontainer/ExceptionDialogModel.ts +1 -0
- package/appcontainer/FeedbackDialogModel.ts +1 -0
- package/appcontainer/ImpersonationBarModel.ts +1 -0
- package/appcontainer/MessageSourceModel.ts +1 -0
- package/appcontainer/OptionsDialogModel.ts +1 -0
- package/appcontainer/PageStateModel.ts +1 -0
- package/appcontainer/RouterModel.ts +2 -0
- package/appcontainer/SizingModeModel.ts +1 -0
- package/appcontainer/ThemeModel.ts +1 -0
- package/appcontainer/ToastSourceModel.ts +1 -0
- package/appcontainer/UserAgentModel.ts +1 -0
- package/appcontainer/ViewportSizeModel.ts +1 -0
- package/build/types/admin/AdminUtils.d.ts +29 -0
- package/build/types/admin/columns/UserData.d.ts +3 -0
- package/build/types/admin/detail/RestDetailModel.d.ts +20 -0
- package/build/types/admin/detail/RestDetailPanel.d.ts +34 -0
- package/build/types/admin/tabs/activity/tracking/ActivityTrackingModel.d.ts +5 -17
- package/build/types/admin/tabs/general/config/ConfigDetailPanel.d.ts +7 -0
- package/build/types/admin/tabs/general/config/ConfigValue.d.ts +10 -4
- package/build/types/admin/tabs/userData/jsonblob/JsonBlobDetailPanel.d.ts +3 -0
- package/build/types/admin/tabs/userData/prefs/UserPreferenceDetailPanel.d.ts +3 -0
- package/build/types/admin/tabs/userData/prefs/UserPreferenceModel.d.ts +3 -0
- package/build/types/appcontainer/AboutDialogModel.d.ts +1 -0
- package/build/types/appcontainer/AppContainerModel.d.ts +1 -0
- package/build/types/appcontainer/AppStateModel.d.ts +1 -0
- package/build/types/appcontainer/BannerSourceModel.d.ts +1 -0
- package/build/types/appcontainer/ChangelogDialogModel.d.ts +1 -0
- package/build/types/appcontainer/ColChooserOptionsModel.d.ts +1 -0
- package/build/types/appcontainer/ExceptionDialogModel.d.ts +1 -0
- package/build/types/appcontainer/FeedbackDialogModel.d.ts +1 -0
- package/build/types/appcontainer/ImpersonationBarModel.d.ts +1 -0
- package/build/types/appcontainer/MessageSourceModel.d.ts +1 -0
- package/build/types/appcontainer/OptionsDialogModel.d.ts +1 -0
- package/build/types/appcontainer/PageStateModel.d.ts +1 -0
- package/build/types/appcontainer/RouterModel.d.ts +1 -0
- package/build/types/appcontainer/SizingModeModel.d.ts +1 -0
- package/build/types/appcontainer/ThemeModel.d.ts +1 -0
- package/build/types/appcontainer/ToastSourceModel.d.ts +1 -0
- package/build/types/appcontainer/UserAgentModel.d.ts +1 -0
- package/build/types/appcontainer/ViewportSizeModel.d.ts +1 -0
- package/build/types/cmp/ag-grid/AgGridModel.d.ts +3 -1
- package/build/types/cmp/card/Card.d.ts +2 -2
- package/build/types/cmp/chart/ChartModel.d.ts +2 -0
- package/build/types/cmp/dataview/DataViewModel.d.ts +2 -0
- package/build/types/cmp/daterange/DateRangePickerModel.d.ts +266 -0
- package/build/types/cmp/daterange/DateRangePresets.d.ts +26 -0
- package/build/types/cmp/daterange/DateRangeUtils.d.ts +96 -0
- package/build/types/cmp/daterange/Types.d.ts +152 -0
- package/build/types/cmp/daterange/index.d.ts +4 -0
- package/build/types/cmp/filter/FilterChooserModel.d.ts +3 -1
- package/build/types/cmp/form/FormModel.d.ts +3 -1
- package/build/types/cmp/grid/GridModel.d.ts +2 -0
- package/build/types/cmp/grid/Types.d.ts +2 -0
- package/build/types/cmp/grid/filter/GridFilterModel.d.ts +1 -1
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +3 -1
- package/build/types/cmp/input/HoistInputProps.d.ts +49 -2
- package/build/types/cmp/tab/TabContainerModel.d.ts +3 -1
- package/build/types/cmp/tab/TabModel.d.ts +3 -1
- package/build/types/cmp/treemap/TreeMapModel.d.ts +2 -0
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +2 -0
- package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +2 -0
- package/build/types/core/HoistBase.d.ts +7 -0
- package/build/types/core/HoistProps.d.ts +26 -1
- package/build/types/core/model/RootRefreshContextModel.d.ts +1 -0
- package/build/types/core/types/Telemetry.d.ts +1 -1
- package/build/types/data/Store.d.ts +3 -1
- package/build/types/data/StoreSelectionModel.d.ts +3 -1
- package/build/types/data/cube/Cube.d.ts +5 -2
- package/build/types/data/cube/View.d.ts +2 -0
- package/build/types/desktop/cmp/appOption/AutoRefreshAppOption.d.ts +3 -0
- package/build/types/desktop/cmp/appOption/ThemeAppOption.d.ts +3 -0
- package/build/types/desktop/cmp/button/Button.d.ts +2 -2
- package/build/types/desktop/cmp/button/ButtonGroup.d.ts +2 -2
- package/build/types/desktop/cmp/dash/DashConfig.d.ts +2 -0
- package/build/types/desktop/cmp/dash/DashViewModel.d.ts +3 -1
- package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +1 -1
- package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +1 -1
- package/build/types/desktop/cmp/daterange/DateRangePicker.d.ts +66 -0
- package/build/types/desktop/cmp/daterange/impl/CustomTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/DateRangePickerLocalModel.d.ts +121 -0
- package/build/types/desktop/cmp/daterange/impl/PeriodTab.d.ts +2 -0
- package/build/types/desktop/cmp/daterange/impl/PresetsTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/RelativeTab.d.ts +3 -0
- package/build/types/desktop/cmp/daterange/impl/TabUtils.d.ts +21 -0
- package/build/types/desktop/cmp/daterange/index.d.ts +2 -0
- package/build/types/desktop/cmp/dock/DockContainerModel.d.ts +3 -1
- package/build/types/desktop/cmp/dock/DockViewModel.d.ts +3 -1
- package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +4 -1
- package/build/types/desktop/cmp/input/IntentInput.d.ts +38 -0
- package/build/types/desktop/cmp/input/NumberInput.d.ts +2 -2
- package/build/types/desktop/cmp/input/SegmentedControl.d.ts +25 -4
- package/build/types/desktop/cmp/input/TextArea.d.ts +2 -2
- package/build/types/desktop/cmp/input/TextInput.d.ts +2 -2
- package/build/types/desktop/cmp/input/index.d.ts +1 -0
- package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +3 -1
- package/build/types/desktop/cmp/panel/PanelModel.d.ts +3 -1
- package/build/types/desktop/cmp/rest/RestGridModel.d.ts +1 -1
- package/build/types/desktop/cmp/tab/impl/TabContainer.d.ts +1 -1
- package/build/types/icon/Icon.d.ts +3 -0
- package/build/types/inspector/impl/InspectorUtils.d.ts +3 -0
- package/build/types/inspector/instances/InstancesModel.d.ts +4 -0
- package/build/types/kit/react-day-picker/index.d.ts +3 -3
- package/build/types/mobile/cmp/button/Button.d.ts +2 -2
- package/build/types/mobile/cmp/input/NumberInput.d.ts +2 -2
- package/build/types/mobile/cmp/input/SegmentedControl.d.ts +18 -4
- package/build/types/mobile/cmp/input/TextArea.d.ts +2 -2
- package/build/types/mobile/cmp/input/TextInput.d.ts +2 -2
- package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +3 -1
- package/build/types/mobile/cmp/navigator/PageModel.d.ts +3 -1
- package/build/types/mobile/cmp/tab/impl/TabContainer.d.ts +1 -1
- package/build/types/svc/InspectorService.d.ts +1 -0
- package/build/types/utils/js/LangUtils.d.ts +24 -5
- package/cmp/README.md +1 -0
- package/cmp/ag-grid/AgGridModel.ts +5 -0
- package/cmp/badge/Badge.ts +5 -3
- package/cmp/card/Card.ts +4 -3
- package/cmp/chart/ChartModel.ts +11 -1
- package/cmp/dataview/DataViewModel.ts +7 -1
- package/cmp/daterange/DateRangePickerModel.ts +628 -0
- package/cmp/daterange/DateRangePresets.ts +274 -0
- package/cmp/daterange/DateRangeUtils.ts +557 -0
- package/cmp/daterange/README.md +434 -0
- package/cmp/daterange/Types.ts +203 -0
- package/cmp/daterange/index.ts +10 -0
- package/cmp/filter/FilterChooserModel.ts +7 -4
- package/cmp/form/FormModel.ts +6 -0
- package/cmp/form/README.md +1 -0
- package/cmp/grid/GridModel.ts +24 -4
- package/cmp/grid/Types.ts +3 -0
- package/cmp/grid/filter/GridFilterModel.ts +3 -1
- package/cmp/grouping/GroupingChooserModel.ts +6 -1
- package/cmp/input/HoistInputProps.ts +50 -2
- package/cmp/input/README.md +42 -0
- package/cmp/layout/Box.ts +3 -2
- package/cmp/tab/TabContainerModel.ts +9 -1
- package/cmp/tab/TabModel.ts +5 -0
- package/cmp/treemap/SplitTreeMapModel.ts +12 -2
- package/cmp/treemap/TreeMapModel.ts +6 -1
- package/cmp/viewmanager/ViewManagerModel.ts +6 -1
- package/cmp/zoneGrid/ZoneGridModel.ts +7 -0
- package/core/HoistBase.ts +11 -0
- package/core/HoistProps.ts +27 -0
- package/core/README.md +46 -0
- package/core/impl/InstallServices.ts +5 -1
- package/core/model/RootRefreshContextModel.ts +2 -0
- package/core/types/Telemetry.ts +1 -1
- package/data/README.md +3 -1
- package/data/Store.ts +7 -0
- package/data/StoreSelectionModel.ts +5 -1
- package/data/cube/Cube.ts +12 -3
- package/data/cube/View.ts +5 -1
- package/desktop/README.md +2 -0
- package/desktop/appcontainer/LoginPanel.ts +2 -0
- package/desktop/cmp/button/Button.scss +71 -42
- package/desktop/cmp/button/Button.ts +10 -1
- package/desktop/cmp/button/ButtonGroup.ts +4 -1
- package/desktop/cmp/button/grid/ColChooserButton.ts +9 -1
- package/desktop/cmp/button/zoneGrid/ZoneMapperButton.ts +1 -0
- package/desktop/cmp/dash/DashConfig.ts +3 -0
- package/desktop/cmp/dash/DashViewModel.ts +14 -1
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +3 -1
- package/desktop/cmp/dash/container/DashContainerModel.ts +3 -1
- package/desktop/cmp/daterange/DateRangePicker.scss +577 -0
- package/desktop/cmp/daterange/DateRangePicker.ts +357 -0
- package/desktop/cmp/daterange/impl/CustomTab.ts +165 -0
- package/desktop/cmp/daterange/impl/DateRangePickerLocalModel.ts +482 -0
- package/desktop/cmp/daterange/impl/PeriodTab.ts +138 -0
- package/desktop/cmp/daterange/impl/PresetsTab.ts +58 -0
- package/desktop/cmp/daterange/impl/RelativeTab.ts +108 -0
- package/desktop/cmp/daterange/impl/TabUtils.ts +34 -0
- package/desktop/cmp/daterange/index.ts +8 -0
- package/desktop/cmp/dock/DockContainerModel.ts +6 -1
- package/desktop/cmp/dock/DockViewModel.ts +6 -1
- package/desktop/cmp/filechooser/FileChooser.ts +4 -0
- package/desktop/cmp/form/FormField.ts +1 -0
- package/desktop/cmp/grouping/GroupingChooser.ts +8 -2
- package/desktop/cmp/input/Checkbox.ts +1 -0
- package/desktop/cmp/input/CodeInput.ts +1 -0
- package/desktop/cmp/input/DateInput.scss +1 -1
- package/desktop/cmp/input/DateInput.ts +1 -0
- package/desktop/cmp/input/IntentInput.scss +202 -0
- package/desktop/cmp/input/IntentInput.ts +213 -0
- package/desktop/cmp/input/NumberInput.ts +11 -2
- package/desktop/cmp/input/Picker.ts +1 -0
- package/desktop/cmp/input/RadioInput.ts +2 -1
- package/desktop/cmp/input/SegmentedControl.scss +45 -2
- package/desktop/cmp/input/SegmentedControl.ts +66 -11
- package/desktop/cmp/input/Select.ts +9 -7
- package/desktop/cmp/input/Slider.ts +2 -0
- package/desktop/cmp/input/SwitchInput.ts +1 -0
- package/desktop/cmp/input/TextArea.ts +11 -2
- package/desktop/cmp/input/TextInput.ts +11 -2
- package/desktop/cmp/input/index.ts +1 -0
- package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +5 -0
- package/desktop/cmp/panel/Panel.ts +8 -5
- package/desktop/cmp/panel/PanelModel.ts +8 -0
- package/desktop/cmp/panel/impl/ResizeContainer.ts +2 -1
- package/desktop/cmp/rest/RestGridModel.ts +4 -0
- package/desktop/cmp/tab/impl/TabContainer.ts +2 -0
- package/docs/README.md +2 -0
- package/docs/build-and-publish.md +23 -7
- package/docs/doc-registry.json +8 -0
- package/docs/version-compatibility.md +2 -0
- package/icon/Icon.ts +9 -0
- package/icon/index.ts +24 -0
- package/inspector/README.md +8 -2
- package/inspector/impl/InspectorUtils.ts +12 -0
- package/inspector/instances/DiagnosticsModel.ts +3 -2
- package/inspector/instances/InstancesModel.ts +81 -14
- package/inspector/instances/InstancesPanel.ts +6 -0
- package/kit/react-day-picker/index.ts +3 -3
- package/mobile/appcontainer/LoginPanel.ts +2 -0
- package/mobile/cmp/button/Button.ts +16 -3
- package/mobile/cmp/form/FormField.ts +1 -0
- package/mobile/cmp/input/Checkbox.ts +1 -0
- package/mobile/cmp/input/DateInput.ts +1 -0
- package/mobile/cmp/input/Label.ts +13 -8
- package/mobile/cmp/input/NumberInput.ts +11 -2
- package/mobile/cmp/input/SearchInput.ts +1 -0
- package/mobile/cmp/input/SegmentedControl.scss +36 -6
- package/mobile/cmp/input/SegmentedControl.ts +37 -11
- package/mobile/cmp/input/Select.ts +2 -0
- package/mobile/cmp/input/SwitchInput.ts +1 -0
- package/mobile/cmp/input/TextArea.ts +11 -2
- package/mobile/cmp/input/TextInput.ts +11 -2
- package/mobile/cmp/navigator/NavigatorModel.ts +6 -1
- package/mobile/cmp/navigator/PageModel.ts +6 -1
- package/mobile/cmp/tab/impl/TabContainer.ts +9 -1
- package/package.json +19 -19
- package/styles/vars.scss +32 -2
- package/svc/InspectorService.ts +2 -0
- package/svc/TraceService.ts +5 -2
- package/utils/js/LangUtils.ts +37 -5
|
@@ -111,6 +111,9 @@ export interface PanelConfig {
|
|
|
111
111
|
|
|
112
112
|
/** @internal */
|
|
113
113
|
xhImpl?;
|
|
114
|
+
|
|
115
|
+
/** See {@link HoistBase.xhName}. */
|
|
116
|
+
xhName?: string;
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
export interface PanelPersistState {
|
|
@@ -215,11 +218,13 @@ export class PanelModel extends HoistModel implements Persistable<PanelPersistSt
|
|
|
215
218
|
showSplitterCollapseButton = showSplitter && collapsible,
|
|
216
219
|
showHeaderCollapseButton = true,
|
|
217
220
|
showModalToggleButton = true,
|
|
221
|
+
xhName = null,
|
|
218
222
|
xhImpl = false
|
|
219
223
|
}: PanelConfig) {
|
|
220
224
|
super();
|
|
221
225
|
makeObservable(this);
|
|
222
226
|
this.xhImpl = xhImpl;
|
|
227
|
+
this.xhName = xhName;
|
|
223
228
|
|
|
224
229
|
defaultSize =
|
|
225
230
|
isString(defaultSize) && defaultSize.endsWith('px')
|
|
@@ -267,6 +272,7 @@ export class PanelModel extends HoistModel implements Persistable<PanelPersistSt
|
|
|
267
272
|
modalSupport === true
|
|
268
273
|
? new ModalSupportModel()
|
|
269
274
|
: new ModalSupportModel(modalSupport);
|
|
275
|
+
this.modalSupportModel.xhName = this.childXhName('modalSupportModel');
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
if (errorBoundary) {
|
|
@@ -274,10 +280,12 @@ export class PanelModel extends HoistModel implements Persistable<PanelPersistSt
|
|
|
274
280
|
errorBoundary === true
|
|
275
281
|
? new ErrorBoundaryModel()
|
|
276
282
|
: new ErrorBoundaryModel(errorBoundary);
|
|
283
|
+
this.errorBoundaryModel.xhName = this.childXhName('errorBoundaryModel');
|
|
277
284
|
}
|
|
278
285
|
|
|
279
286
|
if (collapsible) {
|
|
280
287
|
this.refreshContextModel = new ManagedRefreshContextModel(this);
|
|
288
|
+
this.refreshContextModel.xhName = this.childXhName('refreshContextModel');
|
|
281
289
|
}
|
|
282
290
|
|
|
283
291
|
if (collapsible || resizable) {
|
|
@@ -18,7 +18,7 @@ export const resizeContainer = hoistCmp.factory({
|
|
|
18
18
|
model: false,
|
|
19
19
|
className: 'xh-resizable',
|
|
20
20
|
|
|
21
|
-
render({className, children, testId}, ref) {
|
|
21
|
+
render({className, children, testId, domAttrs}, ref) {
|
|
22
22
|
const panelModel = useContextModel(PanelModel),
|
|
23
23
|
{size, resizable, collapsed, vertical, contentFirst, showSplitter} = panelModel,
|
|
24
24
|
dim = vertical ? 'height' : 'width',
|
|
@@ -53,6 +53,7 @@ export const resizeContainer = hoistCmp.factory({
|
|
|
53
53
|
[maxDim]: '100%',
|
|
54
54
|
[minDim]: dragBarWidth,
|
|
55
55
|
testId,
|
|
56
|
+
domAttrs,
|
|
56
57
|
items
|
|
57
58
|
});
|
|
58
59
|
}
|
|
@@ -162,9 +162,11 @@ export class RestGridModel extends HoistModel {
|
|
|
162
162
|
onRowDoubleClicked,
|
|
163
163
|
store,
|
|
164
164
|
appData,
|
|
165
|
+
xhName = null,
|
|
165
166
|
...rest
|
|
166
167
|
}: RestGridConfig) {
|
|
167
168
|
super();
|
|
169
|
+
this.xhName = xhName;
|
|
168
170
|
this.readonly = readonly;
|
|
169
171
|
this.editors = editors;
|
|
170
172
|
this.toolbarActions = toolbarActions;
|
|
@@ -186,6 +188,7 @@ export class RestGridModel extends HoistModel {
|
|
|
186
188
|
});
|
|
187
189
|
|
|
188
190
|
this.gridModel = new GridModel({
|
|
191
|
+
xhName: this.childXhName('gridModel'),
|
|
189
192
|
contextMenu: [...this.menuActions, '-', ...GridModel.defaults.contextMenu],
|
|
190
193
|
exportOptions: {filename: pluralize(unit)},
|
|
191
194
|
store: this.parseStore(store),
|
|
@@ -197,6 +200,7 @@ export class RestGridModel extends HoistModel {
|
|
|
197
200
|
});
|
|
198
201
|
|
|
199
202
|
this.formModel = new RestFormModel(this);
|
|
203
|
+
this.formModel.xhName = this.childXhName('formModel');
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
/** Load the underlying store. */
|
|
@@ -24,6 +24,7 @@ export function tabContainerImpl({
|
|
|
24
24
|
childContainerProps,
|
|
25
25
|
className,
|
|
26
26
|
testId,
|
|
27
|
+
domAttrs,
|
|
27
28
|
...props
|
|
28
29
|
}: TabContainerProps) {
|
|
29
30
|
const switcherProps = getSwitcherProps(props),
|
|
@@ -40,6 +41,7 @@ export function tabContainerImpl({
|
|
|
40
41
|
...layoutProps,
|
|
41
42
|
className,
|
|
42
43
|
testId,
|
|
44
|
+
domAttrs,
|
|
43
45
|
item: getChildren(model, switcherProps, testId, childContainerProps)
|
|
44
46
|
});
|
|
45
47
|
}
|
package/docs/README.md
CHANGED
|
@@ -34,6 +34,7 @@ See [`docs-roadmap.md`](./planning/docs-roadmap.md) for documentation coverage t
|
|
|
34
34
|
| Configure a desktop panel (toolbars, masks, collapse) | [`/desktop/cmp/panel/`](../desktop/cmp/panel/README.md) |
|
|
35
35
|
| Build a mobile app | [`/mobile/`](../mobile/README.md) |
|
|
36
36
|
| Save and restore named view configurations | [`/cmp/viewmanager/`](../cmp/viewmanager/README.md) |
|
|
37
|
+
| Select a period or date range (presets, lookbacks, months, custom) | [`/cmp/daterange/`](../cmp/daterange/README.md) |
|
|
37
38
|
| Use layout containers (Box, HBox, VBox, Frame) | [`/cmp/layout/`](../cmp/layout/README.md) |
|
|
38
39
|
| Work with Stores, Records, Fields, or Filters | [`/data/`](../data/README.md) |
|
|
39
40
|
| Set up Cube aggregation with Views and Queries | [`/data/cube/`](../data/cube/README.md) |
|
|
@@ -87,6 +88,7 @@ See [`docs-roadmap.md`](./planning/docs-roadmap.md) for documentation coverage t
|
|
|
87
88
|
| [`/cmp/layout/`](../cmp/layout/README.md) | Flexbox-based layout containers | Box, VBox, HBox, Frame, Viewport, LayoutProps, pixel conversion |
|
|
88
89
|
| [`/cmp/tab/`](../cmp/tab/README.md) | Tabbed interface system | TabContainerModel, routing integration, render modes, refresh strategies |
|
|
89
90
|
| [`/cmp/viewmanager/`](../cmp/viewmanager/README.md) | Save/load named bundles of component state | ViewManagerModel, views, sharing, pinning, auto-save, JsonBlob persistence |
|
|
91
|
+
| [`/cmp/daterange/`](../cmp/daterange/README.md) | Period selection as presets, relative lookbacks, months/years, or custom ranges, resolved to dates and filters | DateRangePickerModel, DateRangePicker, DateRangeSelection, presets, anchorDate, LocalDateRange, currentRangeFilter, priorRange |
|
|
90
92
|
| [`/desktop/`](../desktop/README.md) | Desktop-specific components and app container | Desktop components, Blueprint wrappers, desktop navigation |
|
|
91
93
|
| [`/desktop/cmp/dash/`](../desktop/cmp/dash/README.md) | Configurable dashboard system with draggable, resizable widgets | DashContainerModel, DashCanvasModel, DashViewSpec, DashViewModel, widget persistence, ViewManager integration |
|
|
92
94
|
| [`/desktop/cmp/panel/`](../desktop/cmp/panel/README.md) | Desktop panel container with toolbars, masks, and collapsible behavior | Panel, PanelModel, Toolbar, mask, collapse/resize, persistence, modal support |
|
|
@@ -24,6 +24,14 @@ Publishes a SNAPSHOT build to npm on every push to `develop`. Can also be trigge
|
|
|
24
24
|
- Linting runs as part of this workflow — a lint failure will block the publish.
|
|
25
25
|
- Uses `concurrency` with `cancel-in-progress: true` to avoid redundant builds when multiple pushes
|
|
26
26
|
land in quick succession.
|
|
27
|
+
- After publishing, polls `npm view @xh/hoist@next` until the registry resolves the `next` dist-tag
|
|
28
|
+
to the version just published (10 minute limit). Publishing returns once npm accepts the tarball,
|
|
29
|
+
but the new version is not guaranteed to be resolvable at that moment.
|
|
30
|
+
- Finally fires a `repository_dispatch` (`hoist-react-snapshot`) to `xh/toolbox`, which rebuilds
|
|
31
|
+
and redeploys Toolbox against the new snapshot. The dispatch authenticates as the org-owned
|
|
32
|
+
**XH Build Bot** GitHub App via a short-lived installation token minted by
|
|
33
|
+
`actions/create-github-app-token`, scoped to the toolbox repo with Contents: write. Toolbox runs
|
|
34
|
+
triggered this way show `xh-build-bot[bot]` as the actor.
|
|
27
35
|
|
|
28
36
|
## Deploy Release (`deployRelease.yml`)
|
|
29
37
|
|
|
@@ -62,13 +70,21 @@ Inputs:
|
|
|
62
70
|
Automated dependency update PRs are configured for both GitHub Actions and npm dependencies, each
|
|
63
71
|
checking weekly.
|
|
64
72
|
|
|
65
|
-
## Required Secrets
|
|
66
|
-
|
|
67
|
-
|
|
|
68
|
-
|
|
69
|
-
| `FONTAWESOME_PACKAGE_TOKEN` | CI, Snapshot, Release | Auth token for the Font Awesome Pro npm registry (`npm.fontawesome.com`) |
|
|
70
|
-
| `NPM_TOKEN` | Snapshot, Release, Unpublish | Auth token for publishing to the npm public registry |
|
|
71
|
-
| `
|
|
73
|
+
## Required Secrets and Variables
|
|
74
|
+
|
|
75
|
+
| Name | Type | Used By | Purpose |
|
|
76
|
+
|------|------|---------|---------|
|
|
77
|
+
| `FONTAWESOME_PACKAGE_TOKEN` | Secret | CI, Snapshot, Release | Auth token for the Font Awesome Pro npm registry (`npm.fontawesome.com`) |
|
|
78
|
+
| `NPM_TOKEN` | Secret | Snapshot, Release, Unpublish | Auth token for publishing to the npm public registry |
|
|
79
|
+
| `XH_BUILD_BOT_PRIVATE_KEY` | Secret | Snapshot | Private key for the XH Build Bot GitHub App, used to mint the Toolbox dispatch token |
|
|
80
|
+
| `XH_BUILD_BOT_CLIENT_ID` | Variable | Snapshot | Client ID of the XH Build Bot GitHub App |
|
|
81
|
+
| `GITHUB_TOKEN` | Secret | Release | Provided automatically by GitHub Actions; used for `gh release create` |
|
|
82
|
+
|
|
83
|
+
The XH Build Bot app is registered under the xh GitHub org and installed org-wide. Its credentials
|
|
84
|
+
(app ID, client ID, and private key) are kept in the team 1Password vault under
|
|
85
|
+
"GitHub App: XH Build Bot". To rotate, generate a new private key on the app's settings page, update
|
|
86
|
+
the 1Password item and the `XH_BUILD_BOT_PRIVATE_KEY` secret here and in hoist-core, then revoke the
|
|
87
|
+
old key.
|
|
72
88
|
|
|
73
89
|
Font Awesome Pro packages are sourced from the official Font Awesome registry at
|
|
74
90
|
`npm.fontawesome.com` (configured in `.npmrc`). The `FONTAWESOME_PACKAGE_TOKEN` secret is appended
|
package/docs/doc-registry.json
CHANGED
|
@@ -127,6 +127,14 @@
|
|
|
127
127
|
"description": "Save/load named bundles of component state.",
|
|
128
128
|
"keywords": ["ViewManagerModel", "views", "sharing", "pinning", "auto-save", "JsonBlob persistence"]
|
|
129
129
|
},
|
|
130
|
+
{
|
|
131
|
+
"id": "cmp/daterange/README.md",
|
|
132
|
+
"title": "Date Range Package",
|
|
133
|
+
"mcpCategory": "package",
|
|
134
|
+
"viewerCategory": "components",
|
|
135
|
+
"description": "Period selection as presets, relative lookbacks, months/years, or custom ranges, resolved to dates and filters.",
|
|
136
|
+
"keywords": ["DateRangePickerModel", "DateRangePicker", "DateRangeSelection", "dateRangePresets", "DateRangePreset", "LocalDateRange", "anchorDate", "currentRangeFilter", "priorRange", "business days"]
|
|
137
|
+
},
|
|
130
138
|
{
|
|
131
139
|
"id": "desktop/cmp/dash/README.md",
|
|
132
140
|
"title": "Dashboard System",
|
|
@@ -162,6 +162,7 @@ taking its current major alongside a hoist-react upgrade is low-cost and always
|
|
|
162
162
|
|
|
163
163
|
| hoist-react | Min Dev-Utils Required | Recommended Dev-Utils | Notes |
|
|
164
164
|
|---|---|---|---|
|
|
165
|
+
| 87.1 | -- | 15.0.1 | Take 15.0.1+, not 15.0.0. dev-utils 15 requires 87.1, enforced with a fail-fast build error. Apps taking v15 must also be TS-only (no `.jsx` files) and will see ESLint v10 rules. |
|
|
165
166
|
| 87.0 | 14.0 | 14.0 | React 19: dev-utils 14 ships `@types/react` 19.x and is required for apps adopting pnpm. (13.x can build v87 with `@types/react` 19.x pinned via `resolutions` - a transitional pairing only, not supported.) |
|
|
166
167
|
| 86.0 | -- | 13.0.1 | dev-utils 13 sets a Node floor of >= 22.11 and swaps the markdown loader - verify `flex: 1 1 0` styles (see [v86 notes](./upgrade-notes/v86-upgrade-notes.md)). |
|
|
167
168
|
| 83.0 | -- | 12.0 | dev-utils 12's same-port dev proxy pairs with the hoist-react 83.0.2 `WebSocketService` fix. |
|
|
@@ -178,6 +179,7 @@ hard gates stated in the [hoist-dev-utils CHANGELOG](https://github.com/xh/hoist
|
|
|
178
179
|
|
|
179
180
|
| hoist-dev-utils | Min hoist-react | Min Node | Notes |
|
|
180
181
|
|---|---|---|---|
|
|
182
|
+
| 15.0 | 87.1 | 22.15 | Take 15.0.1+ - 15.0.0 can crash app boot ([#4640](https://github.com/xh/hoist-react/issues/4640)). Apps must be TypeScript-only - `.jsx` files are no longer resolved or transpiled. Re-enables Terser name-mangling, ships ESLint v10 via `@xh/eslint-config` 8, and emits pre-compressed `.br` / `.gz` assets on prod builds. |
|
|
181
183
|
| 14.0 | 87.0 | 22.15 | React 19 / `@types/react` 19.x baseline. Adds pnpm support - apps adopting pnpm must take 14+, and must declare every package they import directly (see dev-utils CHANGELOG). webpack-dev-server 6. |
|
|
182
184
|
| 13.0 | -- | 22.11 | Take 13.0.1+. Markdown files now import as strings; verify `flex: 1 1 0` styles. |
|
|
183
185
|
| 12.0 | 83.0.2 | | Same-port dev proxy (`baseUrl` default now `/api/`); requires hoist-react's `WebSocketService` fix in 83.0.2. |
|
package/icon/Icon.ts
CHANGED
|
@@ -189,6 +189,9 @@ export const Icon = {
|
|
|
189
189
|
arrowsUpDown(p?: IconProps) {
|
|
190
190
|
return Icon.icon({...p, iconName: 'arrows-v'});
|
|
191
191
|
},
|
|
192
|
+
asterisk(p?: IconProps) {
|
|
193
|
+
return Icon.icon({...p, iconName: 'asterisk'});
|
|
194
|
+
},
|
|
192
195
|
balanceScale(p?: IconProps) {
|
|
193
196
|
return Icon.icon({...p, iconName: 'balance-scale'});
|
|
194
197
|
},
|
|
@@ -231,6 +234,12 @@ export const Icon = {
|
|
|
231
234
|
calendar(p?: IconProps) {
|
|
232
235
|
return Icon.icon({...p, iconName: 'calendar-day'});
|
|
233
236
|
},
|
|
237
|
+
calendarDays(p?: IconProps) {
|
|
238
|
+
return Icon.icon({...p, iconName: 'calendar-days'});
|
|
239
|
+
},
|
|
240
|
+
calendarRange(p?: IconProps) {
|
|
241
|
+
return Icon.icon({...p, iconName: 'calendar-range'});
|
|
242
|
+
},
|
|
234
243
|
camera(p?: IconProps) {
|
|
235
244
|
return Icon.icon({...p, iconName: 'camera'});
|
|
236
245
|
},
|
package/icon/index.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
faArrowToTop as faArrowToTopLight,
|
|
34
34
|
faArrowUp as faArrowUpLight,
|
|
35
35
|
faArrowUpFromBracket as faArrowUpFromBracketLight,
|
|
36
|
+
faAsterisk as faAsteriskLight,
|
|
36
37
|
faBalanceScale as faBalanceScaleLight,
|
|
37
38
|
faBalanceScaleLeft as faBalanceScaleLeftLight,
|
|
38
39
|
faBalanceScaleRight as faBalanceScaleRightLight,
|
|
@@ -53,6 +54,8 @@ import {
|
|
|
53
54
|
faBullseyeArrow as faBullseyeArrowLight,
|
|
54
55
|
faCalculator as faCalculatorLight,
|
|
55
56
|
faCalendarDay as faCalendarDayLight,
|
|
57
|
+
faCalendarDays as faCalendarDaysLight,
|
|
58
|
+
faCalendarRange as faCalendarRangeLight,
|
|
56
59
|
faCamera as faCameraLight,
|
|
57
60
|
faCaretLeft as faCaretLeftLight,
|
|
58
61
|
faCaretRight as faCaretRightLight,
|
|
@@ -251,6 +254,7 @@ import {
|
|
|
251
254
|
faArrowToTop,
|
|
252
255
|
faArrowUp,
|
|
253
256
|
faArrowUpFromBracket,
|
|
257
|
+
faAsterisk,
|
|
254
258
|
faBalanceScale,
|
|
255
259
|
faBalanceScaleLeft,
|
|
256
260
|
faBalanceScaleRight,
|
|
@@ -271,6 +275,8 @@ import {
|
|
|
271
275
|
faBullseyeArrow,
|
|
272
276
|
faCalculator,
|
|
273
277
|
faCalendarDay,
|
|
278
|
+
faCalendarDays,
|
|
279
|
+
faCalendarRange,
|
|
274
280
|
faCamera,
|
|
275
281
|
faCaretLeft,
|
|
276
282
|
faCaretRight,
|
|
@@ -469,6 +475,7 @@ import {
|
|
|
469
475
|
faArrowToTop as faArrowToTopSolid,
|
|
470
476
|
faArrowUp as faArrowUpSolid,
|
|
471
477
|
faArrowUpFromBracket as faArrowUpFromBracketSolid,
|
|
478
|
+
faAsterisk as faAsteriskSolid,
|
|
472
479
|
faBalanceScale as faBalanceScaleSolid,
|
|
473
480
|
faBalanceScaleLeft as faBalanceScaleLeftSolid,
|
|
474
481
|
faBalanceScaleRight as faBalanceScaleRightSolid,
|
|
@@ -489,6 +496,8 @@ import {
|
|
|
489
496
|
faBullseyeArrow as faBullseyeArrowSolid,
|
|
490
497
|
faCalculator as faCalculatorSolid,
|
|
491
498
|
faCalendarDay as faCalendarDaySolid,
|
|
499
|
+
faCalendarDays as faCalendarDaysSolid,
|
|
500
|
+
faCalendarRange as faCalendarRangeSolid,
|
|
492
501
|
faCamera as faCameraSolid,
|
|
493
502
|
faCaretLeft as faCaretLeftSolid,
|
|
494
503
|
faCaretRight as faCaretRightSolid,
|
|
@@ -688,6 +697,7 @@ import {
|
|
|
688
697
|
faArrowToTop as faArrowToTopThin,
|
|
689
698
|
faArrowUp as faArrowUpThin,
|
|
690
699
|
faArrowUpFromBracket as faArrowUpFromBracketThin,
|
|
700
|
+
faAsterisk as faAsteriskThin,
|
|
691
701
|
faBalanceScale as faBalanceScaleThin,
|
|
692
702
|
faBalanceScaleLeft as faBalanceScaleLeftThin,
|
|
693
703
|
faBalanceScaleRight as faBalanceScaleRightThin,
|
|
@@ -708,6 +718,8 @@ import {
|
|
|
708
718
|
faBullseyeArrow as faBullseyeArrowThin,
|
|
709
719
|
faCalculator as faCalculatorThin,
|
|
710
720
|
faCalendarDay as faCalendarDayThin,
|
|
721
|
+
faCalendarDays as faCalendarDaysThin,
|
|
722
|
+
faCalendarRange as faCalendarRangeThin,
|
|
711
723
|
faCamera as faCameraThin,
|
|
712
724
|
faCaretLeft as faCaretLeftThin,
|
|
713
725
|
faCaretRight as faCaretRightThin,
|
|
@@ -976,6 +988,10 @@ library.add(
|
|
|
976
988
|
faArrowUpLight,
|
|
977
989
|
faArrowUpSolid,
|
|
978
990
|
faArrowUpThin,
|
|
991
|
+
faAsterisk,
|
|
992
|
+
faAsteriskLight,
|
|
993
|
+
faAsteriskSolid,
|
|
994
|
+
faAsteriskThin,
|
|
979
995
|
faBalanceScale,
|
|
980
996
|
faBalanceScaleLight,
|
|
981
997
|
faBalanceScaleSolid,
|
|
@@ -1053,9 +1069,17 @@ library.add(
|
|
|
1053
1069
|
faCalculatorSolid,
|
|
1054
1070
|
faCalculatorThin,
|
|
1055
1071
|
faCalendarDay,
|
|
1072
|
+
faCalendarDays,
|
|
1073
|
+
faCalendarRange,
|
|
1056
1074
|
faCalendarDayLight,
|
|
1057
1075
|
faCalendarDaySolid,
|
|
1058
1076
|
faCalendarDayThin,
|
|
1077
|
+
faCalendarDaysLight,
|
|
1078
|
+
faCalendarDaysSolid,
|
|
1079
|
+
faCalendarDaysThin,
|
|
1080
|
+
faCalendarRangeLight,
|
|
1081
|
+
faCalendarRangeSolid,
|
|
1082
|
+
faCalendarRangeThin,
|
|
1059
1083
|
faCamera,
|
|
1060
1084
|
faCameraLight,
|
|
1061
1085
|
faCameraSolid,
|
package/inspector/README.md
CHANGED
|
@@ -122,7 +122,8 @@ navigation or load action created them.
|
|
|
122
122
|
The Instances panel is a split layout with:
|
|
123
123
|
|
|
124
124
|
- **Instances grid** (left, resizable) — Lists all live `HoistModel`, `HoistService`, `Store`,
|
|
125
|
-
`Cube`, and `View` instances with their class name, creation time,
|
|
125
|
+
`Cube`, and `View` instances with their `xhName` (when set), class name, creation time,
|
|
126
|
+
linked status, and sync run
|
|
126
127
|
- **Properties grid** (right) — Shows properties of the selected instance(s), including observable
|
|
127
128
|
values with live updates
|
|
128
129
|
- **Diagnostics panel** (tabbed with properties) — Live readout of the data-pipeline
|
|
@@ -133,6 +134,10 @@ The Instances panel is a split layout with:
|
|
|
133
134
|
- **Grouping** — Toggle "Show in Groups" to group by type (Models, Services, Stores)
|
|
134
135
|
- **XH impl filtering** — Toggle "Show XH Impl" to show/hide Hoist's internal framework instances
|
|
135
136
|
(marked with `xhImpl = true`)
|
|
137
|
+
- **Favorites** — Star any instance with an `xhName` to pin it, then toggle "Favorites" to show
|
|
138
|
+
only pinned instances. Keyed by `{className}:{xhName}` and persisted, so the same set of objects
|
|
139
|
+
can be followed across reloads. Favorites with no live instance show as muted placeholder rows -
|
|
140
|
+
un-star one to drop it
|
|
136
141
|
- **Actions** — Log instance to devtools console, trigger `loadAsync()` on models with
|
|
137
142
|
`LoadSupport`
|
|
138
143
|
- **Multi-select** — Select multiple instances to compare their properties side-by-side
|
|
@@ -178,7 +183,8 @@ Inspector state is persisted to `localStorage` under the key
|
|
|
178
183
|
|
|
179
184
|
- Panel sizes (stats panel, instances panel)
|
|
180
185
|
- Grid column state for both grids
|
|
181
|
-
- Quick filter selections (grouping, xhImpl visibility, property filters)
|
|
186
|
+
- Quick filter selections (grouping, xhImpl visibility, favorites, property filters)
|
|
187
|
+
- Favorited instances
|
|
182
188
|
- Store filter text
|
|
183
189
|
- Active/inactive state
|
|
184
190
|
|
|
@@ -0,0 +1,12 @@
|
|
|
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 © 2026 Extremely Heavy Industries Inc.
|
|
6
|
+
*/
|
|
7
|
+
import type {HoistBase} from '@xh/hoist/core';
|
|
8
|
+
|
|
9
|
+
/** Label for an instance within Inspector - its `xhName` or class name, plus `xhId`. */
|
|
10
|
+
export function instanceLabel(inst: HoistBase): string {
|
|
11
|
+
return `${inst.xhName ?? inst.constructor.name} [${inst.xhId}]`;
|
|
12
|
+
}
|
|
@@ -11,6 +11,7 @@ import {fmtDate, numberRenderer} from '@xh/hoist/format';
|
|
|
11
11
|
import {action, makeObservable} from '@xh/hoist/mobx';
|
|
12
12
|
import {Cube} from '@xh/hoist/data';
|
|
13
13
|
import {forIn, isEmpty, isFinite} from 'lodash';
|
|
14
|
+
import {instanceLabel} from '../impl/InspectorUtils';
|
|
14
15
|
import type {InstancesModel} from './InstancesModel';
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -55,7 +56,7 @@ export class DiagnosticsModel extends HoistModel {
|
|
|
55
56
|
private get diagnosticSources(): DiagnosticSource[] {
|
|
56
57
|
const ret: DiagnosticSource[] = [];
|
|
57
58
|
this.parent.selectedInstances.forEach(inst => {
|
|
58
|
-
const label =
|
|
59
|
+
const label = instanceLabel(inst),
|
|
59
60
|
diag = (inst as any).diagnostics;
|
|
60
61
|
if (diag instanceof BaseDiagnostics) {
|
|
61
62
|
ret.push({xhId: inst.xhId, diag, label});
|
|
@@ -63,7 +64,7 @@ export class DiagnosticsModel extends HoistModel {
|
|
|
63
64
|
ret.push({
|
|
64
65
|
xhId: inst.xhId,
|
|
65
66
|
diag: inst.store.diagnostics,
|
|
66
|
-
label: `${label} ›
|
|
67
|
+
label: `${label} › ${instanceLabel(inst.store)}`
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
});
|
|
@@ -16,6 +16,7 @@ import {action, bindable, isObservableProp, makeObservable, runInAction} from '@
|
|
|
16
16
|
import {wait} from '@xh/hoist/promise';
|
|
17
17
|
import {trimToDepth} from '@xh/hoist/utils/js';
|
|
18
18
|
import {compact, find, forIn, head, without} from 'lodash';
|
|
19
|
+
import {instanceLabel} from '../impl/InspectorUtils';
|
|
19
20
|
import {StatsModel} from '../stats/StatsModel';
|
|
20
21
|
import {DiagnosticsModel} from './DiagnosticsModel';
|
|
21
22
|
|
|
@@ -48,6 +49,9 @@ export class InstancesModel extends HoistModel {
|
|
|
48
49
|
@bindable @persist instancesStoreFilter;
|
|
49
50
|
@bindable @persist propertiesStoreFilter;
|
|
50
51
|
|
|
52
|
+
/** Keys of favorited instances (`{className}:{xhName}`) - requires an `xhName` to pin. */
|
|
53
|
+
@bindable.ref @persist favorites: string[] = [];
|
|
54
|
+
|
|
51
55
|
@bindable @persist instQuickFilters = ['showInGroups'];
|
|
52
56
|
get showInGroups() {
|
|
53
57
|
return this.instQuickFilters?.includes('showInGroups');
|
|
@@ -55,6 +59,9 @@ export class InstancesModel extends HoistModel {
|
|
|
55
59
|
get showXhImpl() {
|
|
56
60
|
return this.instQuickFilters?.includes('showXhImpl');
|
|
57
61
|
}
|
|
62
|
+
get favoritesOnly() {
|
|
63
|
+
return this.instQuickFilters?.includes('favoritesOnly');
|
|
64
|
+
}
|
|
58
65
|
|
|
59
66
|
@bindable @persist propQuickFilters = [];
|
|
60
67
|
get showUnderscoreProps() {
|
|
@@ -68,7 +75,9 @@ export class InstancesModel extends HoistModel {
|
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
get selectedInstances(): HoistBase[] {
|
|
71
|
-
return
|
|
78
|
+
return compact(
|
|
79
|
+
this.instancesGridModel.selectedIds.map((it: string) => this.getInstance(it))
|
|
80
|
+
);
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
constructor() {
|
|
@@ -160,6 +169,13 @@ export class InstancesModel extends HoistModel {
|
|
|
160
169
|
}
|
|
161
170
|
}
|
|
162
171
|
|
|
172
|
+
toggleFavorite(record: StoreRecord) {
|
|
173
|
+
const key = favoriteKey(record?.data);
|
|
174
|
+
if (!key) return;
|
|
175
|
+
const {favorites} = this;
|
|
176
|
+
this.favorites = favorites.includes(key) ? without(favorites, key) : [...favorites, key];
|
|
177
|
+
}
|
|
178
|
+
|
|
163
179
|
togglePropsWatchlistItem(record: StoreRecord) {
|
|
164
180
|
const {instanceXhId, property, isGetter} = record.data,
|
|
165
181
|
{propsWatchlist} = this,
|
|
@@ -195,6 +211,9 @@ export class InstancesModel extends HoistModel {
|
|
|
195
211
|
store: {
|
|
196
212
|
fields: [
|
|
197
213
|
{name: 'className', type: 'string'},
|
|
214
|
+
{name: 'xhName', type: 'string'},
|
|
215
|
+
{name: 'isFavorite', type: 'bool'},
|
|
216
|
+
{name: 'alive', type: 'bool'},
|
|
198
217
|
{name: 'displayGroup', type: 'string'},
|
|
199
218
|
{name: 'created', type: 'date'},
|
|
200
219
|
{name: 'syncRun', type: 'number'},
|
|
@@ -218,12 +237,29 @@ export class InstancesModel extends HoistModel {
|
|
|
218
237
|
columns: [
|
|
219
238
|
{
|
|
220
239
|
...actionCol,
|
|
221
|
-
width: calcActionColWidth(
|
|
240
|
+
width: calcActionColWidth(3),
|
|
222
241
|
actions: [
|
|
223
242
|
{
|
|
224
243
|
icon: Icon.terminal(),
|
|
225
244
|
tooltip: 'Log to console',
|
|
226
|
-
actionFn: ({record}) => this.logInstanceToConsole(record)
|
|
245
|
+
actionFn: ({record}) => this.logInstanceToConsole(record),
|
|
246
|
+
displayFn: ({record}) => ({hidden: !record.data.alive})
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
icon: Icon.favorite(),
|
|
250
|
+
actionFn: ({record}) => this.toggleFavorite(record),
|
|
251
|
+
displayFn: ({record}) => {
|
|
252
|
+
const {xhName, isFavorite} = record.data;
|
|
253
|
+
return {
|
|
254
|
+
disabled: !xhName,
|
|
255
|
+
tooltip: xhName
|
|
256
|
+
? 'Toggle Favorite'
|
|
257
|
+
: 'Set xhName to enable favorites',
|
|
258
|
+
icon: isFavorite
|
|
259
|
+
? Icon.favorite({intent: 'warning', prefix: 'fas'})
|
|
260
|
+
: Icon.favorite({className: 'xh-text-color-muted'})
|
|
261
|
+
};
|
|
262
|
+
}
|
|
227
263
|
},
|
|
228
264
|
{
|
|
229
265
|
icon: Icon.refresh({intent: 'success'}),
|
|
@@ -234,7 +270,11 @@ export class InstancesModel extends HoistModel {
|
|
|
234
270
|
}
|
|
235
271
|
]
|
|
236
272
|
},
|
|
237
|
-
{
|
|
273
|
+
{
|
|
274
|
+
field: 'id',
|
|
275
|
+
displayName: 'xhId',
|
|
276
|
+
renderer: (v, {record}) => (record.data.alive ? v : null)
|
|
277
|
+
},
|
|
238
278
|
{
|
|
239
279
|
field: 'syncRun',
|
|
240
280
|
displayName: 'Sync',
|
|
@@ -252,6 +292,8 @@ export class InstancesModel extends HoistModel {
|
|
|
252
292
|
renderer: v => (v ? Icon.link() : null)
|
|
253
293
|
},
|
|
254
294
|
{field: 'displayGroup', hidden: true},
|
|
295
|
+
{field: 'isFavorite', ...boolCheckCol, hidden: true},
|
|
296
|
+
{field: 'xhName', flex: 1, minWidth: 150},
|
|
255
297
|
{field: 'className', flex: 1, minWidth: 150},
|
|
256
298
|
{
|
|
257
299
|
field: 'lastLoadCompleted',
|
|
@@ -263,10 +305,8 @@ export class InstancesModel extends HoistModel {
|
|
|
263
305
|
},
|
|
264
306
|
{field: 'created', align: 'right', renderer: timestampRenderer}
|
|
265
307
|
],
|
|
266
|
-
rowClassFn: rec =>
|
|
267
|
-
|
|
268
|
-
},
|
|
269
|
-
onRowDoubleClicked: ({data: rec}) => this.logInstanceToConsole(rec),
|
|
308
|
+
rowClassFn: rec => (rec?.data.isXhImpl || !rec?.data.alive ? 'xh-impl-row' : null),
|
|
309
|
+
onRowDoubleClicked: ({data: rec}) => rec?.data.alive && this.logInstanceToConsole(rec),
|
|
270
310
|
xhImpl: true
|
|
271
311
|
});
|
|
272
312
|
}
|
|
@@ -387,11 +427,15 @@ export class InstancesModel extends HoistModel {
|
|
|
387
427
|
private autoLoadInstancesGrid() {
|
|
388
428
|
this.addAutorun({
|
|
389
429
|
run: () => {
|
|
390
|
-
const {showXhImpl, instancesGridModel, selectedSyncRun} =
|
|
430
|
+
const {showXhImpl, favoritesOnly, favorites, instancesGridModel, selectedSyncRun} =
|
|
431
|
+
this,
|
|
391
432
|
data = [];
|
|
392
433
|
|
|
393
434
|
XH.inspectorService.activeInstances.forEach(inst => {
|
|
394
|
-
|
|
435
|
+
const isFavorite = favorites.includes(favoriteKey(inst));
|
|
436
|
+
|
|
437
|
+
// A star is an explicit opt-in, so favorites show regardless of the xhImpl filter.
|
|
438
|
+
if (favoritesOnly ? !isFavorite : !showXhImpl && inst.isXhImpl) return;
|
|
395
439
|
if (selectedSyncRun && inst.syncRun !== selectedSyncRun) return;
|
|
396
440
|
|
|
397
441
|
const displayGroup = inst.isHoistService
|
|
@@ -403,9 +447,29 @@ export class InstancesModel extends HoistModel {
|
|
|
403
447
|
: inst.isView
|
|
404
448
|
? 'Views'
|
|
405
449
|
: 'Models';
|
|
406
|
-
data.push({...inst, displayGroup});
|
|
450
|
+
data.push({...inst, displayGroup, isFavorite, alive: true});
|
|
407
451
|
});
|
|
408
452
|
|
|
453
|
+
// Favorites with no live instance - shown so they can be seen and un-starred.
|
|
454
|
+
if (favoritesOnly && !selectedSyncRun) {
|
|
455
|
+
const aliveKeys = new Set(data.map(favoriteKey));
|
|
456
|
+
favorites
|
|
457
|
+
.filter(key => !aliveKeys.has(key))
|
|
458
|
+
.forEach(key => {
|
|
459
|
+
const sep = key.indexOf(':'),
|
|
460
|
+
className = key.slice(0, sep),
|
|
461
|
+
xhName = key.slice(sep + 1);
|
|
462
|
+
data.push({
|
|
463
|
+
id: key,
|
|
464
|
+
className,
|
|
465
|
+
xhName,
|
|
466
|
+
displayGroup: 'Not Alive',
|
|
467
|
+
isFavorite: true,
|
|
468
|
+
alive: false
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
409
473
|
instancesGridModel.loadData(data);
|
|
410
474
|
}
|
|
411
475
|
});
|
|
@@ -482,8 +546,7 @@ export class InstancesModel extends HoistModel {
|
|
|
482
546
|
return null;
|
|
483
547
|
|
|
484
548
|
const {xhId} = instance,
|
|
485
|
-
|
|
486
|
-
instanceDisplayName = `${ctorName} [${xhId}]`,
|
|
549
|
+
instanceDisplayName = instanceLabel(instance),
|
|
487
550
|
isLoadedGetter = isGetter && this.shouldLoadGetter(xhId, property),
|
|
488
551
|
v = !isGetter || isLoadedGetter ? instance[property] : null,
|
|
489
552
|
// Detect FormModel.values Proxy object - throws otherwise on attempt to render in grid.
|
|
@@ -554,7 +617,11 @@ export class InstancesModel extends HoistModel {
|
|
|
554
617
|
}
|
|
555
618
|
}
|
|
556
619
|
|
|
557
|
-
const GROUP_SORT_ORDER = ['Models', 'Services', 'Cubes', 'Views', 'Stores'];
|
|
620
|
+
const GROUP_SORT_ORDER = ['Models', 'Services', 'Cubes', 'Views', 'Stores', 'Not Alive'];
|
|
621
|
+
|
|
622
|
+
/** Persistent identity for Favorites - null when the instance has no `xhName` to pin by. */
|
|
623
|
+
const favoriteKey = (inst: {className?: string; xhName?: string}): string =>
|
|
624
|
+
inst?.xhName ? `${inst.className}:${inst.xhName}` : null;
|
|
558
625
|
|
|
559
626
|
const timestampRenderer = v => fmtDate(v, {fmt: 'HH:mm:ss.SSS'});
|
|
560
627
|
|
|
@@ -132,6 +132,12 @@ const instanceGridBar = hoistCmp.factory<InstancesModel>(({model}) => {
|
|
|
132
132
|
value: 'showXhImpl',
|
|
133
133
|
tooltip:
|
|
134
134
|
'Show instances created as part of internal Hoist model/component implementations'
|
|
135
|
+
}),
|
|
136
|
+
button({
|
|
137
|
+
text: 'Favorites',
|
|
138
|
+
value: 'favoritesOnly',
|
|
139
|
+
tooltip:
|
|
140
|
+
'Show only favorited instances, including any not currently alive. Star any instance with an xhName to favorite it - favorites persist across reloads.'
|
|
135
141
|
})
|
|
136
142
|
]
|
|
137
143
|
}),
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import {elementFactory} from '@xh/hoist/core';
|
|
8
8
|
import {ComponentType} from 'react';
|
|
9
|
-
import {DayPicker} from 'react
|
|
10
|
-
import 'react
|
|
9
|
+
import {DayPicker} from '@daypicker/react';
|
|
10
|
+
import '@daypicker/react/style.css';
|
|
11
11
|
|
|
12
12
|
export {DayPicker};
|
|
13
|
-
export type {DayPickerProps, Matcher} from 'react
|
|
13
|
+
export type {DayPickerProps, Matcher} from '@daypicker/react';
|
|
14
14
|
|
|
15
15
|
// DayPicker's props are a discriminated union over its selection modes. Cast to ComponentType to
|
|
16
16
|
// keep our element factory ergonomic and produce portable type declarations.
|
|
@@ -52,6 +52,7 @@ export const loginPanel = hoistCmp.factory({
|
|
|
52
52
|
bind: 'username',
|
|
53
53
|
leftIcon: Icon.user(),
|
|
54
54
|
autoComplete: 'username',
|
|
55
|
+
enablePasswordManagers: true,
|
|
55
56
|
autoCapitalize: 'none',
|
|
56
57
|
commitOnChange: true,
|
|
57
58
|
testId: 'xh-login-username'
|
|
@@ -64,6 +65,7 @@ export const loginPanel = hoistCmp.factory({
|
|
|
64
65
|
leftIcon: Icon.lock(),
|
|
65
66
|
type: 'password',
|
|
66
67
|
autoComplete: 'current-password',
|
|
68
|
+
enablePasswordManagers: true,
|
|
67
69
|
commitOnChange: true,
|
|
68
70
|
testId: 'xh-login-password'
|
|
69
71
|
})
|