@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
|
@@ -0,0 +1,274 @@
|
|
|
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 {LocalDate} from '@xh/hoist/utils/datetime';
|
|
8
|
+
import {fmtDateRangeOffset, nextDayInMode, previousDayInMode, singleDay} from './DateRangeUtils';
|
|
9
|
+
import type {
|
|
10
|
+
DateRangeContext,
|
|
11
|
+
DateRangePreset,
|
|
12
|
+
DateRangePresetToken,
|
|
13
|
+
DateRangeUnit,
|
|
14
|
+
LocalDateRange
|
|
15
|
+
} from './Types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Presets shipped with Hoist, keyed by token. Offer any subset (in any order) via the `presets`
|
|
19
|
+
* config of {@link DateRangePickerModel}, alongside any app-defined {@link DateRangePreset}s.
|
|
20
|
+
*
|
|
21
|
+
* Labels describe a range without claiming it ends today, since the anchor date need not be
|
|
22
|
+
* today: `Prev 7 Days` rather than `Last 7 Days`. The one exception is `anchorDay`, which reads
|
|
23
|
+
* `Today` when the anchor date is the current day and `As Of` otherwise - the trigger's dates
|
|
24
|
+
* supply the day itself.
|
|
25
|
+
*
|
|
26
|
+
* Period-to-date presets (`wtd`, `mtd`, `qtd`, `ytd`) resolve their prior range as the same span
|
|
27
|
+
* one unit earlier - e.g. MTD on the 12th compares against the 1st through 12th of the prior
|
|
28
|
+
* month. Previous-unit presets (`prevWeek`, `prevMonth`, ...) compare against the unit before.
|
|
29
|
+
* Rolling windows compare against the window of equal length immediately preceding them. The
|
|
30
|
+
* same logic, mirrored by `resolveNext`, drives stepping: `mtd` stepped back once is the prior MTD.
|
|
31
|
+
*
|
|
32
|
+
* A preset that names a specific period reads the same as a pick of that period on the Months &
|
|
33
|
+
* Years tab - `prevMonth` labels as e.g. `Aug 2026` and `prevYear` as `2025` - so the trigger
|
|
34
|
+
* describes the period, whichever way it was chosen. The underlying values stay distinct: a preset
|
|
35
|
+
* re-resolves against the anchor date as time passes, where a pinned month or year does not.
|
|
36
|
+
*/
|
|
37
|
+
export const dateRangePresets: Record<DateRangePresetToken, DateRangePreset> = {
|
|
38
|
+
anchorDay: {
|
|
39
|
+
token: 'anchorDay',
|
|
40
|
+
label: anchorLabel,
|
|
41
|
+
name: ctx => (isAnchorToday(ctx) ? 'Today' : 'As Of Date'),
|
|
42
|
+
resolve: ({anchorDate}) => singleDay(anchorDate),
|
|
43
|
+
resolvePrior: priorDay,
|
|
44
|
+
resolveNext: nextDay,
|
|
45
|
+
shiftedLabel: (range, offset, ctx) => dayFromAnchor(offset, ctx)
|
|
46
|
+
},
|
|
47
|
+
prevDay: {
|
|
48
|
+
token: 'prevDay',
|
|
49
|
+
label: 'Prev Day',
|
|
50
|
+
resolve: ctx => singleDay(previousDayInMode(ctx.anchorDate, ctx)),
|
|
51
|
+
resolvePrior: priorDay,
|
|
52
|
+
resolveNext: nextDay,
|
|
53
|
+
// Already one step back - stepped, it reads from the anchor like `anchorDay` does.
|
|
54
|
+
shiftedLabel: (range, offset, ctx) => dayFromAnchor(offset - 1, ctx)
|
|
55
|
+
},
|
|
56
|
+
wtd: {
|
|
57
|
+
token: 'wtd',
|
|
58
|
+
label: 'WTD',
|
|
59
|
+
name: 'Week to Date',
|
|
60
|
+
resolve: toDate('weeks'),
|
|
61
|
+
resolvePrior: shiftedBy('weeks', -1),
|
|
62
|
+
resolveNext: shiftedBy('weeks', 1)
|
|
63
|
+
},
|
|
64
|
+
mtd: {
|
|
65
|
+
token: 'mtd',
|
|
66
|
+
label: 'MTD',
|
|
67
|
+
name: 'Month to Date',
|
|
68
|
+
resolve: toDate('months'),
|
|
69
|
+
resolvePrior: shiftedBy('months', -1),
|
|
70
|
+
resolveNext: shiftedBy('months', 1)
|
|
71
|
+
},
|
|
72
|
+
qtd: {
|
|
73
|
+
token: 'qtd',
|
|
74
|
+
label: 'QTD',
|
|
75
|
+
name: 'Quarter to Date',
|
|
76
|
+
resolve: toDate('quarters'),
|
|
77
|
+
resolvePrior: shiftedBy('quarters', -1),
|
|
78
|
+
resolveNext: shiftedBy('quarters', 1)
|
|
79
|
+
},
|
|
80
|
+
ytd: {
|
|
81
|
+
token: 'ytd',
|
|
82
|
+
label: 'YTD',
|
|
83
|
+
name: 'Year to Date',
|
|
84
|
+
resolve: toDate('years'),
|
|
85
|
+
resolvePrior: shiftedBy('years', -1),
|
|
86
|
+
resolveNext: shiftedBy('years', 1)
|
|
87
|
+
},
|
|
88
|
+
prev7Days: {
|
|
89
|
+
token: 'prev7Days',
|
|
90
|
+
label: 'Prev 7 Days',
|
|
91
|
+
resolve: prevDays(7),
|
|
92
|
+
shiftedLabel: lengthLabel('7 Days')
|
|
93
|
+
},
|
|
94
|
+
prev30Days: {
|
|
95
|
+
token: 'prev30Days',
|
|
96
|
+
label: 'Prev 30 Days',
|
|
97
|
+
resolve: prevDays(30),
|
|
98
|
+
shiftedLabel: lengthLabel('30 Days')
|
|
99
|
+
},
|
|
100
|
+
prev90Days: {
|
|
101
|
+
token: 'prev90Days',
|
|
102
|
+
label: 'Prev 90 Days',
|
|
103
|
+
resolve: prevDays(90),
|
|
104
|
+
shiftedLabel: lengthLabel('90 Days')
|
|
105
|
+
},
|
|
106
|
+
prev3Months: {
|
|
107
|
+
token: 'prev3Months',
|
|
108
|
+
label: 'Prev 3 Months',
|
|
109
|
+
resolve: prevMonths(3),
|
|
110
|
+
resolvePrior: shiftedBy('months', -3),
|
|
111
|
+
resolveNext: shiftedBy('months', 3),
|
|
112
|
+
shiftedLabel: lengthLabel('3 Months')
|
|
113
|
+
},
|
|
114
|
+
prev6Months: {
|
|
115
|
+
token: 'prev6Months',
|
|
116
|
+
label: 'Prev 6 Months',
|
|
117
|
+
resolve: prevMonths(6),
|
|
118
|
+
resolvePrior: shiftedBy('months', -6),
|
|
119
|
+
resolveNext: shiftedBy('months', 6),
|
|
120
|
+
shiftedLabel: lengthLabel('6 Months')
|
|
121
|
+
},
|
|
122
|
+
prev12Months: {
|
|
123
|
+
token: 'prev12Months',
|
|
124
|
+
label: 'Prev 12 Months',
|
|
125
|
+
resolve: prevMonths(12),
|
|
126
|
+
resolvePrior: shiftedBy('years', -1),
|
|
127
|
+
resolveNext: shiftedBy('years', 1),
|
|
128
|
+
shiftedLabel: lengthLabel('12 Months')
|
|
129
|
+
},
|
|
130
|
+
prevWeek: {
|
|
131
|
+
token: 'prevWeek',
|
|
132
|
+
label: 'Prev Week',
|
|
133
|
+
resolve: previousUnit('weeks'),
|
|
134
|
+
resolvePrior: adjacentUnit('weeks', -1),
|
|
135
|
+
resolveNext: adjacentUnit('weeks', 1),
|
|
136
|
+
shiftedLabel: periodLabel('[Wk of] MMM D')
|
|
137
|
+
},
|
|
138
|
+
prevMonth: {
|
|
139
|
+
token: 'prevMonth',
|
|
140
|
+
label: ctx => previousUnitStart(ctx, 'months').format('MMM YYYY'),
|
|
141
|
+
name: ctx => `Prev Month (${previousUnitStart(ctx, 'months').format('MMM YYYY')})`,
|
|
142
|
+
resolve: previousUnit('months'),
|
|
143
|
+
resolvePrior: adjacentUnit('months', -1),
|
|
144
|
+
resolveNext: adjacentUnit('months', 1),
|
|
145
|
+
shiftedLabel: periodLabel('MMM YYYY')
|
|
146
|
+
},
|
|
147
|
+
prevQuarter: {
|
|
148
|
+
token: 'prevQuarter',
|
|
149
|
+
label: ctx => previousUnitStart(ctx, 'quarters').format('[Q]Q YYYY'),
|
|
150
|
+
name: ctx => `Prev Quarter (${previousUnitStart(ctx, 'quarters').format('[Q]Q YYYY')})`,
|
|
151
|
+
resolve: previousUnit('quarters'),
|
|
152
|
+
resolvePrior: adjacentUnit('quarters', -1),
|
|
153
|
+
resolveNext: adjacentUnit('quarters', 1),
|
|
154
|
+
shiftedLabel: periodLabel('[Q]Q YYYY')
|
|
155
|
+
},
|
|
156
|
+
prevYear: {
|
|
157
|
+
token: 'prevYear',
|
|
158
|
+
label: ctx => previousUnitStart(ctx, 'years').format('YYYY'),
|
|
159
|
+
name: ctx => `Prev Year (${previousUnitStart(ctx, 'years').format('YYYY')})`,
|
|
160
|
+
resolve: previousUnit('years'),
|
|
161
|
+
resolvePrior: adjacentUnit('years', -1),
|
|
162
|
+
resolveNext: adjacentUnit('years', 1),
|
|
163
|
+
shiftedLabel: periodLabel('YYYY')
|
|
164
|
+
},
|
|
165
|
+
all: {
|
|
166
|
+
token: 'all',
|
|
167
|
+
label: 'All',
|
|
168
|
+
name: 'All Dates',
|
|
169
|
+
// Everything selectable - unbounded at the start unless the model sets a `minDate`.
|
|
170
|
+
resolve: ({minDate, maxDate}) => ({start: minDate, end: maxDate}),
|
|
171
|
+
resolvePrior: () => null,
|
|
172
|
+
resolveNext: () => null
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/** Tokens of the presets shipped with Hoist, in a sensible display order. */
|
|
177
|
+
export const DATE_RANGE_PRESET_TOKENS = Object.keys(dateRangePresets) as DateRangePresetToken[];
|
|
178
|
+
|
|
179
|
+
/** Presets offered by {@link DateRangePickerModel} when none are configured. */
|
|
180
|
+
export const DEFAULT_DATE_RANGE_PRESETS: DateRangePresetToken[] = [
|
|
181
|
+
'anchorDay',
|
|
182
|
+
'mtd',
|
|
183
|
+
'qtd',
|
|
184
|
+
'ytd',
|
|
185
|
+
'prev7Days',
|
|
186
|
+
'prev30Days',
|
|
187
|
+
'prev90Days',
|
|
188
|
+
'prev12Months',
|
|
189
|
+
'prevMonth',
|
|
190
|
+
'prevYear'
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
//------------------
|
|
194
|
+
// Implementation
|
|
195
|
+
//------------------
|
|
196
|
+
type Resolver = DateRangePreset['resolve'];
|
|
197
|
+
type Shifter = DateRangePreset['resolvePrior'];
|
|
198
|
+
type ShiftedLabel = DateRangePreset['shiftedLabel'];
|
|
199
|
+
|
|
200
|
+
/** From the start of the unit containing the anchor date, through the anchor date. */
|
|
201
|
+
function toDate(unit: DateRangeUnit): Resolver {
|
|
202
|
+
return ({anchorDate}) => ({start: anchorDate.startOf(unit), end: anchorDate});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** A rolling window of `n` days ending on the anchor date. */
|
|
206
|
+
function prevDays(n: number): Resolver {
|
|
207
|
+
return ({anchorDate}) => ({start: anchorDate.subtract(n - 1, 'days'), end: anchorDate});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** A rolling window of `n` months ending on the anchor date. */
|
|
211
|
+
function prevMonths(n: number): Resolver {
|
|
212
|
+
return ({anchorDate}) => ({start: anchorDate.subtract(n, 'months').nextDay(), end: anchorDate});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** The full calendar unit before the one containing the anchor date. */
|
|
216
|
+
function previousUnit(unit: DateRangeUnit): Resolver {
|
|
217
|
+
return ctx => {
|
|
218
|
+
const start = previousUnitStart(ctx, unit);
|
|
219
|
+
return {start, end: start.endOf(unit)};
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function previousUnitStart({anchorDate}: DateRangeContext, unit: DateRangeUnit): LocalDate {
|
|
224
|
+
return anchorDate.startOf(unit).subtract(1, unit);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** The current range shifted by `n` units - negative back, positive forward - keeping its shape. */
|
|
228
|
+
function shiftedBy(unit: DateRangeUnit, n: number): Shifter {
|
|
229
|
+
return ({start, end}) => ({start: start.add(n, unit), end: end.add(n, unit)});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** The full calendar unit `n` units from a current range that is itself a full unit. */
|
|
233
|
+
function adjacentUnit(unit: DateRangeUnit, n: number): Shifter {
|
|
234
|
+
return ({start}) => {
|
|
235
|
+
const next = start.add(n, unit);
|
|
236
|
+
return {start: next, end: next.endOf(unit)};
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** The day before or after a single-day range - by business day in `businessDayMode`. */
|
|
241
|
+
function priorDay({start}: LocalDateRange, ctx: DateRangeContext): LocalDateRange {
|
|
242
|
+
return singleDay(previousDayInMode(start, ctx));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function nextDay({start}: LocalDateRange, ctx: DateRangeContext): LocalDateRange {
|
|
246
|
+
return singleDay(nextDayInMode(start, ctx));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** Shifted label for a rolling window - its length alone, e.g. `7 Days`. */
|
|
250
|
+
function lengthLabel(length: string): ShiftedLabel {
|
|
251
|
+
return () => length;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Shifted label for a previous-unit preset - the period the range now covers. */
|
|
255
|
+
function periodLabel(format: string): ShiftedLabel {
|
|
256
|
+
return ({start}) => start.format(format);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function isAnchorToday({anchorDate, today}: DateRangeContext): boolean {
|
|
260
|
+
return anchorDate === today;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function anchorLabel(ctx: DateRangeContext): string {
|
|
264
|
+
return isAnchorToday(ctx) ? 'Today' : 'As Of';
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* A single day `n` steps from the anchor day, in the T-1 idiom finance users speak - `Today −2`,
|
|
269
|
+
* `As Of −1` - so a walk through single days reads the same however it began. Zero is the anchor
|
|
270
|
+
* day itself.
|
|
271
|
+
*/
|
|
272
|
+
function dayFromAnchor(n: number, ctx: DateRangeContext): string {
|
|
273
|
+
return n ? `${anchorLabel(ctx)} ${fmtDateRangeOffset(n)}` : anchorLabel(ctx);
|
|
274
|
+
}
|