@xh/hoist 87.1.1 → 87.3.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 +108 -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/grid/impl/ColumnWidthCalculator.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/desktop/hooks/UseHotkeys.d.ts +4 -3
- 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 +8 -2
- 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/clock/Clock.ts +1 -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/grid/impl/ColumnWidthCalculator.ts +5 -10
- 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/grid/editors/DateEditor.ts +11 -2
- 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 +57 -5
- 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/desktop/cmp/toolbar/Toolbar.scss +20 -6
- package/desktop/hooks/UseHotkeys.ts +41 -12
- 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 +20 -8
- 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
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import {FormModel} from '@xh/hoist/cmp/form';
|
|
8
8
|
import {placeholder, span} from '@xh/hoist/cmp/layout';
|
|
9
9
|
import {tabContainer, TabContainerModel, TabConfig} from '@xh/hoist/cmp/tab';
|
|
10
|
-
import {
|
|
10
|
+
import {readonlyJsonInput} from '@xh/hoist/admin/AdminUtils';
|
|
11
|
+
import {creates, hoistCmp, HoistModel, managed, PlainObject, XH} from '@xh/hoist/core';
|
|
11
12
|
import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
12
13
|
import {
|
|
13
14
|
CodeInputLineStyles,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
textInput
|
|
18
19
|
} from '@xh/hoist/desktop/cmp/input';
|
|
19
20
|
import {Icon} from '@xh/hoist/icon';
|
|
20
|
-
import {makeObservable} from '@xh/hoist/mobx';
|
|
21
|
+
import {makeObservable, observable} from '@xh/hoist/mobx';
|
|
21
22
|
import classNames from 'classnames';
|
|
22
23
|
import {isPlainObject, last, union} from 'lodash';
|
|
23
24
|
import {ReactElement} from 'react';
|
|
@@ -25,9 +26,13 @@ import {buildResolvedJson, changedKeysFromStored} from './ConfigUtils';
|
|
|
25
26
|
import './ConfigValue.scss';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
|
-
* Presentation of a config's value
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* Presentation of a config's value, bound to the `value` field of an enclosing Form. Plain configs
|
|
30
|
+
* render a single editor by type; configs with a typedClass and/or an active instance-config
|
|
31
|
+
* override render a tab set over the applicable views of the value.
|
|
32
|
+
*
|
|
33
|
+
* Used within the RestGrid editor dialog (editable, opening on the Database tab) and the docked
|
|
34
|
+
* detail panel (read-only, opening on the most-derived view). Pass `height` for a fixed-height
|
|
35
|
+
* display, or omit it to fill the available space.
|
|
31
36
|
*/
|
|
32
37
|
export const configValue = hoistCmp.factory<ConfigValueModel>({
|
|
33
38
|
displayName: 'ConfigValue',
|
|
@@ -35,22 +40,28 @@ export const configValue = hoistCmp.factory<ConfigValueModel>({
|
|
|
35
40
|
model: creates(() => new ConfigValueModel()),
|
|
36
41
|
|
|
37
42
|
render({model, className}) {
|
|
43
|
+
const {height} = model;
|
|
44
|
+
className = classNames(className, height == null ? 'xh-config-value--fill' : null);
|
|
38
45
|
return model.usesTabs
|
|
39
46
|
? tabContainer({model: model.tabContainerModel, className})
|
|
40
|
-
: valueFormField(model.valueType,
|
|
47
|
+
: valueFormField(model.valueType, height, className);
|
|
41
48
|
}
|
|
42
49
|
});
|
|
43
50
|
|
|
44
51
|
class ConfigValueModel extends HoistModel {
|
|
45
52
|
override xhImpl = true;
|
|
46
53
|
|
|
47
|
-
@managed tabContainerModel: TabContainerModel;
|
|
54
|
+
@managed @observable.ref tabContainerModel: TabContainerModel;
|
|
48
55
|
|
|
49
56
|
get formModel(): FormModel {
|
|
50
57
|
return this.componentProps.formModel;
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
/** Fixed height for the value display, or null to fill available space. */
|
|
60
|
+
get height(): number | null {
|
|
61
|
+
return this.componentProps.height ?? null;
|
|
62
|
+
}
|
|
63
|
+
get readonly(): boolean {
|
|
64
|
+
return this.formModel?.readonly ?? false;
|
|
54
65
|
}
|
|
55
66
|
get valueField() {
|
|
56
67
|
return this.formModel?.fields?.value;
|
|
@@ -85,16 +96,77 @@ class ConfigValueModel extends HoistModel {
|
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
override onLinked() {
|
|
88
|
-
|
|
99
|
+
// Rebuild the tab set whenever the bound data changes - a new record selected into a
|
|
100
|
+
// shared FormModel (detail panel) or the same one re-saved. Tracks the value field's
|
|
101
|
+
// initialValue, not its live value, so typing in the editor does not tear down the tabs.
|
|
102
|
+
this.addReaction({
|
|
103
|
+
track: () => [
|
|
104
|
+
this.resolvedValue,
|
|
105
|
+
this.defaultValue,
|
|
106
|
+
this.overrideValue,
|
|
107
|
+
this.valueType,
|
|
108
|
+
this.valueField?.initialValue
|
|
109
|
+
],
|
|
110
|
+
run: () => this.buildTabs(),
|
|
111
|
+
fireImmediately: true
|
|
112
|
+
});
|
|
89
113
|
}
|
|
90
114
|
|
|
91
115
|
private buildTabs() {
|
|
92
|
-
|
|
116
|
+
XH.safeDestroy(this.tabContainerModel);
|
|
117
|
+
this.tabContainerModel = null;
|
|
118
|
+
if (!this.usesTabs) return;
|
|
119
|
+
|
|
120
|
+
const {
|
|
121
|
+
resolvedValue,
|
|
122
|
+
defaultValue,
|
|
123
|
+
overrideValue,
|
|
124
|
+
valueType,
|
|
125
|
+
valueField,
|
|
126
|
+
height,
|
|
127
|
+
readonly
|
|
128
|
+
} = this,
|
|
93
129
|
hasOverride = overrideValue != null,
|
|
94
130
|
hasResolved = resolvedValue != null,
|
|
95
131
|
hasDefaults = defaultValue != null,
|
|
96
132
|
tabs: TabConfig[] = [];
|
|
97
133
|
|
|
134
|
+
// Tabs run least- to most-derived: Defaults, Database, Instance, Resolved.
|
|
135
|
+
if (hasDefaults) {
|
|
136
|
+
tabs.push({
|
|
137
|
+
id: 'defaults',
|
|
138
|
+
title: 'Defaults',
|
|
139
|
+
icon: Icon.code(),
|
|
140
|
+
content: () =>
|
|
141
|
+
jsonInput({
|
|
142
|
+
value: JSON.stringify(defaultValue),
|
|
143
|
+
readonly: true,
|
|
144
|
+
autoFormat: true,
|
|
145
|
+
enableSearch: true,
|
|
146
|
+
className: 'xh-config-value__defaults',
|
|
147
|
+
...sizeProps(height)
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
tabs.push({
|
|
153
|
+
id: 'db',
|
|
154
|
+
title: hasOverride
|
|
155
|
+
? span({className: 'xh-config-value__overridden', item: 'Database'})
|
|
156
|
+
: 'Database',
|
|
157
|
+
icon: Icon.edit(),
|
|
158
|
+
content: () => valueFormField(valueType, height)
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (hasOverride) {
|
|
162
|
+
tabs.push({
|
|
163
|
+
id: 'instance',
|
|
164
|
+
title: 'Instance',
|
|
165
|
+
icon: Icon.warning({intent: 'warning'}),
|
|
166
|
+
content: () => readonlyValue(valueType, overrideValue, height)
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
98
170
|
// Resolved - effective value with typedClass defaults applied.
|
|
99
171
|
if (hasResolved) {
|
|
100
172
|
// Highlight keys explicitly set in the database value or an instance override - all
|
|
@@ -111,50 +183,15 @@ class ConfigValueModel extends HoistModel {
|
|
|
111
183
|
id: 'resolved',
|
|
112
184
|
title: 'Resolved',
|
|
113
185
|
icon: Icon.bolt(),
|
|
114
|
-
content: () => resolvedTab({text, lineStyles, height})
|
|
186
|
+
content: () => resolvedTab({text, lineStyles, ...sizeProps(height)})
|
|
115
187
|
});
|
|
116
188
|
}
|
|
117
189
|
|
|
118
|
-
if
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
icon: Icon.warning({intent: 'warning'}),
|
|
123
|
-
content: () => readonlyValue(valueType, overrideValue, height)
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
tabs.push({
|
|
128
|
-
id: 'db',
|
|
129
|
-
title: hasOverride
|
|
130
|
-
? span({className: 'xh-config-value__overridden', item: 'Database'})
|
|
131
|
-
: 'Database',
|
|
132
|
-
icon: Icon.edit(),
|
|
133
|
-
content: () => valueFormField(valueType, height)
|
|
190
|
+
// Open on Database if editable, else the most-derived view.
|
|
191
|
+
this.tabContainerModel = new TabContainerModel({
|
|
192
|
+
defaultTabId: readonly ? last(tabs).id : 'db',
|
|
193
|
+
tabs
|
|
134
194
|
});
|
|
135
|
-
|
|
136
|
-
// Defaults - the typedClass defaults as declared in code.
|
|
137
|
-
if (hasDefaults) {
|
|
138
|
-
tabs.push({
|
|
139
|
-
id: 'defaults',
|
|
140
|
-
title: 'Defaults',
|
|
141
|
-
icon: Icon.code(),
|
|
142
|
-
content: () =>
|
|
143
|
-
jsonInput({
|
|
144
|
-
value: JSON.stringify(defaultValue),
|
|
145
|
-
readonly: true,
|
|
146
|
-
autoFormat: true,
|
|
147
|
-
enableSearch: true,
|
|
148
|
-
className: 'xh-config-value__defaults',
|
|
149
|
-
height
|
|
150
|
-
})
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Built most- to least-derived above, but displayed the other way round - opening on the
|
|
155
|
-
// last tab, i.e. the most derived view available.
|
|
156
|
-
tabs.reverse();
|
|
157
|
-
this.tabContainerModel = new TabContainerModel({defaultTabId: last(tabs).id, tabs});
|
|
158
195
|
}
|
|
159
196
|
}
|
|
160
197
|
|
|
@@ -182,7 +219,11 @@ const resolvedTab = hoistCmp.factory<ConfigValueModel>(({model, text, lineStyles
|
|
|
182
219
|
|
|
183
220
|
// Label-less FormField for `value`, bound via the enclosing Form context for standard validation
|
|
184
221
|
// display and read-only rendering. The plain branch passes `className` for the full-width rule.
|
|
185
|
-
function valueFormField(
|
|
222
|
+
function valueFormField(
|
|
223
|
+
valueType: string,
|
|
224
|
+
height: number | null,
|
|
225
|
+
className?: string
|
|
226
|
+
): ReactElement {
|
|
186
227
|
return formField({
|
|
187
228
|
field: 'value',
|
|
188
229
|
label: null,
|
|
@@ -193,13 +234,13 @@ function valueFormField(valueType: string, height: number, className?: string):
|
|
|
193
234
|
}
|
|
194
235
|
|
|
195
236
|
// Editable input for a config value, by type. Bound by the enclosing FormField.
|
|
196
|
-
function valueInput(valueType: string, height: number): ReactElement {
|
|
237
|
+
function valueInput(valueType: string, height: number | null): ReactElement {
|
|
197
238
|
switch (valueType) {
|
|
198
239
|
case 'json':
|
|
199
240
|
return jsonInput({
|
|
200
241
|
autoFormat: true,
|
|
201
242
|
enableSearch: true,
|
|
202
|
-
height
|
|
243
|
+
...sizeProps(height)
|
|
203
244
|
});
|
|
204
245
|
case 'bool':
|
|
205
246
|
return select({options: [true, false], enableClear: false});
|
|
@@ -217,24 +258,22 @@ function valueInput(valueType: string, height: number): ReactElement {
|
|
|
217
258
|
}
|
|
218
259
|
|
|
219
260
|
// Read-only display of a raw stored value, by type. Masks pwd.
|
|
220
|
-
function readonlyValue(valueType: string, value: any, height: number): ReactElement {
|
|
261
|
+
function readonlyValue(valueType: string, value: any, height: number | null): ReactElement {
|
|
221
262
|
switch (valueType) {
|
|
222
263
|
case 'json':
|
|
223
|
-
return
|
|
224
|
-
value,
|
|
225
|
-
readonly: true,
|
|
226
|
-
autoFormat: true,
|
|
227
|
-
enableSearch: true,
|
|
228
|
-
width: null,
|
|
229
|
-
height
|
|
230
|
-
});
|
|
264
|
+
return readonlyJsonInput(value, height);
|
|
231
265
|
case 'pwd':
|
|
232
|
-
return
|
|
266
|
+
return span(value == null ? '' : '*****');
|
|
233
267
|
default:
|
|
234
|
-
return
|
|
268
|
+
return span(value?.toString() ?? '');
|
|
235
269
|
}
|
|
236
270
|
}
|
|
237
271
|
|
|
272
|
+
// Layout props for a JSON editor - fixed to `height` if given, otherwise filling its container.
|
|
273
|
+
function sizeProps(height: number | null): PlainObject {
|
|
274
|
+
return height != null ? {height} : {flex: 1, height: '100%', width: '100%'};
|
|
275
|
+
}
|
|
276
|
+
|
|
238
277
|
// Muting styles for pre-rendered JSON `text` - every line NOT in `highlightLines`.
|
|
239
278
|
function mutedLineStyles(text: string, highlightLines: number[]): CodeInputLineStyles[] {
|
|
240
279
|
const changed = new Set(highlightLines),
|
|
@@ -0,0 +1,93 @@
|
|
|
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 {jsonRenderer, yesNoRenderer} from '@xh/hoist/admin/AdminUtils';
|
|
8
|
+
import {badgeRenderer} from '@xh/hoist/admin/columns';
|
|
9
|
+
import {restDetailPanel} from '@xh/hoist/admin/detail/RestDetailPanel';
|
|
10
|
+
import {formFieldSet} from '@xh/hoist/cmp/form';
|
|
11
|
+
import {hbox} from '@xh/hoist/cmp/layout';
|
|
12
|
+
import {hoistCmp, uses} from '@xh/hoist/core';
|
|
13
|
+
import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
14
|
+
import {Icon} from '@xh/hoist/icon';
|
|
15
|
+
import {archivedDateRenderer} from './JsonBlobColumns';
|
|
16
|
+
import {JsonBlobModel} from './JsonBlobModel';
|
|
17
|
+
|
|
18
|
+
/** Read-only detail view of the JSON Blob selected in the grid. */
|
|
19
|
+
export const jsonBlobDetailPanel = hoistCmp.factory<JsonBlobModel>({
|
|
20
|
+
displayName: 'JsonBlobDetailPanel',
|
|
21
|
+
model: uses(JsonBlobModel),
|
|
22
|
+
|
|
23
|
+
render({model}) {
|
|
24
|
+
return restDetailPanel({
|
|
25
|
+
icon: Icon.json(),
|
|
26
|
+
emptyText: 'Select a blob to view its details.',
|
|
27
|
+
persistWith: {...model.persistWith, path: 'detailPanel'},
|
|
28
|
+
renderForm: (record, formModel) => {
|
|
29
|
+
const {description, meta, archived} = formModel.values,
|
|
30
|
+
// Meta is stored as JSON text - a serialized null is as empty as no value.
|
|
31
|
+
hasMeta = meta != null && meta !== 'null';
|
|
32
|
+
return [
|
|
33
|
+
formFieldSet({
|
|
34
|
+
title: 'Blob',
|
|
35
|
+
items: [
|
|
36
|
+
hbox(
|
|
37
|
+
formField({field: 'type', flex: 1}),
|
|
38
|
+
formField({field: 'owner', flex: 1}),
|
|
39
|
+
formField({field: 'acl', flex: 1})
|
|
40
|
+
),
|
|
41
|
+
formField({field: 'description', omit: !description}),
|
|
42
|
+
hbox(
|
|
43
|
+
formField({
|
|
44
|
+
field: 'token',
|
|
45
|
+
readonlyRenderer: badgeRenderer,
|
|
46
|
+
flex: 1
|
|
47
|
+
}),
|
|
48
|
+
formField({
|
|
49
|
+
field: 'archived',
|
|
50
|
+
readonlyRenderer: yesNoRenderer,
|
|
51
|
+
flex: 1
|
|
52
|
+
}),
|
|
53
|
+
formField({
|
|
54
|
+
field: 'archivedDate',
|
|
55
|
+
readonlyRenderer: archivedDateRenderer,
|
|
56
|
+
omit: !archived,
|
|
57
|
+
flex: 1
|
|
58
|
+
})
|
|
59
|
+
),
|
|
60
|
+
hbox(
|
|
61
|
+
formField({field: 'dateCreated', label: 'Created', flex: 1}),
|
|
62
|
+
formField({field: 'lastUpdated', label: 'Updated', flex: 1}),
|
|
63
|
+
formField({field: 'lastUpdatedBy', label: 'Updated By', flex: 1})
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}),
|
|
67
|
+
// Value and Meta share the remaining height 3:2, favoring the value.
|
|
68
|
+
formFieldSet({
|
|
69
|
+
title: 'Value',
|
|
70
|
+
className: 'xh-admin-readonly-form__fill',
|
|
71
|
+
flexGrow: 3,
|
|
72
|
+
item: formField({
|
|
73
|
+
field: 'value',
|
|
74
|
+
label: null,
|
|
75
|
+
readonlyRenderer: jsonRenderer
|
|
76
|
+
})
|
|
77
|
+
}),
|
|
78
|
+
formFieldSet({
|
|
79
|
+
title: 'Meta',
|
|
80
|
+
className: 'xh-admin-readonly-form__fill',
|
|
81
|
+
flexGrow: 2,
|
|
82
|
+
omit: !hasMeta,
|
|
83
|
+
item: formField({
|
|
84
|
+
field: 'meta',
|
|
85
|
+
label: null,
|
|
86
|
+
readonlyRenderer: jsonRenderer
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
@@ -68,6 +68,10 @@ export class JsonBlobModel extends HoistModel {
|
|
|
68
68
|
{...(Col.lastUpdatedBy.field as FieldSpec), editable: false}
|
|
69
69
|
]
|
|
70
70
|
},
|
|
71
|
+
onRowDoubleClicked: ({data}) => {
|
|
72
|
+
if (data && !this.gridModel.readonly) this.gridModel.editRecord(data);
|
|
73
|
+
},
|
|
74
|
+
toolbarActions: [addAction, editAction, cloneAction, deleteAction],
|
|
71
75
|
menuActions: [addAction, editAction, cloneAction, deleteAction],
|
|
72
76
|
prepareCloneFn: ({clone}) => (clone.name = `${clone.name}_CLONE`),
|
|
73
77
|
sortBy: ['owner', 'name'],
|
|
@@ -16,6 +16,7 @@ import {restGrid} from '@xh/hoist/desktop/cmp/rest';
|
|
|
16
16
|
import {toolbarSep} from '@xh/hoist/desktop/cmp/toolbar';
|
|
17
17
|
import {Icon} from '@xh/hoist/icon';
|
|
18
18
|
import {differ} from '../../../differ/Differ';
|
|
19
|
+
import {jsonBlobDetailPanel} from './JsonBlobDetailPanel';
|
|
19
20
|
import {JsonBlobModel} from './JsonBlobModel';
|
|
20
21
|
|
|
21
22
|
export const jsonBlobPanel = hoistCmp.factory({
|
|
@@ -64,6 +65,7 @@ export const jsonBlobPanel = hoistCmp.factory({
|
|
|
64
65
|
]
|
|
65
66
|
})
|
|
66
67
|
}),
|
|
68
|
+
jsonBlobDetailPanel(),
|
|
67
69
|
differ({omit: !model.differModel})
|
|
68
70
|
);
|
|
69
71
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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 {jsonRenderer, rawValueRenderer} from '@xh/hoist/admin/AdminUtils';
|
|
8
|
+
import {valueTypeRenderer} from '@xh/hoist/admin/columns';
|
|
9
|
+
import {restDetailPanel} from '@xh/hoist/admin/detail/RestDetailPanel';
|
|
10
|
+
import {formFieldSet} from '@xh/hoist/cmp/form';
|
|
11
|
+
import {hbox} from '@xh/hoist/cmp/layout';
|
|
12
|
+
import {hoistCmp, uses} from '@xh/hoist/core';
|
|
13
|
+
import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
14
|
+
import {Icon} from '@xh/hoist/icon';
|
|
15
|
+
import {UserPreferenceModel} from './UserPreferenceModel';
|
|
16
|
+
|
|
17
|
+
/** Read-only detail view of the user preference value selected in the grid. */
|
|
18
|
+
export const userPreferenceDetailPanel = hoistCmp.factory<UserPreferenceModel>({
|
|
19
|
+
displayName: 'UserPreferenceDetailPanel',
|
|
20
|
+
model: uses(UserPreferenceModel),
|
|
21
|
+
|
|
22
|
+
render({model}) {
|
|
23
|
+
return restDetailPanel({
|
|
24
|
+
icon: Icon.bookmark(),
|
|
25
|
+
emptyText: 'Select a user preference to view its details.',
|
|
26
|
+
persistWith: {...model.persistWith, path: 'detailPanel'},
|
|
27
|
+
renderForm: (record, formModel) => {
|
|
28
|
+
const {type} = formModel.values,
|
|
29
|
+
isJson = type === 'json';
|
|
30
|
+
return [
|
|
31
|
+
formFieldSet({
|
|
32
|
+
title: 'Preference',
|
|
33
|
+
items: [
|
|
34
|
+
hbox(
|
|
35
|
+
formField({field: 'username', flex: 1}),
|
|
36
|
+
formField({field: 'groupName', flex: 1}),
|
|
37
|
+
formField({
|
|
38
|
+
field: 'type',
|
|
39
|
+
readonlyRenderer: valueTypeRenderer,
|
|
40
|
+
flex: 1
|
|
41
|
+
})
|
|
42
|
+
),
|
|
43
|
+
hbox(
|
|
44
|
+
formField({field: 'lastUpdatedBy', label: 'Updated By', flex: 1}),
|
|
45
|
+
formField({field: 'lastUpdated', label: 'Updated', flex: 2})
|
|
46
|
+
)
|
|
47
|
+
]
|
|
48
|
+
}),
|
|
49
|
+
formFieldSet({
|
|
50
|
+
title: 'Value',
|
|
51
|
+
className: isJson ? 'xh-admin-readonly-form__fill' : null,
|
|
52
|
+
item: formField({
|
|
53
|
+
field: 'userValue',
|
|
54
|
+
label: null,
|
|
55
|
+
readonlyRenderer: isJson ? jsonRenderer : rawValueRenderer
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
@@ -9,10 +9,12 @@ import {AppModel} from '@xh/hoist/admin/AppModel';
|
|
|
9
9
|
import * as Col from '@xh/hoist/admin/columns';
|
|
10
10
|
import {HoistModel, LoadSpec, managed, XH} from '@xh/hoist/core';
|
|
11
11
|
import {FieldSpec} from '@xh/hoist/data';
|
|
12
|
-
import {RestGridModel} from '@xh/hoist/desktop/cmp/rest';
|
|
12
|
+
import {addAction, deleteAction, editAction, RestGridModel} from '@xh/hoist/desktop/cmp/rest';
|
|
13
13
|
import {bindable, makeObservable} from '@xh/hoist/mobx';
|
|
14
14
|
|
|
15
15
|
export class UserPreferenceModel extends HoistModel {
|
|
16
|
+
override persistWith = {localStorageKey: 'xhAdminUserPreferenceState'};
|
|
17
|
+
|
|
16
18
|
@managed gridModel: RestGridModel;
|
|
17
19
|
|
|
18
20
|
@bindable showEditorDialog: boolean = false;
|
|
@@ -32,11 +34,16 @@ export class UserPreferenceModel extends HoistModel {
|
|
|
32
34
|
exportOptions: {filename: exportFilenameWithDate('user-prefs')},
|
|
33
35
|
filterFields: ['name', 'username'],
|
|
34
36
|
groupBy: 'groupName',
|
|
35
|
-
persistWith:
|
|
37
|
+
persistWith: this.persistWith,
|
|
36
38
|
readonly: AppModel.readonly,
|
|
37
39
|
selModel: 'multiple',
|
|
38
40
|
sortBy: 'name',
|
|
39
41
|
unit: 'user preference',
|
|
42
|
+
onRowDoubleClicked: ({data}) => {
|
|
43
|
+
if (data && !this.gridModel.readonly) this.gridModel.editRecord(data);
|
|
44
|
+
},
|
|
45
|
+
toolbarActions: [addAction, editAction, deleteAction],
|
|
46
|
+
menuActions: [addAction, editAction, deleteAction],
|
|
40
47
|
// Store + fields
|
|
41
48
|
store: {
|
|
42
49
|
url: 'rest/userPreferenceAdmin',
|
|
@@ -65,7 +72,7 @@ export class UserPreferenceModel extends HoistModel {
|
|
|
65
72
|
// Cols + editors
|
|
66
73
|
columns: [
|
|
67
74
|
{...Col.name},
|
|
68
|
-
{...Col.type},
|
|
75
|
+
{...Col.type, renderer: Col.valueTypeRenderer, align: 'center'},
|
|
69
76
|
{...Col.username},
|
|
70
77
|
{...Col.groupName, hidden},
|
|
71
78
|
{...Col.userValue},
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import * as Col from '@xh/hoist/admin/columns/Rest';
|
|
9
9
|
import * as AdminCol from '@xh/hoist/admin/columns';
|
|
10
10
|
import {prefEditorDialog} from '@xh/hoist/admin/tabs/userData/prefs/editor/PrefEditorDialog';
|
|
11
|
+
import {userPreferenceDetailPanel} from '@xh/hoist/admin/tabs/userData/prefs/UserPreferenceDetailPanel';
|
|
11
12
|
import {UserPreferenceModel} from '@xh/hoist/admin/tabs/userData/prefs/UserPreferenceModel';
|
|
12
13
|
import {hframe} from '@xh/hoist/cmp/layout';
|
|
13
14
|
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
@@ -59,7 +60,8 @@ export const userPreferencePanel = hoistCmp.factory({
|
|
|
59
60
|
prefEditorDialog()
|
|
60
61
|
],
|
|
61
62
|
mask: 'onLoad'
|
|
62
|
-
})
|
|
63
|
+
}),
|
|
64
|
+
userPreferenceDetailPanel()
|
|
63
65
|
);
|
|
64
66
|
}
|
|
65
67
|
});
|
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
.xh-admin-role-details {
|
|
2
2
|
&__form {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
.xh-form-field {
|
|
6
|
-
margin: 0;
|
|
7
|
-
padding: 2px var(--xh-pad-px);
|
|
8
|
-
|
|
9
|
-
&__label {
|
|
10
|
-
font-size: var(--xh-font-size-small-px);
|
|
11
|
-
padding: 0;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
&__readonly-display {
|
|
15
|
-
padding: var(--xh-pad-half-px);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&:nth-child(odd) {
|
|
19
|
-
background-color: var(--xh-grid-bg-odd);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
3
|
+
flex: none;
|
|
4
|
+
margin: var(--xh-pad-px);
|
|
22
5
|
}
|
|
23
6
|
}
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2026 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import {valOrNa} from '@xh/hoist/admin/AdminUtils';
|
|
8
|
+
import {form, formFieldSet} from '@xh/hoist/cmp/form';
|
|
9
|
+
import {frame, hbox, placeholder, vframe} from '@xh/hoist/cmp/layout';
|
|
9
10
|
import {tabContainer} from '@xh/hoist/cmp/tab';
|
|
10
11
|
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
11
12
|
import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
@@ -31,21 +32,20 @@ export const roleDetails = hoistCmp.factory({
|
|
|
31
32
|
|
|
32
33
|
const details = hoistCmp.factory(() =>
|
|
33
34
|
form({
|
|
34
|
-
fieldDefaults: {
|
|
35
|
-
item:
|
|
36
|
-
|
|
35
|
+
fieldDefaults: {readonlyRenderer: valOrNa},
|
|
36
|
+
item: formFieldSet({
|
|
37
|
+
title: 'Role',
|
|
38
|
+
className: 'xh-admin-role-details__form xh-admin-readonly-form',
|
|
37
39
|
items: [
|
|
38
|
-
formField({field: 'name'}),
|
|
39
|
-
formField({field: 'category'}),
|
|
40
|
+
hbox(formField({field: 'name', flex: 1}), formField({field: 'category', flex: 1})),
|
|
40
41
|
formField({
|
|
41
42
|
field: 'notes',
|
|
42
|
-
readonlyRenderer: v =>
|
|
43
|
-
|
|
43
|
+
readonlyRenderer: v =>
|
|
44
|
+
frame({
|
|
44
45
|
style: {overflowY: 'auto'},
|
|
45
|
-
|
|
46
|
-
item: v
|
|
47
|
-
})
|
|
48
|
-
}
|
|
46
|
+
maxHeight: 80,
|
|
47
|
+
item: valOrNa(v)
|
|
48
|
+
})
|
|
49
49
|
}),
|
|
50
50
|
formField({field: 'lastUpdated'})
|
|
51
51
|
]
|
|
@@ -71,6 +71,8 @@ import {installServicesAsync} from '../core/impl/InstallServices';
|
|
|
71
71
|
* Root object for Framework GUI State.
|
|
72
72
|
*/
|
|
73
73
|
export class AppContainerModel extends HoistModel {
|
|
74
|
+
override xhName = 'appContainerModel';
|
|
75
|
+
|
|
74
76
|
override telemetryPrefix = 'xh.client';
|
|
75
77
|
|
|
76
78
|
private initCalled = false;
|
|
@@ -338,6 +340,7 @@ export class AppContainerModel extends HoistModel {
|
|
|
338
340
|
// App init phase
|
|
339
341
|
this.setAppState('INITIALIZING_APP');
|
|
340
342
|
this.appModel = createSingleton(this.appSpec.modelClass);
|
|
343
|
+
this.appModel.xhName ??= 'appModel';
|
|
341
344
|
await this.runner(ctx)
|
|
342
345
|
.span('appInit')
|
|
343
346
|
.run(ctx => this.appModel.initAsync(ctx as InitContext));
|
|
@@ -15,6 +15,7 @@ import {bindable, makeObservable} from '@xh/hoist/mobx';
|
|
|
15
15
|
*/
|
|
16
16
|
export class ColChooserOptionsModel extends HoistModel {
|
|
17
17
|
override xhImpl = true;
|
|
18
|
+
override xhName = 'colChooserOptionsModel';
|
|
18
19
|
override persistWith = {localStorageKey: 'xhColChooser'};
|
|
19
20
|
|
|
20
21
|
@bindable showGroups: boolean = true;
|
|
@@ -18,6 +18,7 @@ import {action, observable, makeObservable, bindable} from '@xh/hoist/mobx';
|
|
|
18
18
|
*/
|
|
19
19
|
export class ExceptionDialogModel extends HoistModel {
|
|
20
20
|
override xhImpl = true;
|
|
21
|
+
override xhName = 'exceptionDialogModel';
|
|
21
22
|
|
|
22
23
|
@observable.ref
|
|
23
24
|
displayData: {exception: HoistException; options: ExceptionHandlerOptions};
|