@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
|
@@ -11,21 +11,12 @@ import {
|
|
|
11
11
|
ActivityTrackingDataFieldSpec,
|
|
12
12
|
DataFieldsEditorModel
|
|
13
13
|
} from '@xh/hoist/admin/tabs/activity/tracking/datafields/DataFieldsEditorModel';
|
|
14
|
+
import {DateRangePickerModel} from '@xh/hoist/cmp/daterange';
|
|
14
15
|
import {FilterChooserModel} from '@xh/hoist/cmp/filter';
|
|
15
16
|
import {FormModel} from '@xh/hoist/cmp/form';
|
|
16
17
|
import {ColumnRenderer, ColumnSpec, GridModel, TreeStyle} from '@xh/hoist/cmp/grid';
|
|
17
18
|
import {GroupingChooserModel} from '@xh/hoist/cmp/grouping';
|
|
18
|
-
import {
|
|
19
|
-
HoistModel,
|
|
20
|
-
LoadSpec,
|
|
21
|
-
LocalDateUnit,
|
|
22
|
-
managed,
|
|
23
|
-
PersistableState,
|
|
24
|
-
PersistenceProvider,
|
|
25
|
-
persistOptions,
|
|
26
|
-
PlainObject,
|
|
27
|
-
XH
|
|
28
|
-
} from '@xh/hoist/core';
|
|
19
|
+
import {HoistModel, LoadSpec, managed, PlainObject, XH} from '@xh/hoist/core';
|
|
29
20
|
import {Cube, CubeFieldSpec, FieldSpec, getCubeLeaves, ViewRowData} from '@xh/hoist/data';
|
|
30
21
|
import {dateRenderer, dateTimeSecRenderer, numberRenderer} from '@xh/hoist/format';
|
|
31
22
|
import {action, computed, makeObservable, observable} from '@xh/hoist/mobx';
|
|
@@ -34,29 +25,15 @@ import {compact, get, isEmpty, isEqual, round} from 'lodash';
|
|
|
34
25
|
import moment from 'moment';
|
|
35
26
|
import {ActivityDetailProvider} from './detail/ActivityDetailModel';
|
|
36
27
|
|
|
37
|
-
/**
|
|
38
|
-
* A relative time interval (e.g. 7 days) ending on the current app day. Drives the quick-select
|
|
39
|
-
* buttons and the persisted time period, which rolls forward to end on today on restore.
|
|
40
|
-
*/
|
|
41
|
-
export interface ActivityInterval {
|
|
42
|
-
value: number;
|
|
43
|
-
unit: LocalDateUnit;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Quick-select intervals offered in the toolbar - labels are derived as `${value}${unit[0]}`. */
|
|
47
|
-
export const INTERVALS: ActivityInterval[] = [
|
|
48
|
-
{value: 6, unit: 'months'},
|
|
49
|
-
{value: 1, unit: 'months'},
|
|
50
|
-
{value: 7, unit: 'days'},
|
|
51
|
-
{value: 1, unit: 'days'}
|
|
52
|
-
];
|
|
53
|
-
|
|
54
28
|
export class ActivityTrackingModel extends HoistModel implements ActivityDetailProvider {
|
|
55
29
|
override telemetryPrefix = 'xh.client.admin.tracking';
|
|
56
30
|
|
|
57
31
|
/** FormModel for server-side querying controls. */
|
|
58
32
|
@managed formModel: FormModel;
|
|
59
33
|
|
|
34
|
+
/** Period to query, resolved against the current app day. */
|
|
35
|
+
@managed dateRangePickerModel: DateRangePickerModel;
|
|
36
|
+
|
|
60
37
|
/** Models for data-handling components - can be rebuilt due to change in dataFields. */
|
|
61
38
|
@managed @observable.ref groupingChooserModel: GroupingChooserModel;
|
|
62
39
|
@managed @observable.ref cube: Cube;
|
|
@@ -92,10 +69,6 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
92
69
|
return this.groupingChooserModel.value;
|
|
93
70
|
}
|
|
94
71
|
|
|
95
|
-
get endDay(): LocalDate {
|
|
96
|
-
return this.formModel.values.endDay;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
72
|
@computed
|
|
100
73
|
get hasFilter(): boolean {
|
|
101
74
|
return !!this.filterChooserModel.value;
|
|
@@ -142,7 +115,7 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
142
115
|
this.markPersist('showFilterChooser');
|
|
143
116
|
|
|
144
117
|
this.formModel = this.createQueryFormModel();
|
|
145
|
-
this.
|
|
118
|
+
this.dateRangePickerModel = this.createDateRangePickerModel();
|
|
146
119
|
|
|
147
120
|
this.dataFieldsEditorModel = new DataFieldsEditorModel(this);
|
|
148
121
|
this.markPersist('dataFields');
|
|
@@ -211,39 +184,6 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
211
184
|
this.showFilterChooser = !this.showFilterChooser;
|
|
212
185
|
}
|
|
213
186
|
|
|
214
|
-
adjustDates(dir: 'add' | 'subtract') {
|
|
215
|
-
const {startDay, endDay} = this.formModel.fields,
|
|
216
|
-
appDay = LocalDate.currentAppDay(),
|
|
217
|
-
start: LocalDate = startDay.value,
|
|
218
|
-
end: LocalDate = endDay.value,
|
|
219
|
-
diff = end.diff(start),
|
|
220
|
-
incr = diff + 1;
|
|
221
|
-
|
|
222
|
-
let newStart = start[dir](incr),
|
|
223
|
-
newEnd = end[dir](incr);
|
|
224
|
-
|
|
225
|
-
if (newEnd > appDay) {
|
|
226
|
-
newStart = appDay.subtract(Math.abs(diff));
|
|
227
|
-
newEnd = appDay;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
startDay.setValue(newStart);
|
|
231
|
-
endDay.setValue(newEnd);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Set the start date by taking the end date and pushing back the interval - then pushing
|
|
235
|
-
// forward one day as the day range query is inclusive.
|
|
236
|
-
adjustStartDate(interval: ActivityInterval) {
|
|
237
|
-
this.formModel.setValues({
|
|
238
|
-
startDay: this.endDay.subtract(interval.value, interval.unit).nextDay()
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
isInterval(interval: ActivityInterval) {
|
|
243
|
-
const {startDay, endDay} = this.formModel.values;
|
|
244
|
-
return startDay === endDay.subtract(interval.value, interval.unit).nextDay();
|
|
245
|
-
}
|
|
246
|
-
|
|
247
187
|
getDisplayName(fieldName: string) {
|
|
248
188
|
return fieldName ? (this.cube.store.getField(fieldName)?.displayName ?? fieldName) : null;
|
|
249
189
|
}
|
|
@@ -254,33 +194,26 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
254
194
|
private createQueryFormModel(): FormModel {
|
|
255
195
|
return new FormModel({
|
|
256
196
|
persistWith: {...this.persistWith, path: 'queryFormValues', includeFields: ['maxRows']},
|
|
257
|
-
fields: [
|
|
258
|
-
{name: 'startDay', initialValue: () => LocalDate.currentAppDay()},
|
|
259
|
-
{name: 'endDay', initialValue: () => LocalDate.currentAppDay()},
|
|
260
|
-
{name: 'maxRows', initialValue: XH.trackService.conf.maxRows?.default}
|
|
261
|
-
]
|
|
197
|
+
fields: [{name: 'maxRows', initialValue: XH.trackService.conf.maxRows?.default}]
|
|
262
198
|
});
|
|
263
199
|
}
|
|
264
200
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
201
|
+
private createDateRangePickerModel(): DateRangePickerModel {
|
|
202
|
+
return new DateRangePickerModel({
|
|
203
|
+
persistWith: this.persistWith,
|
|
204
|
+
presets: [
|
|
205
|
+
'anchorDay',
|
|
206
|
+
'prevDay',
|
|
207
|
+
'prev7Days',
|
|
208
|
+
'prev30Days',
|
|
209
|
+
'prev90Days',
|
|
210
|
+
'mtd',
|
|
211
|
+
'prevMonth',
|
|
212
|
+
'ytd'
|
|
213
|
+
],
|
|
214
|
+
initialValue: 'anchorDay',
|
|
215
|
+
// Track logs are stamped in the app time zone - follow its day, across midnight too.
|
|
216
|
+
anchorDay: 'appDay'
|
|
284
217
|
});
|
|
285
218
|
}
|
|
286
219
|
|
|
@@ -324,11 +257,11 @@ export class ActivityTrackingModel extends HoistModel implements ActivityDetailP
|
|
|
324
257
|
|
|
325
258
|
@computed
|
|
326
259
|
private get query() {
|
|
327
|
-
const {
|
|
260
|
+
const {start, end} = this.dateRangePickerModel.currentRange;
|
|
328
261
|
return {
|
|
329
|
-
startDay:
|
|
330
|
-
endDay:
|
|
331
|
-
maxRows: values.maxRows,
|
|
262
|
+
startDay: start,
|
|
263
|
+
endDay: end,
|
|
264
|
+
maxRows: this.formModel.values.maxRows,
|
|
332
265
|
filters: this.filterChooserModel.value
|
|
333
266
|
};
|
|
334
267
|
}
|
|
@@ -10,17 +10,17 @@ import {form} from '@xh/hoist/cmp/form';
|
|
|
10
10
|
import {grid} from '@xh/hoist/cmp/grid';
|
|
11
11
|
import {div, filler, hframe} from '@xh/hoist/cmp/layout';
|
|
12
12
|
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
13
|
-
import {button,
|
|
13
|
+
import {button, colChooserButton, exportButton} from '@xh/hoist/desktop/cmp/button';
|
|
14
|
+
import {dateRangePicker} from '@xh/hoist/desktop/cmp/daterange';
|
|
14
15
|
import {filterChooser} from '@xh/hoist/desktop/cmp/filter';
|
|
15
16
|
import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
16
17
|
import {groupingChooser} from '@xh/hoist/desktop/cmp/grouping';
|
|
17
|
-
import {
|
|
18
|
+
import {select} from '@xh/hoist/desktop/cmp/input';
|
|
18
19
|
import {panel} from '@xh/hoist/desktop/cmp/panel';
|
|
19
20
|
import {toolbar, toolbarSep} from '@xh/hoist/desktop/cmp/toolbar';
|
|
20
21
|
import {viewManager} from '@xh/hoist/desktop/cmp/viewmanager';
|
|
21
22
|
import {Icon} from '@xh/hoist/icon';
|
|
22
|
-
import {
|
|
23
|
-
import {INTERVALS, ActivityTrackingModel} from './ActivityTrackingModel';
|
|
23
|
+
import {ActivityTrackingModel} from './ActivityTrackingModel';
|
|
24
24
|
import {aggChartPanel} from '@xh/hoist/admin/tabs/activity/tracking/chart/AggChartPanel';
|
|
25
25
|
import {activityDetailView} from './detail/ActivityDetailView';
|
|
26
26
|
import './ActivityTracking.scss';
|
|
@@ -45,64 +45,33 @@ export const activityTrackingPanel = hoistCmp.factory({
|
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
const tbar = hoistCmp.factory<ActivityTrackingModel>(({model}) =>
|
|
49
|
-
|
|
50
|
-
return toolbar(
|
|
48
|
+
const tbar = hoistCmp.factory<ActivityTrackingModel>(({model}) =>
|
|
49
|
+
toolbar(
|
|
51
50
|
viewManager({
|
|
52
51
|
model: model.viewManagerModel,
|
|
53
52
|
showSaveButton: 'always'
|
|
54
53
|
}),
|
|
55
54
|
'-',
|
|
55
|
+
dateRangePicker({showStepButtons: true, testId: 'activity-period'}),
|
|
56
|
+
toolbarSep(),
|
|
57
|
+
filterChooserToggleButton(),
|
|
58
|
+
toolbarSep(),
|
|
59
|
+
dataFieldsEditor(),
|
|
60
|
+
filler(),
|
|
56
61
|
form({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
item: dateInput({...dateInputProps})
|
|
66
|
-
}),
|
|
67
|
-
Icon.caretRight(),
|
|
68
|
-
formField({
|
|
69
|
-
field: 'endDay',
|
|
70
|
-
item: dateInput({...dateInputProps})
|
|
71
|
-
}),
|
|
72
|
-
button({
|
|
73
|
-
icon: Icon.angleRight(),
|
|
74
|
-
onClick: () => model.adjustDates('add'),
|
|
75
|
-
disabled: model.endDay >= LocalDate.currentAppDay()
|
|
76
|
-
}),
|
|
77
|
-
buttonGroup({
|
|
78
|
-
items: INTERVALS.map(interval =>
|
|
79
|
-
button({
|
|
80
|
-
text: `${interval.value}${interval.unit[0]}`,
|
|
81
|
-
onClick: () => model.adjustStartDate(interval),
|
|
82
|
-
active: model.isInterval(interval),
|
|
83
|
-
...dateBtn
|
|
84
|
-
})
|
|
85
|
-
)
|
|
86
|
-
}),
|
|
87
|
-
toolbarSep(),
|
|
88
|
-
filterChooserToggleButton(),
|
|
89
|
-
toolbarSep(),
|
|
90
|
-
dataFieldsEditor(),
|
|
91
|
-
filler(),
|
|
92
|
-
formField({
|
|
93
|
-
field: 'maxRows',
|
|
94
|
-
label: 'Max rows',
|
|
95
|
-
width: 140,
|
|
96
|
-
item: select({
|
|
97
|
-
enableFilter: false,
|
|
98
|
-
hideDropdownIndicator: true,
|
|
99
|
-
options: model.maxRowOptions
|
|
100
|
-
})
|
|
62
|
+
item: formField({
|
|
63
|
+
field: 'maxRows',
|
|
64
|
+
label: 'Max rows',
|
|
65
|
+
width: 140,
|
|
66
|
+
item: select({
|
|
67
|
+
enableFilter: false,
|
|
68
|
+
hideDropdownIndicator: true,
|
|
69
|
+
options: model.maxRowOptions
|
|
101
70
|
})
|
|
102
|
-
|
|
71
|
+
})
|
|
103
72
|
})
|
|
104
|
-
)
|
|
105
|
-
|
|
73
|
+
)
|
|
74
|
+
);
|
|
106
75
|
|
|
107
76
|
const filterChooserToggleButton = hoistCmp.factory<ActivityTrackingModel>(({model}) => {
|
|
108
77
|
const {hasFilter, showFilterChooser} = model;
|
|
@@ -161,9 +130,3 @@ const aggregateView = hoistCmp.factory<ActivityTrackingModel>(({model}) => {
|
|
|
161
130
|
]
|
|
162
131
|
});
|
|
163
132
|
});
|
|
164
|
-
|
|
165
|
-
const dateInputProps: DateInputProps = {
|
|
166
|
-
popoverPosition: 'bottom',
|
|
167
|
-
valueType: 'localDate',
|
|
168
|
-
width: 120
|
|
169
|
-
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2026 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
+
import {naSpan, valOrNa} from '@xh/hoist/admin/AdminUtils';
|
|
7
8
|
import {badgeRenderer} from '@xh/hoist/admin/columns';
|
|
8
9
|
import {form} from '@xh/hoist/cmp/form';
|
|
9
10
|
import {grid, gridCountLabel} from '@xh/hoist/cmp/grid';
|
|
@@ -205,6 +206,4 @@ const additionalDataPanel = hoistCmp.factory<ActivityDetailModel>(({model}) => {
|
|
|
205
206
|
});
|
|
206
207
|
});
|
|
207
208
|
|
|
208
|
-
const valOrNa = v => (v != null ? v : naSpan());
|
|
209
|
-
const naSpan = () => span({item: 'N/A', className: 'xh-text-color-muted'});
|
|
210
209
|
const hyperlinkVal = v => (v ? a({href: v, item: v, target: '_blank'}) : '-');
|
|
@@ -28,6 +28,7 @@ import {formField} from '@xh/hoist/desktop/cmp/form';
|
|
|
28
28
|
import {
|
|
29
29
|
buttonGroupInput,
|
|
30
30
|
dateInput,
|
|
31
|
+
intentInput,
|
|
31
32
|
select,
|
|
32
33
|
switchInput,
|
|
33
34
|
textArea
|
|
@@ -112,19 +113,7 @@ const formPanel = hoistCmp.factory<AlertBannerModel>(({model}) => {
|
|
|
112
113
|
}),
|
|
113
114
|
formField({
|
|
114
115
|
field: 'intent',
|
|
115
|
-
item:
|
|
116
|
-
items: model.intentOptions.map(intent =>
|
|
117
|
-
button({
|
|
118
|
-
intent,
|
|
119
|
-
minimal: false,
|
|
120
|
-
// Opacity solution to account for Icon.placeholder() causing label to move when primary deselected
|
|
121
|
-
icon: Icon.check({
|
|
122
|
-
opacity: formModel.values.intent === intent ? 1 : 0
|
|
123
|
-
}),
|
|
124
|
-
value: intent
|
|
125
|
-
})
|
|
126
|
-
)
|
|
127
|
-
})
|
|
116
|
+
item: intentInput({intents: model.intentOptions})
|
|
128
117
|
}),
|
|
129
118
|
formField({
|
|
130
119
|
field: 'iconName',
|
|
@@ -0,0 +1,72 @@
|
|
|
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 {markdownRenderer, yesNoRenderer} 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 {ConfigPanelModel} from './ConfigPanelModel';
|
|
16
|
+
import {configValue} from './ConfigValue';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Read-only detail view of the config selected in the grid. Shows the config's metadata and every
|
|
20
|
+
* available view of its value - resolved, instance override, database, and typedClass defaults -
|
|
21
|
+
* opening on the most-derived view.
|
|
22
|
+
*/
|
|
23
|
+
export const configDetailPanel = hoistCmp.factory<ConfigPanelModel>({
|
|
24
|
+
displayName: 'ConfigDetailPanel',
|
|
25
|
+
model: uses(ConfigPanelModel),
|
|
26
|
+
|
|
27
|
+
render({model}) {
|
|
28
|
+
return restDetailPanel({
|
|
29
|
+
icon: Icon.settings(),
|
|
30
|
+
emptyText: 'Select a config to view its details.',
|
|
31
|
+
persistWith: {...model.persistWith, path: 'detailPanel'},
|
|
32
|
+
renderForm: (record, formModel) => {
|
|
33
|
+
const {note, valueType} = formModel.values;
|
|
34
|
+
return [
|
|
35
|
+
formFieldSet({
|
|
36
|
+
title: 'Config',
|
|
37
|
+
items: [
|
|
38
|
+
hbox(
|
|
39
|
+
formField({field: 'groupName', flex: 1}),
|
|
40
|
+
formField({
|
|
41
|
+
field: 'valueType',
|
|
42
|
+
readonlyRenderer: valueTypeRenderer,
|
|
43
|
+
flex: 1
|
|
44
|
+
}),
|
|
45
|
+
formField({
|
|
46
|
+
field: 'clientVisible',
|
|
47
|
+
readonlyRenderer: yesNoRenderer,
|
|
48
|
+
flex: 1
|
|
49
|
+
})
|
|
50
|
+
),
|
|
51
|
+
formField({
|
|
52
|
+
field: 'note',
|
|
53
|
+
readonlyRenderer: markdownRenderer,
|
|
54
|
+
omit: !note
|
|
55
|
+
}),
|
|
56
|
+
hbox(
|
|
57
|
+
formField({field: 'lastUpdatedBy', label: 'Updated By', flex: 1}),
|
|
58
|
+
formField({field: 'lastUpdated', label: 'Updated', flex: 2})
|
|
59
|
+
)
|
|
60
|
+
]
|
|
61
|
+
}),
|
|
62
|
+
formFieldSet({
|
|
63
|
+
title: 'Value',
|
|
64
|
+
// JSON values stretch to fill the remaining height - scalars sit compactly.
|
|
65
|
+
className: valueType === 'json' ? 'xh-admin-readonly-form__fill' : null,
|
|
66
|
+
item: configValue({formModel})
|
|
67
|
+
})
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
import * as AdminCol from '@xh/hoist/admin/columns';
|
|
8
8
|
import * as Col from '@xh/hoist/admin/columns/Rest';
|
|
9
9
|
import {jsonSearchButton} from '@xh/hoist/admin/jsonsearch/JsonSearch';
|
|
10
|
-
import {filler, fragment} from '@xh/hoist/cmp/layout';
|
|
11
|
-
import {creates, hoistCmp
|
|
10
|
+
import {filler, fragment, hframe} from '@xh/hoist/cmp/layout';
|
|
11
|
+
import {creates, hoistCmp} from '@xh/hoist/core';
|
|
12
12
|
import {button} from '@xh/hoist/desktop/cmp/button';
|
|
13
13
|
import {recordActionBar} from '@xh/hoist/desktop/cmp/record';
|
|
14
14
|
import {restGrid} from '@xh/hoist/desktop/cmp/rest';
|
|
@@ -17,6 +17,7 @@ import {toolbar, toolbarSep} from '@xh/hoist/desktop/cmp/toolbar';
|
|
|
17
17
|
import {Icon} from '@xh/hoist/icon';
|
|
18
18
|
import {differ} from '../../../differ/Differ';
|
|
19
19
|
import {regroupDialog} from '../../../regroup/RegroupDialog';
|
|
20
|
+
import {configDetailPanel} from './ConfigDetailPanel';
|
|
20
21
|
import {ConfigPanelModel} from './ConfigPanelModel';
|
|
21
22
|
|
|
22
23
|
export const configPanel = hoistCmp.factory({
|
|
@@ -24,46 +25,49 @@ export const configPanel = hoistCmp.factory({
|
|
|
24
25
|
|
|
25
26
|
render({model}) {
|
|
26
27
|
return fragment(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
hframe(
|
|
29
|
+
restGrid({
|
|
30
|
+
testId: 'config',
|
|
31
|
+
formBbar: configFormBbar(),
|
|
32
|
+
extraToolbarItems: () => [
|
|
33
|
+
button({
|
|
34
|
+
icon: Icon.diff(),
|
|
35
|
+
text: 'Compare w/ Remote',
|
|
36
|
+
onClick: () => model.openDiffer()
|
|
37
|
+
}),
|
|
38
|
+
toolbarSep(),
|
|
39
|
+
jsonSearchButton({
|
|
40
|
+
subjectName: 'Config',
|
|
41
|
+
docSearchUrl: 'jsonSearch/searchConfigs',
|
|
42
|
+
gridModelConfig: {
|
|
43
|
+
sortBy: ['groupName', 'name'],
|
|
44
|
+
columns: [
|
|
45
|
+
{...AdminCol.groupName},
|
|
46
|
+
{...AdminCol.name},
|
|
47
|
+
{
|
|
48
|
+
field: {name: 'json', type: 'string'},
|
|
49
|
+
hidden: true
|
|
50
|
+
},
|
|
51
|
+
{...Col.lastUpdated}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
groupByOptions: ['groupName']
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
}),
|
|
58
|
+
configDetailPanel()
|
|
59
|
+
),
|
|
56
60
|
differ({omit: !model.differModel}),
|
|
57
61
|
regroupDialog()
|
|
58
62
|
);
|
|
59
63
|
}
|
|
60
64
|
});
|
|
61
65
|
|
|
62
|
-
// Custom toolbar
|
|
66
|
+
// Custom toolbar adds a Revert button to the standard record actions and Cancel/Save. The dialog
|
|
67
|
+
// is edit-only - viewing is handled by the docked detail panel.
|
|
63
68
|
const configFormBbar = hoistCmp.factory<RestFormModel>(({model}) => {
|
|
64
69
|
const {formModel, actions, currentRecord, gridModel} = model,
|
|
65
|
-
{isDirty, isValid
|
|
66
|
-
containsResolved = formModel.values.resolvedValue != null;
|
|
70
|
+
{isDirty, isValid} = formModel;
|
|
67
71
|
return toolbar(
|
|
68
72
|
recordActionBar({
|
|
69
73
|
actions,
|
|
@@ -74,11 +78,11 @@ const configFormBbar = hoistCmp.factory<RestFormModel>(({model}) => {
|
|
|
74
78
|
text: 'Revert',
|
|
75
79
|
icon: Icon.reset(),
|
|
76
80
|
onClick: () => formModel.reset(),
|
|
77
|
-
omit:
|
|
81
|
+
omit: !isDirty
|
|
78
82
|
}),
|
|
79
83
|
filler(),
|
|
80
84
|
button({
|
|
81
|
-
text:
|
|
85
|
+
text: 'Cancel',
|
|
82
86
|
onClick: () => model.close()
|
|
83
87
|
}),
|
|
84
88
|
button({
|
|
@@ -87,23 +91,7 @@ const configFormBbar = hoistCmp.factory<RestFormModel>(({model}) => {
|
|
|
87
91
|
intent: 'success',
|
|
88
92
|
outlined: true,
|
|
89
93
|
disabled: (!model.isAdd && !isDirty) || !isValid,
|
|
90
|
-
onClick:
|
|
91
|
-
const {isAdd} = model,
|
|
92
|
-
{id} = model.currentRecord,
|
|
93
|
-
reopen = !isAdd && containsResolved && formModel.getField('value')?.isDirty;
|
|
94
|
-
|
|
95
|
-
await model.validateAndSaveAsync();
|
|
96
|
-
if (reopen && !model.isOpen) {
|
|
97
|
-
const record = model.store.getById(id);
|
|
98
|
-
if (record) {
|
|
99
|
-
model.parent.editRecord(record);
|
|
100
|
-
XH.successToast(
|
|
101
|
-
'The edit has been saved and the resolved value has been updated.'
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
omit: readonly
|
|
94
|
+
onClick: () => model.validateAndSaveAsync()
|
|
107
95
|
})
|
|
108
96
|
);
|
|
109
97
|
});
|
|
@@ -62,6 +62,9 @@ export class ConfigPanelModel extends HoistModel {
|
|
|
62
62
|
selModel: 'multiple',
|
|
63
63
|
sortBy: 'name',
|
|
64
64
|
unit: 'config',
|
|
65
|
+
onRowDoubleClicked: ({data}) => {
|
|
66
|
+
if (data && !this.gridModel.readonly) this.gridModel.editRecord(data);
|
|
67
|
+
},
|
|
65
68
|
// Store + fields
|
|
66
69
|
store: {
|
|
67
70
|
url: 'rest/configAdmin',
|
|
@@ -77,3 +77,17 @@
|
|
|
77
77
|
padding: 0;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
// Fill mode (no fixed `height`) - the tab set / single field stretches to its container, with
|
|
82
|
+
// the nested layers passing the flex down to the JSON editor.
|
|
83
|
+
.xh-config-value--fill {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex: 1;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
min-height: 0;
|
|
88
|
+
|
|
89
|
+
.xh-form-field__inner {
|
|
90
|
+
flex: 1;
|
|
91
|
+
min-height: 0;
|
|
92
|
+
}
|
|
93
|
+
}
|