@gooddata/sdk-ui-filters 11.54.0-alpha.4 → 11.54.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/esm/AttributeFilterHandler/AttributeFilterHandler.test.helpers.d.ts +34 -0
  2. package/esm/AttributeFilterHandler/AttributeFilterHandler.test.helpers.d.ts.map +1 -0
  3. package/esm/AttributeFilterHandler/AttributeFilterHandler.test.helpers.js +184 -0
  4. package/esm/AttributeFilterHandler/waitForAsync.test.utils.d.ts +2 -0
  5. package/esm/AttributeFilterHandler/waitForAsync.test.utils.d.ts.map +1 -0
  6. package/esm/AttributeFilterHandler/waitForAsync.test.utils.js +2 -0
  7. package/esm/DateFilter/DateFilterCore.d.ts.map +1 -1
  8. package/esm/DateFilter/DateFilterCore.js +1 -0
  9. package/esm/DateFilter/PeriodRangePicker/PeriodRangePicker.d.ts +9 -0
  10. package/esm/DateFilter/PeriodRangePicker/PeriodRangePicker.d.ts.map +1 -0
  11. package/esm/DateFilter/PeriodRangePicker/PeriodRangePicker.js +25 -0
  12. package/esm/DateFilter/PeriodRangePicker/PeriodRangePickerImpl.d.ts +22 -0
  13. package/esm/DateFilter/PeriodRangePicker/PeriodRangePickerImpl.d.ts.map +1 -0
  14. package/esm/DateFilter/PeriodRangePicker/PeriodRangePickerImpl.js +146 -0
  15. package/esm/DateFilter/PeriodRangePicker/momentRangePicker.d.ts +9 -0
  16. package/esm/DateFilter/PeriodRangePicker/momentRangePicker.d.ts.map +1 -0
  17. package/esm/DateFilter/PeriodRangePicker/momentRangePicker.js +9 -0
  18. package/esm/DateFilter/PeriodRangePicker/types.d.ts +28 -0
  19. package/esm/DateFilter/PeriodRangePicker/types.d.ts.map +1 -0
  20. package/esm/DateFilter/PeriodRangePicker/types.js +2 -0
  21. package/esm/DateFilter/PeriodRangePicker/weekStartMomentLocale.d.ts +16 -0
  22. package/esm/DateFilter/PeriodRangePicker/weekStartMomentLocale.d.ts.map +1 -0
  23. package/esm/DateFilter/PeriodRangePicker/weekStartMomentLocale.js +30 -0
  24. package/esm/DateFilter/interfaces/index.d.ts +4 -0
  25. package/esm/DateFilter/interfaces/index.d.ts.map +1 -1
  26. package/esm/DateFilter/utils/StaticPeriodConversions.d.ts +34 -0
  27. package/esm/DateFilter/utils/StaticPeriodConversions.d.ts.map +1 -0
  28. package/esm/DateFilter/utils/StaticPeriodConversions.js +80 -0
  29. package/esm/DateFilter/utils/{Translations/fixtures.d.ts → Translations.test.helpers.d.ts} +2 -2
  30. package/esm/DateFilter/utils/Translations.test.helpers.d.ts.map +1 -0
  31. package/esm/MeasureValueFilter/{fragments/MeasureValueFilterDropdown.d.ts → MeasureValueFilterDropdown.test.utils.d.ts} +1 -1
  32. package/esm/MeasureValueFilter/MeasureValueFilterDropdown.test.utils.d.ts.map +1 -0
  33. package/esm/RankingFilter/{mocks.d.ts → RankingFilter.test.helpers.d.ts} +1 -1
  34. package/esm/RankingFilter/RankingFilter.test.helpers.d.ts.map +1 -0
  35. package/esm/RankingFilter/{fragments/RankingFilterDropdown.d.ts → RankingFilterDropdown.test.utils.d.ts} +1 -1
  36. package/esm/RankingFilter/RankingFilterDropdown.test.utils.d.ts.map +1 -0
  37. package/esm/index.d.ts +2 -0
  38. package/esm/index.d.ts.map +1 -1
  39. package/esm/index.js +2 -0
  40. package/esm/sdk-ui-filters.d.ts +41 -0
  41. package/package.json +13 -12
  42. package/styles/css/components/PeriodRangePicker.css +316 -0
  43. package/styles/css/components/PeriodRangePicker.css.map +1 -0
  44. package/styles/css/dateFilter.css +315 -0
  45. package/styles/css/dateFilter.css.map +1 -1
  46. package/styles/css/main.css +315 -0
  47. package/styles/css/main.css.map +1 -1
  48. package/styles/scss/components/PeriodRangePicker.scss +431 -0
  49. package/styles/scss/dateFilter.scss +1 -0
  50. package/esm/AttributeFilter/Components/FilterMenu/FilterMenuLabelItem.d.ts +0 -27
  51. package/esm/AttributeFilter/Components/FilterMenu/FilterMenuLabelItem.d.ts.map +0 -1
  52. package/esm/AttributeFilter/Components/FilterMenu/FilterMenuLabelItem.js +0 -11
  53. package/esm/AttributeFilter/hooks/useAttributeFilterHandlerMethods.d.ts +0 -80
  54. package/esm/AttributeFilter/hooks/useAttributeFilterHandlerMethods.d.ts.map +0 -1
  55. package/esm/AttributeFilter/hooks/useAttributeFilterHandlerMethods.js +0 -55
  56. package/esm/DateFilter/AbsoluteDateFilterForm/AbsoluteDateFilterFormSection.d.ts +0 -21
  57. package/esm/DateFilter/AbsoluteDateFilterForm/AbsoluteDateFilterFormSection.d.ts.map +0 -1
  58. package/esm/DateFilter/AbsoluteDateFilterForm/AbsoluteDateFilterFormSection.js +0 -27
  59. package/esm/DateFilter/AbsoluteForm.d.ts +0 -15
  60. package/esm/DateFilter/AbsoluteForm.d.ts.map +0 -1
  61. package/esm/DateFilter/AbsoluteForm.js +0 -58
  62. package/esm/DateFilter/DateFilterBody/DateFilterBodyContent.d.ts +0 -33
  63. package/esm/DateFilter/DateFilterBody/DateFilterBodyContent.d.ts.map +0 -1
  64. package/esm/DateFilter/DateFilterBody/DateFilterBodyContent.js +0 -44
  65. package/esm/DateFilter/NumericInput/ArrowButton.d.ts +0 -8
  66. package/esm/DateFilter/NumericInput/ArrowButton.d.ts.map +0 -1
  67. package/esm/DateFilter/NumericInput/ArrowButton.js +0 -12
  68. package/esm/DateFilter/NumericInput/NumericInput.d.ts +0 -10
  69. package/esm/DateFilter/NumericInput/NumericInput.d.ts.map +0 -1
  70. package/esm/DateFilter/NumericInput/NumericInput.js +0 -46
  71. package/esm/DateFilter/NumericInput/utils.d.ts +0 -2
  72. package/esm/DateFilter/NumericInput/utils.d.ts.map +0 -1
  73. package/esm/DateFilter/NumericInput/utils.js +0 -6
  74. package/esm/DateFilter/RelativeDateFilterForm/RelativeDateFilterFormSection.d.ts +0 -19
  75. package/esm/DateFilter/RelativeDateFilterForm/RelativeDateFilterFormSection.d.ts.map +0 -1
  76. package/esm/DateFilter/RelativeDateFilterForm/RelativeDateFilterFormSection.js +0 -37
  77. package/esm/DateFilter/Select/Select.d.ts +0 -12
  78. package/esm/DateFilter/Select/Select.d.ts.map +0 -1
  79. package/esm/DateFilter/Select/Select.js +0 -14
  80. package/esm/DateFilter/Select/SelectButton.d.ts +0 -8
  81. package/esm/DateFilter/Select/SelectButton.d.ts.map +0 -1
  82. package/esm/DateFilter/Select/SelectButton.js +0 -9
  83. package/esm/DateFilter/Select/SelectMenu.d.ts +0 -14
  84. package/esm/DateFilter/Select/SelectMenu.d.ts.map +0 -1
  85. package/esm/DateFilter/Select/SelectMenu.js +0 -32
  86. package/esm/DateFilter/utils/Translations/fixtures.d.ts.map +0 -1
  87. package/esm/MeasureValueFilter/fragments/MeasureValueFilterDropdown.d.ts.map +0 -1
  88. package/esm/RankingFilter/fragments/RankingFilterDropdown.d.ts.map +0 -1
  89. package/esm/RankingFilter/mocks.d.ts.map +0 -1
  90. /package/esm/DateFilter/utils/{Translations/fixtures.js → Translations.test.helpers.js} +0 -0
  91. /package/esm/MeasureValueFilter/{fragments/MeasureValueFilterDropdown.js → MeasureValueFilterDropdown.test.utils.js} +0 -0
  92. /package/esm/RankingFilter/{mocks.js → RankingFilter.test.helpers.js} +0 -0
  93. /package/esm/RankingFilter/{fragments/RankingFilterDropdown.js → RankingFilterDropdown.test.utils.js} +0 -0
@@ -0,0 +1,34 @@
1
+ import { type ElementsQueryOptionsElementsSpecification, type IElementsQueryAttributeFilter } from "@gooddata/sdk-backend-spi";
2
+ import { type IAttributeElement, type IAttributeFilter, type IMeasure, type IRelativeDateFilter } from "@gooddata/sdk-model";
3
+ export declare const particularAttributeElements: ElementsQueryOptionsElementsSpecification;
4
+ export declare const anotherParticularAttributeElements: ElementsQueryOptionsElementsSpecification;
5
+ export declare const limitingAttributeFilters: IElementsQueryAttributeFilter[];
6
+ export declare const limitingMeasures: IMeasure[];
7
+ export declare const limitingDateFilters: IRelativeDateFilter[];
8
+ export declare const staticElements: IAttributeElement[];
9
+ export declare const hiddenElements: string[];
10
+ export declare const newTestAttributeFilterHandler: (useCase: "hidden" | "negative" | "nonExisting" | "positive" | "static") => import("./types/attributeFilterHandler.js").IMultiSelectAttributeFilterHandler;
11
+ export declare const positiveAttributeFilterDefaultDF: import("@gooddata/sdk-model").IPositiveAttributeFilter;
12
+ export declare const emptyPositiveAttributeFilterDefaultDF: import("@gooddata/sdk-model").IPositiveAttributeFilter;
13
+ export declare const negativeAttributeFilterDefaultDF: import("@gooddata/sdk-model").INegativeAttributeFilter;
14
+ export declare const newTestAttributeFilterHandlerWithAttributeFilter: (attributeFilter: IAttributeFilter, advancedOptions?: {
15
+ staticElements?: IAttributeElement[] | undefined;
16
+ hiddenElements?: string[] | undefined;
17
+ } | undefined) => import("./types/attributeFilterHandler.js").IMultiSelectAttributeFilterHandler;
18
+ /**
19
+ * Handler whose elements loads can be made to fail on demand.
20
+ *
21
+ * The failure is injected into the backend the handler talks to, so that the tests of the error
22
+ * paths do not have to mock the internal loadElements module. A module mock cannot be relied on
23
+ * here, because the test files share the module registry (see `isolate: false` in vitest.config.ts)
24
+ * and the module is already evaluated unmocked by the time such a suite runs.
25
+ */
26
+ export declare const newTestAttributeFilterHandlerWithElementsLoadFailures: (attributeFilter: IAttributeFilter) => {
27
+ attributeFilterHandler: import("./types/attributeFilterHandler.js").IMultiSelectAttributeFilterHandler;
28
+ /**
29
+ * Makes the next elements load reject with the provided error. Call it repeatedly to queue up
30
+ * more failures, one per load - the equivalent of several mockRejectedValueOnce() calls.
31
+ */
32
+ failNextElementsLoad: (error: unknown) => void;
33
+ };
34
+ //# sourceMappingURL=AttributeFilterHandler.test.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AttributeFilterHandler.test.helpers.d.ts","sourceRoot":"","sources":["../../src/AttributeFilterHandler/AttributeFilterHandler.test.helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,yCAAyC,EAG9C,KAAK,6BAA6B,EACrC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAQ3B,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,2BAA2B,EAAE,yCAEzC,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,yCAEhD,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,6BAA6B,EAOnE,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EAAyB,CAAC;AAEjE,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,EAEpD,CAAC;AAyDF,eAAO,MAAM,cAAc,qBAKpB,CAAC;AAIR,eAAO,MAAM,cAAc,UAAsB,CAAC;AAElD,eAAO,MAAM,6BAA6B,4JAuBzC,CAAC;AAEF,eAAO,MAAM,gCAAgC,wDAE3C,CAAC;AAEH,eAAO,MAAM,qCAAqC,wDAEhD,CAAC;AAEH,eAAO,MAAM,gCAAgC,wDAE3C,CAAC;AAEH,eAAO,MAAM,gDAAgD;;;gGAU5D,CAAC;AA2EF;;;;;;;GAOG;AACH,eAAO,MAAM,qDAAqD;;IAU1D;;;OAGG;;CAKV,CAAC"}
@@ -0,0 +1,184 @@
1
+ // (C) 2019-2026 GoodData Corporation
2
+ import { ReferenceMd, ReferenceRecordings } from "@gooddata/reference-workspace";
3
+ import { recordedBackend } from "@gooddata/sdk-backend-mockingbird";
4
+ import { attributeIdentifier, idRef, measureIdentifier, newNegativeAttributeFilter, newPositiveAttributeFilter, newRelativeDateFilter, } from "@gooddata/sdk-model";
5
+ import { newAttributeFilterHandler } from "./factory.js";
6
+ export const particularAttributeElements = {
7
+ values: ["TouchAll", "WonderKid"],
8
+ };
9
+ export const anotherParticularAttributeElements = {
10
+ values: ["PhoenixSoft"],
11
+ };
12
+ export const limitingAttributeFilters = [
13
+ {
14
+ attributeFilter: newPositiveAttributeFilter(ReferenceMd.Product.Name, {
15
+ uris: ["460488"],
16
+ }),
17
+ overAttribute: idRef("attr.opportunitysnapshot.id"),
18
+ },
19
+ ];
20
+ export const limitingMeasures = [ReferenceMd.Amount];
21
+ export const limitingDateFilters = [
22
+ newRelativeDateFilter(ReferenceMd.DateDatasets.Snapshot.SnapshotDate.identifier, "GDC.time.date", 0, -1),
23
+ ];
24
+ const productNameAttrId = attributeIdentifier(ReferenceMd.Product.Name);
25
+ const amountMeasureId = measureIdentifier(ReferenceMd.Amount);
26
+ const snapshotDateId = ReferenceMd.DateDatasets.Snapshot.SnapshotDate.identifier;
27
+ const productDefaultId = attributeIdentifier(ReferenceMd.Product.Default);
28
+ const backend = recordedBackend(ReferenceRecordings.Recordings, {
29
+ attributeElementsFiltering: {
30
+ attributeFilters: {
31
+ [productNameAttrId]: (_element, index) => {
32
+ return (index + 1) % 2 === 0;
33
+ },
34
+ [productDefaultId]: (_element, index) => {
35
+ return (index + 1) % 2 === 0;
36
+ },
37
+ },
38
+ measures: {
39
+ [amountMeasureId]: (_element, index) => {
40
+ return (index + 1) % 3 === 0;
41
+ },
42
+ },
43
+ dateFilters: {
44
+ [snapshotDateId]: (_element, index) => {
45
+ return (index + 1) % 4 === 0;
46
+ },
47
+ },
48
+ },
49
+ });
50
+ const workspace = "testWorkspace";
51
+ const positiveAttributeFilter = newPositiveAttributeFilter(ReferenceMd.Product.Name, {
52
+ uris: ["165678", "165847"],
53
+ });
54
+ const emptyPositiveAttributeFilter = newPositiveAttributeFilter(ReferenceMd.Product.Name, {
55
+ uris: [],
56
+ });
57
+ const negativeAttributeFilter = newNegativeAttributeFilter(ReferenceMd.Product.Name, {
58
+ uris: ["165678", "165847"],
59
+ });
60
+ const nonExistingAttributeFilter = newPositiveAttributeFilter("non-existing-displayForm", {
61
+ uris: [],
62
+ });
63
+ const createDummyElements = (createElement, size) => new Array(size).fill(null).reduce((result, _, index) => {
64
+ result.push(createElement(index));
65
+ return result;
66
+ }, []);
67
+ export const staticElements = createDummyElements((index) => {
68
+ return {
69
+ title: `Element ${index}`,
70
+ uri: `/element?id=${index}`,
71
+ };
72
+ }, 100);
73
+ // This actually does not filter elements in mockingbirg
74
+ // It just triggers usage of the attributeElementsFiltering
75
+ export const hiddenElements = ["/hidden-element"];
76
+ export const newTestAttributeFilterHandler = (useCase) => {
77
+ let filter = positiveAttributeFilter;
78
+ const options = {
79
+ selectionMode: "multi",
80
+ };
81
+ if (useCase === "positive") {
82
+ filter = positiveAttributeFilter;
83
+ }
84
+ else if (useCase === "negative") {
85
+ filter = negativeAttributeFilter;
86
+ }
87
+ else if (useCase === "nonExisting") {
88
+ filter = nonExistingAttributeFilter;
89
+ }
90
+ else if (useCase === "static") {
91
+ filter = emptyPositiveAttributeFilter;
92
+ options.staticElements = staticElements;
93
+ }
94
+ else if (useCase === "hidden") {
95
+ filter = positiveAttributeFilter;
96
+ options.hiddenElements = hiddenElements;
97
+ }
98
+ return newAttributeFilterHandler(backend, workspace, filter, options);
99
+ };
100
+ export const positiveAttributeFilterDefaultDF = newPositiveAttributeFilter(ReferenceMd.Product.Default, {
101
+ uris: ["165678", "165847"],
102
+ });
103
+ export const emptyPositiveAttributeFilterDefaultDF = newPositiveAttributeFilter(ReferenceMd.Product.Default, {
104
+ uris: [],
105
+ });
106
+ export const negativeAttributeFilterDefaultDF = newNegativeAttributeFilter(ReferenceMd.Product.Default, {
107
+ uris: ["165678", "165847"],
108
+ });
109
+ export const newTestAttributeFilterHandlerWithAttributeFilter = (attributeFilter, advancedOptions) => {
110
+ const options = {
111
+ selectionMode: "multi",
112
+ ...(advancedOptions ?? {}),
113
+ };
114
+ return newAttributeFilterHandler(backend, workspace, attributeFilter, options);
115
+ };
116
+ const isFunction = (value) => typeof value === "function";
117
+ const isElementsQuery = (value) => typeof value === "object" && value !== null && isFunction(value.query);
118
+ /**
119
+ * Facade of `target` with a single method replaced.
120
+ *
121
+ * A proxy is used instead of an object spread, because the backend services are class instances -
122
+ * their methods live on the prototype and a spread would drop them.
123
+ */
124
+ const withReplacedMethod = (target, method, replacement) => new Proxy(target, {
125
+ get(proxiedTarget, property) {
126
+ if (property === method) {
127
+ return replacement;
128
+ }
129
+ const value = Reflect.get(proxiedTarget, property, proxiedTarget);
130
+ return isFunction(value) ? value.bind(proxiedTarget) : value;
131
+ },
132
+ });
133
+ /**
134
+ * Elements query that rejects with the queued errors, one error per query() call, and delegates to
135
+ * the recorded implementation once the queue is empty.
136
+ */
137
+ const withQueuedElementsLoadFailures = (elementsQuery, errors) => new Proxy(elementsQuery, {
138
+ get(proxiedTarget, property) {
139
+ const value = Reflect.get(proxiedTarget, property, proxiedTarget);
140
+ if (!isFunction(value)) {
141
+ return value;
142
+ }
143
+ if (property === "query") {
144
+ return (...args) => errors.length > 0 ? Promise.reject(errors.shift()) : value.apply(proxiedTarget, args);
145
+ }
146
+ return (...args) => {
147
+ const result = value.apply(proxiedTarget, args);
148
+ // The builder methods return the query itself, so the result has to be wrapped again
149
+ // to keep the interception in place for the rest of the chain.
150
+ return isElementsQuery(result) ? withQueuedElementsLoadFailures(result, errors) : result;
151
+ };
152
+ },
153
+ });
154
+ const backendWithQueuedElementsLoadFailures = (errors) => withReplacedMethod(backend, "workspace", (workspaceId) => {
155
+ const analyticalWorkspace = backend.workspace(workspaceId);
156
+ return withReplacedMethod(analyticalWorkspace, "attributes", () => {
157
+ const attributes = analyticalWorkspace.attributes();
158
+ return withReplacedMethod(attributes, "elements", () => {
159
+ const elements = attributes.elements();
160
+ return withReplacedMethod(elements, "forDisplayForm", (ref) => withQueuedElementsLoadFailures(elements.forDisplayForm(ref), errors));
161
+ });
162
+ });
163
+ });
164
+ /**
165
+ * Handler whose elements loads can be made to fail on demand.
166
+ *
167
+ * The failure is injected into the backend the handler talks to, so that the tests of the error
168
+ * paths do not have to mock the internal loadElements module. A module mock cannot be relied on
169
+ * here, because the test files share the module registry (see `isolate: false` in vitest.config.ts)
170
+ * and the module is already evaluated unmocked by the time such a suite runs.
171
+ */
172
+ export const newTestAttributeFilterHandlerWithElementsLoadFailures = (attributeFilter) => {
173
+ const errors = [];
174
+ return {
175
+ attributeFilterHandler: newAttributeFilterHandler(backendWithQueuedElementsLoadFailures(errors), workspace, attributeFilter, { selectionMode: "multi" }),
176
+ /**
177
+ * Makes the next elements load reject with the provided error. Call it repeatedly to queue up
178
+ * more failures, one per load - the equivalent of several mockRejectedValueOnce() calls.
179
+ */
180
+ failNextElementsLoad: (error) => {
181
+ errors.push(error);
182
+ },
183
+ };
184
+ };
@@ -0,0 +1,2 @@
1
+ export declare const waitForAsync: () => Promise<any>;
2
+ //# sourceMappingURL=waitForAsync.test.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitForAsync.test.utils.d.ts","sourceRoot":"","sources":["../../src/AttributeFilterHandler/waitForAsync.test.utils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,oBAAmF,CAAC"}
@@ -0,0 +1,2 @@
1
+ // (C) 2019-2026 GoodData Corporation
2
+ export const waitForAsync = () => new Promise((resolve) => setTimeout(resolve, 0));
@@ -1 +1 @@
1
- {"version":3,"file":"DateFilterCore.d.ts","sourceRoot":"","sources":["../../src/DateFilter/DateFilterCore.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DateFilterCore.d.ts","sourceRoot":"","sources":["../../src/DateFilter/DateFilterCore.tsx"],"names":[],"mappings":"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"}
@@ -102,6 +102,7 @@ export function DateFilterCore({ originalSelectedFilterOption, originalExcludeCu
102
102
  ], onOpenStateChanged: handleOpenStateChanged, overlayPositionType: overlayPositionType, renderButton: ({ isOpen, buttonRef, dropdownId, toggleDropdown }) => (_jsx("span", { onClick: disabled ? () => { } : toggleDropdown, children: dateFilterButton(isOpen, buttonRef, dropdownId, toggleDropdown) })), ignoreClicksOnByClass: [
103
103
  ".s-do-not-close-dropdown-on-click",
104
104
  ".rdp-day", // absolute range picker calendar items
105
+ ".rc-picker-cell-inner", // PeriodRangePicker (rc-picker) period grid cells
105
106
  ], renderBody: ({ closeDropdown, ariaAttributes }) => {
106
107
  return isConfigurationOpen && FilterConfigurationComponent ? (_jsx(FilterConfigurationComponent, { onSaveButtonClick: closeConfiguration, onCancelButtonClick: cancelConfiguration })) : (
107
108
  // Dropdown component uses Children.map and adds special props to this component
@@ -0,0 +1,9 @@
1
+ import { type IPeriodRangePickerProps } from "./types.js";
2
+ /**
3
+ * A grid picker for selecting a Week/Month/Quarter/Year period range. Renders the rc-picker panel matching
4
+ * {@link IPeriodRangePickerProps.granularity} and reports the resolved day-level range via `onRangeChange`.
5
+ *
6
+ * @alpha
7
+ */
8
+ export declare function PeriodRangePicker(props: IPeriodRangePickerProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=PeriodRangePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeriodRangePicker.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/PeriodRangePicker/PeriodRangePicker.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAgB1D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,uBAAuB,2CAM/D"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { Suspense, lazy } from "react";
4
+ // `@rc-component/picker`'s "es" build - the one its package.json `exports` map serves to the `import`
5
+ // condition, for every subpath - ships ESM syntax with extensionless relative imports (`from "./common"`),
6
+ // which Node's ESM resolver cannot resolve. It is therefore loadable by bundlers only: under plain Node ESM
7
+ // every entry point of that package throws ERR_MODULE_NOT_FOUND. Since this package is `"type": "module"`,
8
+ // Node always takes that `import` condition, so anything that statically reaches rc-picker poisons the whole
9
+ // `@gooddata/sdk-ui-filters` barrel for Node consumers - including every other package's vitest run, where
10
+ // this package's built `esm/` is externalized and resolved by Node rather than by Vite.
11
+ //
12
+ // Keeping the rc-picker-importing module behind a dynamic import keeps the barrel importable in Node and
13
+ // code-splits a heavy dependency out of the main bundle; the picker is only ever shown on demand anyway.
14
+ const PeriodRangePickerImpl = lazy(async () => ({
15
+ default: (await import("./PeriodRangePickerImpl.js")).PeriodRangePickerImpl,
16
+ }));
17
+ /**
18
+ * A grid picker for selecting a Week/Month/Quarter/Year period range. Renders the rc-picker panel matching
19
+ * {@link IPeriodRangePickerProps.granularity} and reports the resolved day-level range via `onRangeChange`.
20
+ *
21
+ * @alpha
22
+ */
23
+ export function PeriodRangePicker(props) {
24
+ return (_jsx(Suspense, { fallback: null, children: _jsx(PeriodRangePickerImpl, { ...props }) }));
25
+ }
@@ -0,0 +1,22 @@
1
+ import { type Moment } from "moment";
2
+ import { type IPeriodRange, type IPeriodRangePickerProps, type PeriodRangePickerGranularity } from "./types.js";
3
+ /**
4
+ * Resolves the picker's raw selected [start, end] into the exact day-level range this component reports.
5
+ *
6
+ * @remarks
7
+ * rc-picker's month/quarter/year panels hand back a start-of-unit anchor for BOTH ends of the range, so the end
8
+ * anchor still needs expanding to the last day of its period. `resolvePeriodBoundaries` already accepts "any date
9
+ * within the period" for either bound, so a start-of-unit anchor works as input either way. Day needs no expansion,
10
+ * and `resolvePeriodBoundaries` handles it as a no-op period (start/end of day), so it's routed through uniformly.
11
+ */
12
+ export declare function resolveSelectedRange(granularity: PeriodRangePickerGranularity, start: Moment, end: Moment, weekStart: NonNullable<IPeriodRangePickerProps["weekStart"]>): IPeriodRange;
13
+ /**
14
+ * A grid picker for selecting a Week/Month/Quarter/Year period range. Renders the rc-picker panel matching
15
+ * {@link IPeriodRangePickerProps.granularity} and reports the resolved day-level range via `onRangeChange`.
16
+ *
17
+ * @remarks
18
+ * Loaded lazily by `PeriodRangePicker`, which is the public entry point - this module has to stay out of the
19
+ * package's eager module graph, see the note in PeriodRangePicker.tsx. Import it directly only from tests.
20
+ */
21
+ export declare function PeriodRangePickerImpl({ granularity, range, onRangeChange, isMobile, weekStart, withoutApply, submitForm }: IPeriodRangePickerProps): import("react/jsx-runtime").JSX.Element;
22
+ //# sourceMappingURL=PeriodRangePickerImpl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeriodRangePickerImpl.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/PeriodRangePicker/PeriodRangePickerImpl.tsx"],"names":[],"mappings":"AA4BA,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAU7C,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACpC,MAAM,YAAY,CAAC;AAsEpB;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAChC,WAAW,EAAE,4BAA4B,EACzC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,WAAW,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,GAC7D,YAAY,CAOd;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EAClC,WAAW,EACX,KAAK,EACL,aAAa,EACb,QAAQ,EACR,SAAoB,EACpB,YAAoB,EACpB,UAAU,EACb,EAAE,uBAAuB,2CAiEzB"}
@@ -0,0 +1,146 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { useCallback, useMemo, useRef } from "react";
4
+ import * as rcDeDE from "@rc-component/picker/locale/de_DE";
5
+ import * as rcEnGB from "@rc-component/picker/locale/en_GB";
6
+ import * as rcEnUS from "@rc-component/picker/locale/en_US";
7
+ import * as rcEsES from "@rc-component/picker/locale/es_ES";
8
+ import * as rcFiFI from "@rc-component/picker/locale/fi_FI";
9
+ import * as rcFrCA from "@rc-component/picker/locale/fr_CA";
10
+ import * as rcFrFR from "@rc-component/picker/locale/fr_FR";
11
+ import * as rcIdID from "@rc-component/picker/locale/id_ID";
12
+ import * as rcItIT from "@rc-component/picker/locale/it_IT";
13
+ import * as rcJaJP from "@rc-component/picker/locale/ja_JP";
14
+ import * as rcKoKR from "@rc-component/picker/locale/ko_KR";
15
+ import * as rcNlNL from "@rc-component/picker/locale/nl_NL";
16
+ import * as rcPlPL from "@rc-component/picker/locale/pl_PL";
17
+ import * as rcPtBR from "@rc-component/picker/locale/pt_BR";
18
+ import * as rcPtPT from "@rc-component/picker/locale/pt_PT";
19
+ import * as rcRuRU from "@rc-component/picker/locale/ru_RU";
20
+ import * as rcSlSI from "@rc-component/picker/locale/sl_SI";
21
+ import * as rcThTH from "@rc-component/picker/locale/th_TH";
22
+ import * as rcTrTR from "@rc-component/picker/locale/tr_TR";
23
+ import * as rcUkUA from "@rc-component/picker/locale/uk_UA";
24
+ import * as rcViVN from "@rc-component/picker/locale/vi_VN";
25
+ import * as rcZhCN from "@rc-component/picker/locale/zh_CN";
26
+ import * as rcZhTW from "@rc-component/picker/locale/zh_TW";
27
+ import { defaultImport } from "default-import";
28
+ import moment from "moment";
29
+ import { useIntl } from "react-intl";
30
+ import { useDebounce } from "@gooddata/sdk-ui";
31
+ import { sanitizeLocaleForMoment } from "@gooddata/util";
32
+ import { platformDateFormat } from "../constants/Platform.js";
33
+ import { resolvePeriodBoundaries } from "../utils/StaticPeriodConversions.js";
34
+ import { MomentRangePicker } from "./momentRangePicker.js";
35
+ import { getWeekStartMomentLocale } from "./weekStartMomentLocale.js";
36
+ // rc-picker's locale files carry the same ESM-`export default`-without-`"type": "module"` packaging quirk as
37
+ // its `generate/moment` module (see momentRangePicker.tsx), so the default export is unwrapped via
38
+ // `defaultImport`, which tolerates both interop shapes these modules can be loaded through.
39
+ const pickerLocale = (localeModule) => defaultImport(localeModule);
40
+ // Mirrors DatePicker.tsx's `convertedLocales`, narrowed to whichever rc-picker bundles under sdk-ui-filters's
41
+ // supported intl locale list. rc-picker has no dedicated zh_HK date-picker locale or
42
+ // en_AU — both fall back to their closest sibling (zh_TW, en_GB respectively).
43
+ const RC_PICKER_LOCALES = {
44
+ "en-US": pickerLocale(rcEnUS),
45
+ "en-US-x-24h": pickerLocale(rcEnUS),
46
+ "de-DE": pickerLocale(rcDeDE),
47
+ "es-ES": pickerLocale(rcEsES),
48
+ "fr-FR": pickerLocale(rcFrFR),
49
+ "ja-JP": pickerLocale(rcJaJP),
50
+ "nl-NL": pickerLocale(rcNlNL),
51
+ "pt-BR": pickerLocale(rcPtBR),
52
+ "pt-PT": pickerLocale(rcPtPT),
53
+ "zh-Hans": pickerLocale(rcZhCN),
54
+ "ru-RU": pickerLocale(rcRuRU),
55
+ "it-IT": pickerLocale(rcItIT),
56
+ "es-419": pickerLocale(rcEsES),
57
+ "en-GB": pickerLocale(rcEnGB),
58
+ "fr-CA": pickerLocale(rcFrCA),
59
+ "zh-Hant": pickerLocale(rcZhTW),
60
+ "en-AU": pickerLocale(rcEnGB),
61
+ "fi-FI": pickerLocale(rcFiFI),
62
+ "zh-HK": pickerLocale(rcZhTW),
63
+ "tr-TR": pickerLocale(rcTrTR),
64
+ "pl-PL": pickerLocale(rcPlPL),
65
+ "ko-KR": pickerLocale(rcKoKR),
66
+ "sl-SI": pickerLocale(rcSlSI),
67
+ "id-ID": pickerLocale(rcIdID),
68
+ "th-TH": pickerLocale(rcThTH),
69
+ "uk-UA": pickerLocale(rcUkUA),
70
+ "vi-VN": pickerLocale(rcViVN),
71
+ };
72
+ function getPickerLocale(intlLocale) {
73
+ return RC_PICKER_LOCALES[intlLocale] ?? RC_PICKER_LOCALES["en-US"];
74
+ }
75
+ const GRANULARITY_TO_PICKER_MODE = {
76
+ "GDC.time.date": "date",
77
+ "GDC.time.week_us": "week",
78
+ "GDC.time.month": "month",
79
+ "GDC.time.quarter": "quarter",
80
+ "GDC.time.year": "year",
81
+ };
82
+ function parseRangeValue(range) {
83
+ if (!range.from || !range.to) {
84
+ return null;
85
+ }
86
+ return [moment(range.from, platformDateFormat), moment(range.to, platformDateFormat)];
87
+ }
88
+ /**
89
+ * Resolves the picker's raw selected [start, end] into the exact day-level range this component reports.
90
+ *
91
+ * @remarks
92
+ * rc-picker's month/quarter/year panels hand back a start-of-unit anchor for BOTH ends of the range, so the end
93
+ * anchor still needs expanding to the last day of its period. `resolvePeriodBoundaries` already accepts "any date
94
+ * within the period" for either bound, so a start-of-unit anchor works as input either way. Day needs no expansion,
95
+ * and `resolvePeriodBoundaries` handles it as a no-op period (start/end of day), so it's routed through uniformly.
96
+ */
97
+ export function resolveSelectedRange(granularity, start, end, weekStart) {
98
+ return resolvePeriodBoundaries(granularity, start.format(platformDateFormat), end.format(platformDateFormat), weekStart);
99
+ }
100
+ /**
101
+ * A grid picker for selecting a Week/Month/Quarter/Year period range. Renders the rc-picker panel matching
102
+ * {@link IPeriodRangePickerProps.granularity} and reports the resolved day-level range via `onRangeChange`.
103
+ *
104
+ * @remarks
105
+ * Loaded lazily by `PeriodRangePicker`, which is the public entry point - this module has to stay out of the
106
+ * package's eager module graph, see the note in PeriodRangePicker.tsx. Import it directly only from tests.
107
+ */
108
+ export function PeriodRangePickerImpl({ granularity, range, onRangeChange, isMobile, weekStart = "Sunday", withoutApply = false, submitForm, }) {
109
+ const intl = useIntl();
110
+ const wrapperRef = useRef(null);
111
+ const debouncedSubmitForm = useDebounce(submitForm, 0);
112
+ const pickerMode = GRANULARITY_TO_PICKER_MODE[granularity];
113
+ const value = useMemo(() => parseRangeValue(range), [range]);
114
+ // Week-start is a workspace setting independent of display language (see weekStartMomentLocale.ts) — only
115
+ // relevant for the Week grid; Month/Quarter/Year/Day ignore it, so leave their locale's own default alone.
116
+ const locale = useMemo(() => {
117
+ const baseLocale = getPickerLocale(intl.locale);
118
+ if (granularity !== "GDC.time.week_us") {
119
+ return baseLocale;
120
+ }
121
+ const momentLocaleKey = getWeekStartMomentLocale(sanitizeLocaleForMoment(intl.locale), weekStart);
122
+ return { ...baseLocale, locale: momentLocaleKey };
123
+ }, [intl.locale, granularity, weekStart]);
124
+ const handleChange = useCallback((dates) => {
125
+ if (!dates?.[0] || !dates[1]) {
126
+ onRangeChange({ from: undefined, to: undefined });
127
+ return;
128
+ }
129
+ onRangeChange(resolveSelectedRange(granularity, dates[0], dates[1], weekStart));
130
+ if (withoutApply) {
131
+ // rc-picker's RangePicker calls onChange twice per completed selection (both with the same,
132
+ // correct final value); debouncing collapses that into a single submitForm() call rather than
133
+ // firing it twice for one user gesture. Deferred to the next render loop — mirrors
134
+ // DateRangePicker.tsx's updateRangeState, whose comment notes the newest values aren't
135
+ // propagated to state yet within the same tick.
136
+ debouncedSubmitForm();
137
+ }
138
+ }, [granularity, weekStart, withoutApply, debouncedSubmitForm, onRangeChange]);
139
+ const getPopupContainer = useCallback(() => wrapperRef.current ?? document.body, []);
140
+ return (_jsx("div", { className: isMobile
141
+ ? "gd-period-range-picker gd-period-range-picker-mobile s-period-range-picker"
142
+ : "gd-period-range-picker s-period-range-picker", ref: wrapperRef, children: _jsx(MomentRangePicker, { picker: pickerMode, value: value, onChange: handleChange, inputReadOnly: true, getPopupContainer: getPopupContainer, locale: locale,
143
+ // rc-picker's bare defaults render no clear button, a "~" separator, and no suffix icon —
144
+ // each is pinned explicitly here.
145
+ allowClear: true, separator: "\u2192", suffixIcon: _jsx("span", { className: "gd-icon-calendar", "aria-hidden": "true" }) }) }));
146
+ }
@@ -0,0 +1,9 @@
1
+ import { type RangePickerProps } from "@rc-component/picker";
2
+ import { type Moment } from "moment";
3
+ /**
4
+ * rc-picker's RangePicker with `generateConfig` pre-bound to run on `moment`, so it composes directly
5
+ * with this package's existing moment-based date handling without introducing a second date library.
6
+ */
7
+ export type MomentRangePickerProps = Omit<RangePickerProps<Moment>, "generateConfig">;
8
+ export declare function MomentRangePicker(props: MomentRangePickerProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=momentRangePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"momentRangePicker.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/PeriodRangePicker/momentRangePicker.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAWrC;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAEtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,2CAE9D"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { RangePicker } from "@rc-component/picker";
4
+ import * as momentGenerateConfigModule from "@rc-component/picker/generate/moment";
5
+ import { defaultImport } from "default-import";
6
+ const momentGenerateConfig = defaultImport(momentGenerateConfigModule);
7
+ export function MomentRangePicker(props) {
8
+ return _jsx(RangePicker, { generateConfig: momentGenerateConfig, ...props });
9
+ }
@@ -0,0 +1,28 @@
1
+ import { type DateFilterGranularity, type DateString, type WeekStart } from "@gooddata/sdk-model";
2
+ /**
3
+ * Granularities {@link PeriodRangePicker} can render a picker for.
4
+ * @alpha
5
+ */
6
+ export type PeriodRangePickerGranularity = Extract<DateFilterGranularity, "GDC.time.date" | "GDC.time.week_us" | "GDC.time.month" | "GDC.time.quarter" | "GDC.time.year">;
7
+ /**
8
+ * A day-level absolute range.
9
+ * @alpha
10
+ */
11
+ export interface IPeriodRange {
12
+ from?: DateString;
13
+ to?: DateString;
14
+ }
15
+ /**
16
+ * @alpha
17
+ */
18
+ export interface IPeriodRangePickerProps {
19
+ granularity: PeriodRangePickerGranularity;
20
+ range: IPeriodRange;
21
+ onRangeChange: (newRange: IPeriodRange) => void;
22
+ isMobile: boolean;
23
+ /** Which day a week starts on; only relevant when `granularity` is `"GDC.time.week_us"`. Defaults to "Sunday". */
24
+ weekStart?: WeekStart;
25
+ withoutApply?: boolean;
26
+ submitForm: () => void;
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/PeriodRangePicker/types.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAElG;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAC9C,qBAAqB,EACrB,eAAe,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,eAAe,CACjG,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,EAAE,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,4BAA4B,CAAC;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,kHAAkH;IAClH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ // (C) 2026 GoodData Corporation
2
+ export {};
@@ -0,0 +1,16 @@
1
+ import { type WeekStart } from "@gooddata/sdk-model";
2
+ /**
3
+ * rc-picker's moment-powered picker derives week-start purely from the active moment locale's `firstDayOfWeek()`
4
+ * (see `@rc-component/picker`'s moment `generateConfig`, `getWeekFirstDay`) — there is no standalone
5
+ * "week starts on" prop, unlike react-day-picker's `weekStartsOn` used by the existing day-grid picker. This
6
+ * app's `weekStart` is an independently configured workspace setting, not implied by display language, so we
7
+ * cannot just let the display locale's own default week-start apply: the Week grid's visual week rows must
8
+ * agree with the boundary this component actually resolves and applies (`resolvePeriodBoundaries`), or a user
9
+ * could click a visually Mon-Sun row that resolves to a different Sun-Sat range.
10
+ *
11
+ * @param baseMomentLocale - the display locale to inherit everything else (month names, formats, ...) from
12
+ * @param weekStart - the desired week-start; only the locale's `week.dow`/`week.doy` are overridden
13
+ * @returns a moment locale key carrying `baseMomentLocale`'s data with `week` overridden to match `weekStart`
14
+ */
15
+ export declare function getWeekStartMomentLocale(baseMomentLocale: string, weekStart: WeekStart): string;
16
+ //# sourceMappingURL=weekStartMomentLocale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weekStartMomentLocale.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/PeriodRangePicker/weekStartMomentLocale.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAe/F"}
@@ -0,0 +1,30 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import moment from "moment";
3
+ const LOCALE_KEY_NAMESPACE = "gdc-period-range-picker-week-start";
4
+ /**
5
+ * rc-picker's moment-powered picker derives week-start purely from the active moment locale's `firstDayOfWeek()`
6
+ * (see `@rc-component/picker`'s moment `generateConfig`, `getWeekFirstDay`) — there is no standalone
7
+ * "week starts on" prop, unlike react-day-picker's `weekStartsOn` used by the existing day-grid picker. This
8
+ * app's `weekStart` is an independently configured workspace setting, not implied by display language, so we
9
+ * cannot just let the display locale's own default week-start apply: the Week grid's visual week rows must
10
+ * agree with the boundary this component actually resolves and applies (`resolvePeriodBoundaries`), or a user
11
+ * could click a visually Mon-Sun row that resolves to a different Sun-Sat range.
12
+ *
13
+ * @param baseMomentLocale - the display locale to inherit everything else (month names, formats, ...) from
14
+ * @param weekStart - the desired week-start; only the locale's `week.dow`/`week.doy` are overridden
15
+ * @returns a moment locale key carrying `baseMomentLocale`'s data with `week` overridden to match `weekStart`
16
+ */
17
+ export function getWeekStartMomentLocale(baseMomentLocale, weekStart) {
18
+ const dow = weekStart === "Monday" ? 1 : 0;
19
+ const localeKey = `${LOCALE_KEY_NAMESPACE}-${baseMomentLocale.toLowerCase()}-${dow}`;
20
+ if (!moment.locales().includes(localeKey)) {
21
+ const parentLocale = moment.locales().includes(baseMomentLocale) ? baseMomentLocale : "en";
22
+ const previousGlobalLocale = moment.locale();
23
+ moment.defineLocale(localeKey, {
24
+ parentLocale,
25
+ week: { dow },
26
+ });
27
+ moment.locale(previousGlobalLocale);
28
+ }
29
+ return localeKey;
30
+ }
@@ -4,6 +4,10 @@ import { type DateFilterGranularity, type DateString, type EmptyValues, type IAb
4
4
  * @public
5
5
  */
6
6
  export interface IUiAbsoluteDateFilterForm extends IAbsoluteDateFilterForm {
7
+ /**
8
+ * Selected global absolute date filter granularity. Absent means "Day", for backward compatibility.
9
+ */
10
+ granularity?: DateFilterGranularity;
7
11
  /**
8
12
  * Selected global absolute date filter start date
9
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/interfaces/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/DateFilter/interfaces/index.ts"],"names":[],"mappings":"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"}