@gooddata/sdk-ui-analytical-designer 11.65.0-alpha.8 → 11.65.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/NOTICE +622 -2311
- package/README.md +31 -57
- package/esm/actions/app_context_actions.d.ts +0 -10
- package/esm/actions/app_context_actions.d.ts.map +1 -1
- package/esm/actions/app_context_actions.js +0 -1
- package/esm/backend.d.ts +20 -13
- package/esm/backend.d.ts.map +1 -1
- package/esm/backend.js +32 -89
- package/esm/components/CustomDragLayer.d.ts.map +1 -1
- package/esm/components/CustomDragLayer.js +0 -1
- package/esm/components/DragScroller/DragScroller.d.ts.map +1 -1
- package/esm/components/DragScroller/DragScroller.js +1 -2
- package/esm/components/Messages.d.ts.map +1 -1
- package/esm/components/Messages.js +13 -11
- package/esm/components/ReportTitle.js +1 -1
- package/esm/components/buckets/BucketIcon.d.ts +1 -1
- package/esm/components/buckets/BucketIcon.d.ts.map +1 -1
- package/esm/components/buckets/BucketIcon.js +11 -161
- package/esm/components/buckets/MeasureAttributeFilterPickerBody.d.ts.map +1 -1
- package/esm/components/buckets/MeasureAttributeFilterPickerBody.js +0 -1
- package/esm/components/buckets/MeasureDateFilter.d.ts.map +1 -1
- package/esm/components/filterBar/dateFilter/AdditionalFiltersSection/AdditionalDateAttributes.js +1 -1
- package/esm/components/header/VisualizationsDropdown.js +1 -1
- package/esm/components/report/PluggableVisualization.d.ts.map +1 -1
- package/esm/components/report/PluggableVisualization.js +0 -3
- package/esm/components/sort/chart_sort_button_combiners.js +1 -1
- package/esm/constants/actions.d.ts +0 -1
- package/esm/constants/actions.d.ts.map +1 -1
- package/esm/constants/actions.js +0 -2
- package/esm/embedding/AnalyticalDesigner.d.ts +0 -1
- package/esm/embedding/AnalyticalDesigner.d.ts.map +1 -1
- package/esm/embedding/AnalyticalDesigner.js +2 -4
- package/esm/embedding/AnalyticalDesignerEmbedded.d.ts +12 -9
- package/esm/embedding/AnalyticalDesignerEmbedded.d.ts.map +1 -1
- package/esm/embedding/AnalyticalDesignerEmbedded.js +5 -11
- package/esm/embedding/analyticalDesignerConfig.d.ts +0 -6
- package/esm/embedding/analyticalDesignerConfig.d.ts.map +1 -1
- package/esm/embedding/analyticalDesignerConfig.js +0 -36
- package/esm/embedding/analyticalDesignerTypes.d.ts +119 -104
- package/esm/embedding/analyticalDesignerTypes.d.ts.map +1 -1
- package/esm/embedding/hostBridge.d.ts +2 -9
- package/esm/embedding/hostBridge.d.ts.map +1 -1
- package/esm/embedding/platformContext.d.ts +4 -3
- package/esm/embedding/platformContext.d.ts.map +1 -1
- package/esm/embedding/platformContext.js +4 -5
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/internal.d.ts +3 -2
- package/esm/internal.d.ts.map +1 -1
- package/esm/internal.js +3 -2
- package/esm/models/decorated_bucket_item.js +2 -2
- package/esm/models/metadata.d.ts +17 -4
- package/esm/models/metadata.d.ts.map +1 -1
- package/esm/models/metadata.js +103 -25
- package/esm/postMessageApi/outgoing/drill_events.d.ts.map +1 -1
- package/esm/postMessageApi/outgoing/drill_events.js +10 -3
- package/esm/postMessageApi/outgoing/open_insight_events.d.ts +1 -1
- package/esm/postMessageApi/outgoing/post_event_helper.d.ts +11 -1
- package/esm/postMessageApi/outgoing/post_event_helper.d.ts.map +1 -1
- package/esm/postMessageApi/outgoing/post_event_helper.js +22 -13
- package/esm/postMessageApi/sagas/api_token_received_saga.d.ts +4 -1
- package/esm/postMessageApi/sagas/api_token_received_saga.d.ts.map +1 -1
- package/esm/postMessageApi/sagas/api_token_received_saga.js +8 -19
- package/esm/postMessageApi/sagas/command_received_saga.d.ts +4 -1
- package/esm/postMessageApi/sagas/command_received_saga.d.ts.map +1 -1
- package/esm/sagas/bootstrap_sagas.d.ts +1 -6
- package/esm/sagas/bootstrap_sagas.d.ts.map +1 -1
- package/esm/sagas/bootstrap_sagas.js +2 -7
- package/esm/sagas/open_report_sagas.d.ts +6 -0
- package/esm/sagas/open_report_sagas.d.ts.map +1 -1
- package/esm/sagas/open_report_sagas.js +13 -9
- package/esm/sagas/sagas.d.ts.map +1 -1
- package/esm/sagas/sagas.js +0 -2
- package/esm/sdk-ui-analytical-designer.d.ts +112 -95
- package/esm/selectors/bootstrap_selector.d.ts +0 -21
- package/esm/selectors/bootstrap_selector.d.ts.map +1 -1
- package/esm/selectors/bootstrap_selector.js +0 -2
- package/esm/selectors/buckets_selector.d.ts +44 -4
- package/esm/selectors/buckets_selector.d.ts.map +1 -1
- package/esm/selectors/buckets_selector.js +5 -5
- package/esm/selectors/date_datasets_selector.d.ts +88 -8
- package/esm/selectors/date_datasets_selector.d.ts.map +1 -1
- package/esm/selectors/dialogs_selector.d.ts +11 -11
- package/esm/selectors/insight_selectors.d.ts +110 -10
- package/esm/selectors/insight_selectors.d.ts.map +1 -1
- package/esm/selectors/report_selector.d.ts +44 -4
- package/esm/selectors/report_selector.d.ts.map +1 -1
- package/esm/selectors/report_visualization_selector.d.ts +26 -6
- package/esm/selectors/report_visualization_selector.d.ts.map +1 -1
- package/esm/selectors/route_selector.d.ts +1 -1
- package/esm/selectors/save_report_from_kd_dialog_selector.d.ts +11 -11
- package/esm/selectors/save_report_from_kd_dialog_selector.js +1 -1
- package/esm/selectors/save_report_selector.d.ts +3 -0
- package/esm/selectors/save_report_selector.d.ts.map +1 -1
- package/esm/selectors/save_report_selector.js +18 -2
- package/esm/selectors/uri_selector.d.ts +5 -6
- package/esm/selectors/uri_selector.d.ts.map +1 -1
- package/esm/selectors/uri_selector.js +1 -10
- package/esm/services/bootstrap_error_service.d.ts.map +1 -1
- package/esm/services/bootstrap_error_service.js +5 -14
- package/esm/translations/de-DE.json +0 -22
- package/esm/translations/en-AU.json +0 -22
- package/esm/translations/en-GB.json +3 -25
- package/esm/translations/es-419.json +0 -22
- package/esm/translations/es-ES.json +13 -35
- package/esm/translations/fi-FI.json +0 -22
- package/esm/translations/fr-CA.json +0 -22
- package/esm/translations/fr-FR.json +21 -43
- package/esm/translations/id-ID.json +0 -22
- package/esm/translations/it-IT.json +0 -22
- package/esm/translations/ja-JP.json +0 -22
- package/esm/translations/ko-KR.json +0 -22
- package/esm/translations/nl-NL.json +0 -22
- package/esm/translations/pl-PL.json +0 -22
- package/esm/translations/pt-BR.json +0 -22
- package/esm/translations/pt-PT.json +0 -22
- package/esm/translations/ru-RU.json +0 -22
- package/esm/translations/sl-SI.json +0 -22
- package/esm/translations/th-TH.json +0 -22
- package/esm/translations/tr-TR.json +0 -22
- package/esm/translations/uk-UA.json +0 -22
- package/esm/translations/vi-VN.json +0 -22
- package/esm/translations/zh-HK.json +0 -22
- package/esm/translations/zh-Hans.json +0 -22
- package/esm/translations/zh-Hant.json +0 -22
- package/esm/typings/bear/bearTypes.d.ts +0 -6
- package/esm/typings/bear/bearTypes.d.ts.map +1 -1
- package/esm/utils/appHeader.d.ts +2 -2
- package/esm/utils/appHeader.js +2 -2
- package/esm/utils/custom_mouse_backend.d.ts +1 -1
- package/esm/utils/location.d.ts +0 -1
- package/esm/utils/location.d.ts.map +1 -1
- package/esm/utils/location.js +0 -6
- package/esm/utils/organized_catalog_api.d.ts.map +1 -1
- package/esm/utils/organized_catalog_api.js +0 -1
- package/package.json +21 -23
- package/styles/css/buckets.css +7 -0
- package/styles/css/buckets.css.map +1 -1
- package/styles/css/editor_header.css +1 -1
- package/styles/css/editor_header.css.map +1 -1
- package/styles/css/main.css +11 -1
- package/styles/css/main.css.map +1 -1
- package/styles/css/typo.css +3 -0
- package/styles/css/typo.css.map +1 -1
- package/styles/scss/buckets.scss +10 -0
- package/styles/scss/editor_header.scss +2 -2
- package/styles/scss/filter_bucket.scss +2 -2
- package/styles/scss/typo.scss +4 -0
- package/esm/embedding/embeddedCallbacks.d.ts +0 -31
- package/esm/embedding/embeddedCallbacks.d.ts.map +0 -1
- package/esm/embedding/embeddedCallbacks.js +0 -59
- package/esm/sagas/external_scripts_saga.d.ts +0 -4
- package/esm/sagas/external_scripts_saga.d.ts.map +0 -1
- package/esm/sagas/external_scripts_saga.js +0 -13
- package/esm/tigerNotAuthenticatedHandler.d.ts +0 -8
- package/esm/tigerNotAuthenticatedHandler.d.ts.map +0 -1
- package/esm/tigerNotAuthenticatedHandler.js +0 -24
package/esm/models/metadata.js
CHANGED
|
@@ -46,9 +46,9 @@ function numberOrUndefined(value) {
|
|
|
46
46
|
/** The granularity of a stored All time date filter, which the sdk-model types as a literal. */
|
|
47
47
|
const ALL_TIME_GRANULARITY = "ALL_TIME_GRANULARITY";
|
|
48
48
|
/**
|
|
49
|
-
* The `emptyValueHandling` a
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
* The `emptyValueHandling` a date filter stores for the empty date values mode. Like the legacy `""`
|
|
50
|
+
* attribute filter, only exclude and only are stored: include is the backend default for All time and
|
|
51
|
+
* the picker does not offer it with a period.
|
|
52
52
|
*/
|
|
53
53
|
export function emptyValueHandlingToMd(emptyDateValuesFilter) {
|
|
54
54
|
return emptyDateValuesFilter === "exclude" || emptyDateValuesFilter === "only"
|
|
@@ -165,14 +165,29 @@ function measureFilterToMd(filter) {
|
|
|
165
165
|
},
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
function dateFilterToMd({ filterConfig, dateDatasetRef, }) {
|
|
168
|
+
function dateFilterToMd({ filterConfig, dateDatasetRef, emptyDateValuesFilter }, useEmptyValueHandling) {
|
|
169
169
|
const [from, to] = filterConfig?.interval || [undefined, undefined];
|
|
170
|
+
const emptyValueHandlingProp = useEmptyValueHandling ? emptyValueHandlingToMd(emptyDateValuesFilter) : {};
|
|
170
171
|
if (filterConfig?.type === "absolute") {
|
|
171
172
|
return {
|
|
172
173
|
absoluteDateFilter: {
|
|
173
174
|
dataSet: dateDatasetRef,
|
|
174
175
|
from: from,
|
|
175
176
|
to: to,
|
|
177
|
+
...emptyValueHandlingProp,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// All time is stored without bounds, a no-op the execution drops. To carry the empty date values mode
|
|
182
|
+
// it has to be the real All time filter, the one the execution sends.
|
|
183
|
+
if ((from === undefined || to === undefined) && !isEmpty(emptyValueHandlingProp)) {
|
|
184
|
+
return {
|
|
185
|
+
relativeDateFilter: {
|
|
186
|
+
dataSet: dateDatasetRef,
|
|
187
|
+
granularity: ALL_TIME_GRANULARITY,
|
|
188
|
+
from: 0,
|
|
189
|
+
to: 0,
|
|
190
|
+
...emptyValueHandlingProp,
|
|
176
191
|
},
|
|
177
192
|
};
|
|
178
193
|
}
|
|
@@ -184,6 +199,7 @@ function dateFilterToMd({ filterConfig, dateDatasetRef, }) {
|
|
|
184
199
|
from: numberOrUndefined(from),
|
|
185
200
|
to: numberOrUndefined(to),
|
|
186
201
|
...(filterConfig?.boundedFilter ? { boundedFilter: filterConfig.boundedFilter } : {}),
|
|
202
|
+
...emptyValueHandlingProp,
|
|
187
203
|
}),
|
|
188
204
|
};
|
|
189
205
|
}
|
|
@@ -293,9 +309,9 @@ function rankingFilterToMd(filter) {
|
|
|
293
309
|
},
|
|
294
310
|
};
|
|
295
311
|
}
|
|
296
|
-
function filterToMd(filter, attributeFilterConfigs) {
|
|
312
|
+
function filterToMd(filter, attributeFilterConfigs, useEmptyValueHandling) {
|
|
297
313
|
if (FilterBar.isDateFilter(filter)) {
|
|
298
|
-
return dateFilterToMd(filter);
|
|
314
|
+
return dateFilterToMd(filter, useEmptyValueHandling);
|
|
299
315
|
}
|
|
300
316
|
else if (FilterBar.isAttributeFilter(filter)) {
|
|
301
317
|
return attributeFilterToMd(filter, attributeFilterConfigs);
|
|
@@ -519,8 +535,10 @@ function findDateAttributeDfRef(dateDatasetRef, dateDatasets, granularity) {
|
|
|
519
535
|
return dateAttribute?.dfRef;
|
|
520
536
|
}
|
|
521
537
|
/**
|
|
522
|
-
*
|
|
523
|
-
*
|
|
538
|
+
* LEGACY representation of the empty date values mode, written while `enableImprovedMetricDateFilter` is
|
|
539
|
+
* off: an attribute filter on the date attribute of the date filter's granularity with the single empty
|
|
540
|
+
* string element. With the flag on the mode is written as the date filter's `emptyValueHandling`
|
|
541
|
+
* instead; both representations are always read (see transformVisualizationFilters).
|
|
524
542
|
* Returns undefined if no filter should be created (e.g., for "include" mode).
|
|
525
543
|
*/
|
|
526
544
|
function createEmptyDateValuesAttributeFilter(dateFilter, dateDatasets) {
|
|
@@ -554,12 +572,16 @@ function createEmptyDateValuesAttributeFilter(dateFilter, dateDatasets) {
|
|
|
554
572
|
}
|
|
555
573
|
return undefined;
|
|
556
574
|
}
|
|
557
|
-
|
|
575
|
+
/**
|
|
576
|
+
* @param useEmptyValueHandling - whether the empty date values mode is written as the date filter's
|
|
577
|
+
* `emptyValueHandling` (the `enableImprovedMetricDateFilter` flag) or as the legacy `""` attribute filter,
|
|
578
|
+
* which needs `dateDatasets` to find the date attribute.
|
|
579
|
+
*/
|
|
580
|
+
export function filtersToMetadata(filters, attributeFilterConfigs = {}, dateDatasets, useEmptyValueHandling = false) {
|
|
558
581
|
const result = [];
|
|
559
582
|
filters.forEach((filter) => {
|
|
560
|
-
result.push(filterToMd(filter, attributeFilterConfigs));
|
|
561
|
-
|
|
562
|
-
if (FilterBar.isDateFilter(filter)) {
|
|
583
|
+
result.push(filterToMd(filter, attributeFilterConfigs, useEmptyValueHandling));
|
|
584
|
+
if (!useEmptyValueHandling && FilterBar.isDateFilter(filter)) {
|
|
563
585
|
const emptyValuesFilter = createEmptyDateValuesAttributeFilter(filter, dateDatasets);
|
|
564
586
|
if (emptyValuesFilter) {
|
|
565
587
|
result.push(emptyValuesFilter);
|
|
@@ -807,7 +829,8 @@ function transformVisualizationFilter(filter, data, overTimeComparisonType) {
|
|
|
807
829
|
function transformToDateFilterConfig(visualizationFilter) {
|
|
808
830
|
if (isVisualizationObjectRelativeDateFilter(visualizationFilter)) {
|
|
809
831
|
const { granularity, from, to, boundedFilter } = visualizationFilter.relativeDateFilter;
|
|
810
|
-
|
|
832
|
+
// All time: stored without bounds, or as the real All time filter when it carries a mode
|
|
833
|
+
if (granularity === ALL_TIME_GRANULARITY || from === undefined || to === undefined) {
|
|
811
834
|
return undefined;
|
|
812
835
|
}
|
|
813
836
|
const selectedPresetItem = PRESETS.find((presetItem) => presetItem.granularity === granularity &&
|
|
@@ -831,9 +854,7 @@ function transformToDateFilterConfig(visualizationFilter) {
|
|
|
831
854
|
throw new Error("Unsupported visualization date filter type");
|
|
832
855
|
}
|
|
833
856
|
function transformVisualizationDateFilter(visualizationFilter, overTimeComparisonType, ignoreOverTimeComparisonType) {
|
|
834
|
-
let datasetRef =
|
|
835
|
-
? visualizationFilter.relativeDateFilter.dataSet
|
|
836
|
-
: visualizationFilter.absoluteDateFilter.dataSet;
|
|
857
|
+
let datasetRef = getDateFilterDataSet(visualizationFilter);
|
|
837
858
|
/**
|
|
838
859
|
* convertor from SDK returns ref without type
|
|
839
860
|
*/
|
|
@@ -841,6 +862,7 @@ function transformVisualizationDateFilter(visualizationFilter, overTimeCompariso
|
|
|
841
862
|
...datasetRef,
|
|
842
863
|
type: "dataSet",
|
|
843
864
|
};
|
|
865
|
+
const emptyDateValuesFilter = getDateFilterEmptyValueHandling(visualizationFilter);
|
|
844
866
|
return {
|
|
845
867
|
type: "date",
|
|
846
868
|
localIdentifier: generateBucketItemIdentifier(),
|
|
@@ -850,8 +872,15 @@ function transformVisualizationDateFilter(visualizationFilter, overTimeCompariso
|
|
|
850
872
|
: { overTimeComparisonType }),
|
|
851
873
|
filterConfig: transformToDateFilterConfig(visualizationFilter),
|
|
852
874
|
dateDatasetRef: datasetRef,
|
|
875
|
+
...(emptyDateValuesFilter ? { emptyDateValuesFilter } : {}),
|
|
853
876
|
};
|
|
854
877
|
}
|
|
878
|
+
/** The date dataset a stored date filter filters on. */
|
|
879
|
+
function getDateFilterDataSet(visualizationFilter) {
|
|
880
|
+
return isVisualizationObjectRelativeDateFilter(visualizationFilter)
|
|
881
|
+
? visualizationFilter.relativeDateFilter.dataSet
|
|
882
|
+
: visualizationFilter.absoluteDateFilter.dataSet;
|
|
883
|
+
}
|
|
855
884
|
/** The empty date values mode a stored date filter carries as `emptyValueHandling`, if any. */
|
|
856
885
|
function getDateFilterEmptyValueHandling(visualizationFilter) {
|
|
857
886
|
return isVisualizationObjectRelativeDateFilter(visualizationFilter)
|
|
@@ -1049,23 +1078,71 @@ function detectEmptyDateValuesAttributeFilter(attributeFilter, dateDatasets) {
|
|
|
1049
1078
|
}
|
|
1050
1079
|
return undefined;
|
|
1051
1080
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* Finds the LEGACY empty date values attribute filters (the single-"" element filters on a date
|
|
1083
|
+
* attribute), kept readable so insights saved before the mode moved to `emptyValueHandling` open.
|
|
1084
|
+
*/
|
|
1085
|
+
function collectLegacyEmptyDateValuesFilters(visualizationFilters, dateDatasets) {
|
|
1086
|
+
// keyed by the date dataset ref string
|
|
1056
1087
|
const emptyDateValuesFilters = {};
|
|
1057
1088
|
const emptyDateValuesFilterIndices = new globalThis.Set();
|
|
1058
1089
|
visualizationFilters.forEach((filter, index) => {
|
|
1059
1090
|
if (isVisualizationObjectAttributeFilter(filter)) {
|
|
1060
1091
|
const detected = detectEmptyDateValuesAttributeFilter(filter, dateDatasets);
|
|
1061
1092
|
if (detected) {
|
|
1062
|
-
|
|
1063
|
-
const key = objRefToString(detected.dateDatasetRef);
|
|
1064
|
-
emptyDateValuesFilters[key] = detected;
|
|
1093
|
+
emptyDateValuesFilters[objRefToString(detected.dateDatasetRef)] = detected;
|
|
1065
1094
|
emptyDateValuesFilterIndices.add(index);
|
|
1066
1095
|
}
|
|
1067
1096
|
}
|
|
1068
1097
|
});
|
|
1098
|
+
return { emptyDateValuesFilters, emptyDateValuesFilterIndices };
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Rewrites the stored filters so that every representation of the same empty date values mode compares
|
|
1102
|
+
* equal: the legacy `""` attribute filter is folded into its date filter's `emptyValueHandling` (the way
|
|
1103
|
+
* the reader does), All time with a mode becomes the ALL_TIME_GRANULARITY filter whether it is stored with
|
|
1104
|
+
* bounds or without, and the `include` default is dropped as the writer drops it. Only for comparing
|
|
1105
|
+
* stored content, the result is never saved.
|
|
1106
|
+
*/
|
|
1107
|
+
export function normalizeEmptyDateValuesFilters(visualizationFilters, dateDatasets) {
|
|
1108
|
+
const { emptyDateValuesFilters, emptyDateValuesFilterIndices } = collectLegacyEmptyDateValuesFilters(visualizationFilters, dateDatasets);
|
|
1109
|
+
return visualizationFilters
|
|
1110
|
+
.filter((_filter, index) => !emptyDateValuesFilterIndices.has(index))
|
|
1111
|
+
.map((filter) => {
|
|
1112
|
+
if (!isVisualizationObjectDateFilter(filter)) {
|
|
1113
|
+
return filter;
|
|
1114
|
+
}
|
|
1115
|
+
const dataSet = getDateFilterDataSet(filter);
|
|
1116
|
+
const storedMode = getDateFilterEmptyValueHandling(filter);
|
|
1117
|
+
const mode = emptyValueHandlingToMd(storedMode ?? emptyDateValuesFilters[objRefToString(dataSet)]?.mode);
|
|
1118
|
+
if (isVisualizationObjectAbsoluteDateFilter(filter)) {
|
|
1119
|
+
return {
|
|
1120
|
+
absoluteDateFilter: { ...omit(filter.absoluteDateFilter, "emptyValueHandling"), ...mode },
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
const { granularity, from, to } = filter.relativeDateFilter;
|
|
1124
|
+
const isAllTime = granularity === ALL_TIME_GRANULARITY || from === undefined || to === undefined;
|
|
1125
|
+
if (isAllTime && !isEmpty(mode)) {
|
|
1126
|
+
return {
|
|
1127
|
+
relativeDateFilter: {
|
|
1128
|
+
dataSet,
|
|
1129
|
+
granularity: ALL_TIME_GRANULARITY,
|
|
1130
|
+
from: 0,
|
|
1131
|
+
to: 0,
|
|
1132
|
+
...mode,
|
|
1133
|
+
},
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
return {
|
|
1137
|
+
relativeDateFilter: { ...omit(filter.relativeDateFilter, "emptyValueHandling"), ...mode },
|
|
1138
|
+
};
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
function transformVisualizationFilters(metadataObject, overTimeComparisonType, additionalData) {
|
|
1142
|
+
const visualizationFilters = metadataObject.filters || [];
|
|
1143
|
+
const dateDatasets = additionalData?.dateDatasets || undefined;
|
|
1144
|
+
// First pass: identify the legacy empty date values attribute filters
|
|
1145
|
+
const { emptyDateValuesFilters, emptyDateValuesFilterIndices } = collectLegacyEmptyDateValuesFilters(visualizationFilters, dateDatasets);
|
|
1069
1146
|
// Second pass: transform filters, setting emptyDateValuesFilter on date filters
|
|
1070
1147
|
let firstDateFilterTransformed = false;
|
|
1071
1148
|
const result = [];
|
|
@@ -1081,11 +1158,12 @@ function transformVisualizationFilters(metadataObject, overTimeComparisonType, a
|
|
|
1081
1158
|
}
|
|
1082
1159
|
else if (isVisualizationObjectDateFilter(visualizationFilter)) {
|
|
1083
1160
|
let df = transformVisualizationDateFilter(visualizationFilter, overTimeComparisonType, firstDateFilterTransformed);
|
|
1084
|
-
//
|
|
1161
|
+
// the legacy "" attribute filter sets the mode unless the date filter carries it itself; either
|
|
1162
|
+
// way the attribute filter is dropped, so re-saving migrates the insight to the field
|
|
1085
1163
|
const dateDatasetRef = df.dateDatasetRef;
|
|
1086
1164
|
const key = objRefToString(dateDatasetRef);
|
|
1087
1165
|
const emptyValuesInfo = emptyDateValuesFilters[key];
|
|
1088
|
-
if (emptyValuesInfo) {
|
|
1166
|
+
if (emptyValuesInfo && !df.emptyDateValuesFilter) {
|
|
1089
1167
|
df = { ...df, emptyDateValuesFilter: emptyValuesInfo.mode };
|
|
1090
1168
|
}
|
|
1091
1169
|
firstDateFilterTransformed = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drill_events.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/outgoing/drill_events.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"drill_events.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/outgoing/drill_events.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,wBAAgB,cAAc,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI,CAS5D"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { GdcAdEventType } from "@gooddata/sdk-embedding";
|
|
3
|
+
import { getHostAdapter } from "../../embedding/hostBridge.js";
|
|
3
4
|
import { transformDrillEventToLegacy } from "../../utils/drilling/index.js";
|
|
4
|
-
import {
|
|
5
|
+
import { postHostEvent, postWindowEvent } from "./post_event_helper.js";
|
|
5
6
|
export function drillPerformed(drillEvent) {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
// A host component receives the drill event of @gooddata/sdk-ui; the postMessage contract carries
|
|
8
|
+
// the legacy shape.
|
|
9
|
+
const hostAdapter = getHostAdapter();
|
|
10
|
+
if (hostAdapter) {
|
|
11
|
+
postHostEvent(hostAdapter, GdcAdEventType.Drill, drillEvent);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
postWindowEvent(GdcAdEventType.Drill, transformDrillEventToLegacy(drillEvent));
|
|
8
15
|
}
|
|
@@ -6,7 +6,7 @@ export declare const insightNotFoundError: ICommandFailedBody;
|
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
8
|
* What the InsightOpened event carries. Deliberately NOT sdk-embedding's AdInsightOpenedBody:
|
|
9
|
-
* its `definition` differs from what AD has always posted
|
|
9
|
+
* its `definition` differs from what AD has always posted.
|
|
10
10
|
*/
|
|
11
11
|
export interface IAdInsightOpenedBody {
|
|
12
12
|
availableCommands: GdcAdCommandType[];
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { type AnalyticalDesignerEventType, type IAnalyticalDesignerEventDataMap } from "../../embedding/analyticalDesignerTypes.js";
|
|
2
|
+
import { type IAdHostAdapter } from "../../embedding/hostBridge.js";
|
|
3
|
+
/** Delivers an event to the host that renders AD as a React component. */
|
|
4
|
+
export declare function postHostEvent<T extends AnalyticalDesignerEventType>(hostAdapter: IAdHostAdapter, type: T, data: IAnalyticalDesignerEventDataMap[T], contextId?: string): void;
|
|
5
|
+
/** Posts an event as a window message; data is the @gooddata/sdk-embedding contract payload. */
|
|
6
|
+
export declare function postWindowEvent(type: AnalyticalDesignerEventType, data: unknown, contextId?: string): void;
|
|
7
|
+
/**
|
|
8
|
+
* Emits an event to the host: to the host component when one is installed, else as a window message.
|
|
9
|
+
* Drill is emitted by drillPerformed: the two transports carry different payloads for it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function adPostEvent<T extends Exclude<AnalyticalDesignerEventType, "drill">>(type: T, data: IAnalyticalDesignerEventDataMap[T], contextId?: string): void;
|
|
2
12
|
//# sourceMappingURL=post_event_helper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post_event_helper.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/outgoing/post_event_helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"post_event_helper.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/outgoing/post_event_helper.ts"],"names":[],"mappings":"AAKA,OAAO,EAEH,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACvC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,+BAA+B,CAAC;AAOpF,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,SAAS,2BAA2B,EAC/D,WAAW,EAAE,cAAc,EAC3B,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,EACxC,SAAS,CAAC,EAAE,MAAM,GACnB,IAAI,CAKN;AAED,gGAAgG;AAChG,wBAAgB,eAAe,CAAC,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAO1G;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,OAAO,CAAC,2BAA2B,EAAE,OAAO,CAAC,EAC/E,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,EACxC,SAAS,CAAC,EAAE,MAAM,GACnB,IAAI,CAON"}
|
|
@@ -3,20 +3,29 @@ import { GdcProductName } from "@gooddata/sdk-embedding";
|
|
|
3
3
|
import { messagingUtils } from "@gooddata/sdk-embedding/internal";
|
|
4
4
|
import { getHostAdapter } from "../../embedding/hostBridge.js";
|
|
5
5
|
import { DEFAULT_POST_MESSAGE_CONTEXT_ID } from "../actions/post_message_action_helper.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const resetDefaultContextId = (contextId) => {
|
|
7
|
+
return contextId && contextId === DEFAULT_POST_MESSAGE_CONTEXT_ID ? undefined : contextId;
|
|
8
|
+
};
|
|
9
|
+
/** Delivers an event to the host that renders AD as a React component. */
|
|
10
|
+
export function postHostEvent(hostAdapter, type, data, contextId) {
|
|
11
|
+
const event = { type, data, contextId: resetDefaultContextId(contextId) };
|
|
12
|
+
// every AnalyticalDesignerEvent<T> is an AnalyticalDesignerEvent; TypeScript cannot widen a
|
|
13
|
+
// generic mapped union (TS#30581)
|
|
14
|
+
hostAdapter.onEvent(event);
|
|
15
|
+
}
|
|
16
|
+
/** Posts an event as a window message; data is the @gooddata/sdk-embedding contract payload. */
|
|
17
|
+
export function postWindowEvent(type, data, contextId) {
|
|
18
|
+
messagingUtils.postEvent(GdcProductName.ANALYTICAL_DESIGNER, type, data, resetDefaultContextId(contextId));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Emits an event to the host: to the host component when one is installed, else as a window message.
|
|
22
|
+
* Drill is emitted by drillPerformed: the two transports carry different payloads for it.
|
|
23
|
+
*/
|
|
24
|
+
export function adPostEvent(type, data, contextId) {
|
|
11
25
|
const hostAdapter = getHostAdapter();
|
|
12
26
|
if (hostAdapter) {
|
|
13
|
-
hostAdapter
|
|
14
|
-
product: GdcProductName.ANALYTICAL_DESIGNER,
|
|
15
|
-
name,
|
|
16
|
-
data,
|
|
17
|
-
contextId: resetDefaultContextId(contextId),
|
|
18
|
-
});
|
|
27
|
+
postHostEvent(hostAdapter, type, data, contextId);
|
|
19
28
|
return;
|
|
20
29
|
}
|
|
21
|
-
|
|
22
|
-
}
|
|
30
|
+
postWindowEvent(type, data, contextId);
|
|
31
|
+
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { type AdSetApiTokenCommandData } from "@gooddata/sdk-embedding";
|
|
2
|
-
export declare function handleReceivedApiToken(setApiTokenContext: AdSetApiTokenCommandData): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").
|
|
2
|
+
export declare function handleReceivedApiToken(setApiTokenContext: AdSetApiTokenCommandData): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").PutEffect<{
|
|
3
|
+
payload: undefined;
|
|
4
|
+
type: import("../../sagas/application_context/application_context_actions.js").ApplicationContextActionsTypeKeys;
|
|
5
|
+
}> | import("redux-saga/effects").SelectEffect, void, string | undefined>;
|
|
3
6
|
//# sourceMappingURL=api_token_received_saga.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api_token_received_saga.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/sagas/api_token_received_saga.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"api_token_received_saga.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/sagas/api_token_received_saga.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAexE,wBAAiB,sBAAsB,CAAC,kBAAkB,EAAE,wBAAwB;;;0EAuCnF"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { call, put, select } from "redux-saga/effects";
|
|
3
|
-
import {
|
|
3
|
+
import { isValidApiTokenType, setApiTokenHandler, setJwtHandler } from "../../backend.js";
|
|
4
4
|
import { backendInitialized } from "../../sagas/application_context/application_context_actions.js";
|
|
5
5
|
import { storeApiToken } from "../../store/application_context/app_context_actions.js";
|
|
6
6
|
import { selectApiToken, selectApiTokenType } from "../../store/application_context/app_context_selector.js";
|
|
7
|
-
import { getExternalProviderIdParam } from "../../utils/location.js";
|
|
8
7
|
import { postInvalidCommandArgument } from "../outgoing/invalid_command_events.js";
|
|
9
8
|
import { getPostMessageContextIdFromCommandData } from "./post_message_saga_helper.js";
|
|
10
9
|
const DEFAULT_TOKEN_TYPE = "gooddata";
|
|
@@ -31,29 +30,20 @@ export function* handleReceivedApiToken(setApiTokenContext) {
|
|
|
31
30
|
return;
|
|
32
31
|
}
|
|
33
32
|
const previousToken = yield select(selectApiToken);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else if (type === "gooddata") {
|
|
33
|
+
// The first token and a renewal take the same path: the host's setter decides whether it renews
|
|
34
|
+
// its provider in place or switches the backend to the token (a first token over cookie auth).
|
|
35
|
+
if (type === "gooddata") {
|
|
38
36
|
yield call(updateApiTokenValue, apiToken);
|
|
39
37
|
}
|
|
40
38
|
else if (type === "jwt") {
|
|
41
39
|
yield call(updateJwtValue, apiToken, contextId);
|
|
42
40
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// A host-adopted backend must never be replaced from here — the host's provider already
|
|
46
|
-
// authenticates; only record the token (components like the metric editor read it).
|
|
47
|
-
if (!isHostBackendAdopted) {
|
|
48
|
-
const externalProviderId = yield call(getExternalProviderIdParam);
|
|
49
|
-
yield call(reinitializeBackend, apiToken, externalProviderId);
|
|
41
|
+
if (previousToken === undefined) {
|
|
42
|
+
yield put(backendInitialized());
|
|
50
43
|
}
|
|
51
|
-
yield put(storeApiToken(apiToken.apiToken, apiToken.apiTokenType));
|
|
52
|
-
yield put(backendInitialized());
|
|
53
44
|
}
|
|
54
45
|
function* updateApiTokenValue({ apiToken: token, apiTokenType }) {
|
|
55
|
-
// No handler means
|
|
56
|
-
// already renewed its provider in place; only keep the stored token in sync.
|
|
46
|
+
// No handler means the host renews its auth provider itself; only keep the stored token in sync.
|
|
57
47
|
if (setApiTokenHandler) {
|
|
58
48
|
setApiTokenHandler(token);
|
|
59
49
|
// oxlint-disable-next-line eslint-js/no-console
|
|
@@ -64,8 +54,7 @@ function* updateApiTokenValue({ apiToken: token, apiTokenType }) {
|
|
|
64
54
|
function* updateJwtValue(apiToken, contextId) {
|
|
65
55
|
const { apiToken: token, apiTokenType, secondsBeforeTokenExpirationToCallReminder } = apiToken;
|
|
66
56
|
try {
|
|
67
|
-
// No handler means
|
|
68
|
-
// already renewed its provider in place; only keep the stored token in sync.
|
|
57
|
+
// No handler means the host renews its auth provider itself; only keep the stored token in sync.
|
|
69
58
|
if (setJwtHandler) {
|
|
70
59
|
// set token to backend instance via callback we received from the expiration reminder
|
|
71
60
|
setJwtHandler(token, secondsBeforeTokenExpirationToCallReminder);
|
|
@@ -2,7 +2,10 @@ import { type IDrillableItemsCommandBody } from "@gooddata/sdk-embedding";
|
|
|
2
2
|
import { PostEventActionTypeKeys } from "../actions/action_types.js";
|
|
3
3
|
import { type ICommandReceivedAction } from "../actions/command_received_actions.js";
|
|
4
4
|
export declare function validateHostDomain(organizationId: string, url: string): Promise<boolean>;
|
|
5
|
-
export declare function handleReceivedCommand({ payload: { data: commandData, origin: commandOrigin }, }: ICommandReceivedAction): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").CallEffect<boolean> | Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").
|
|
5
|
+
export declare function handleReceivedCommand({ payload: { data: commandData, origin: commandOrigin }, }: ICommandReceivedAction): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").CallEffect<boolean> | Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").PutEffect<{
|
|
6
|
+
payload: undefined;
|
|
7
|
+
type: import("../../sagas/application_context/application_context_actions.js").ApplicationContextActionsTypeKeys;
|
|
8
|
+
}> | import("redux-saga/effects").SelectEffect, void, string | undefined> | Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").PutEffect<{
|
|
6
9
|
payload: import("../../actions/confirm_unsaved_changes_actions.js").IConfirmUnsavedChangesDialogActionPayload;
|
|
7
10
|
type: import("../../constants/actions.js").ActionTypeKeys.SAGA_CONFIRM_UNSAVED_CHANGES_REQUEST;
|
|
8
11
|
}> | import("redux-saga/effects").SelectEffect, void, boolean> | Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").PutEffect<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command_received_saga.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/sagas/command_received_saga.ts"],"names":[],"mappings":"AAIA,OAAO,EAIH,KAAK,0BAA0B,EAgBlC,MAAM,yBAAyB,CAAC;AAYjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAiBrF,wBAAsB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9F;AAqDD,wBAAiB,qBAAqB,CAAC,EACnC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,GACxD,EAAE,sBAAsB
|
|
1
|
+
{"version":3,"file":"command_received_saga.d.ts","sourceRoot":"","sources":["../../../src/postMessageApi/sagas/command_received_saga.ts"],"names":[],"mappings":"AAIA,OAAO,EAIH,KAAK,0BAA0B,EAgBlC,MAAM,yBAAyB,CAAC;AAYjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAiBrF,wBAAsB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9F;AAqDD,wBAAiB,qBAAqB,CAAC,EACnC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,GACxD,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA4DxB;AAED,wBAAiB,oBAAoB,6EAEpC"}
|
|
@@ -18,15 +18,10 @@ export declare function bootstrap(routeParams: ICustomRouteParams): Generator<im
|
|
|
18
18
|
isEmptyReport: boolean;
|
|
19
19
|
};
|
|
20
20
|
type: import("../constants/actions.js").ActionTypeKeys.APP_FINISHED_SUCCESSFUL_INITIALIZATION;
|
|
21
|
-
}> | import("redux-saga/effects").PutEffect<{
|
|
22
|
-
payload: {
|
|
23
|
-
scripts: import("../actions/app_context_actions.js").IExternalScripts;
|
|
24
|
-
};
|
|
25
|
-
type: import("../constants/actions.js").ActionTypeKeys.LOAD_EXTERNAL_SCRIPTS_REQUESTED;
|
|
26
21
|
}> | import("redux-saga/effects").PutEffect<{
|
|
27
22
|
payload: {
|
|
28
23
|
firstLoaded: boolean;
|
|
29
24
|
};
|
|
30
25
|
type: import("../store/catalog/catalog_store_actions.js").CatalogActionTypeKeys.STORE_SET_CATALOG_FIRST_LOADED;
|
|
31
|
-
}> | import("redux-saga/effects").SelectEffect, void,
|
|
26
|
+
}> | import("redux-saga/effects").SelectEffect, void, string | undefined>;
|
|
32
27
|
//# sourceMappingURL=bootstrap_sagas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap_sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/bootstrap_sagas.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"bootstrap_sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/bootstrap_sagas.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,KAAK,cAAc,EAKtB,MAAM,mCAAmC,CAAC;AAM3C,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAejE,wBAAiB,SAAS,0HAGzB;AAED,wBAAiB,SAAS,CAAC,WAAW,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;0EAoEzD"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
3
3
|
import { all, call, put, select } from "redux-saga/effects";
|
|
4
4
|
import { isContractExpired, isNotAuthenticated, isProtectedDataError } from "@gooddata/sdk-backend-spi";
|
|
5
|
-
import { appFinishedLoading, appFinishedSuccessfulInitialization, appStartedLoading, bootstrapError,
|
|
5
|
+
import { appFinishedLoading, appFinishedSuccessfulInitialization, appStartedLoading, bootstrapError, } from "../actions/app_context_actions.js";
|
|
6
6
|
import { DEFAULT_REPORT_ID } from "../constants/route_params.js";
|
|
7
|
-
import {
|
|
7
|
+
import { getProjectId } from "../selectors/bootstrap_selector.js";
|
|
8
8
|
import { SERVICE_NAME, VERSION } from "../services/telemetry/openTelemetry/constants.js";
|
|
9
9
|
import { logAccessingAD } from "../services/telemetry/tracking_events.js";
|
|
10
10
|
import { setCatalogFirstLoaded } from "../store/catalog/catalog_store_actions.js";
|
|
@@ -31,11 +31,6 @@ export function* bootstrap(routeParams) {
|
|
|
31
31
|
// Verify if user has all required permissions & feature flags for current app context
|
|
32
32
|
// Throws error, when not
|
|
33
33
|
yield call(verifyUserAccess);
|
|
34
|
-
// Load external scripts, when provided
|
|
35
|
-
const extScripts = yield select(externalScripts);
|
|
36
|
-
if (extScripts) {
|
|
37
|
-
yield put(loadExternalScripts(extScripts));
|
|
38
|
-
}
|
|
39
34
|
// Set current workspaceId as a stashed project in the user profile settings
|
|
40
35
|
const currentProjectId = yield select(getProjectId);
|
|
41
36
|
yield call(loadVisualizationClasses, currentProjectId);
|
|
@@ -85,6 +85,12 @@ export declare function selectOpenReportFailureReset(): Generator<import("redux-
|
|
|
85
85
|
* every missing item instead of surfacing as a backend error or a broken page.
|
|
86
86
|
*/
|
|
87
87
|
export declare function failOnMissingDateFilterItems(insight: IInsight): Generator<import("redux-saga/effects").SelectEffect, void, import("../models/date_datasets_meta.js").IDateDatasetsMeta>;
|
|
88
|
+
/**
|
|
89
|
+
* Whether one of the insight's relative date filters has a granularity AD cannot load. All time is
|
|
90
|
+
* supported: it is stored as the real All time filter (ALL_TIME_GRANULARITY) when it carries the empty
|
|
91
|
+
* date values mode.
|
|
92
|
+
*/
|
|
93
|
+
export declare function hasDateFilterWithUnsupportedGranularity(insight: IInsight): boolean;
|
|
88
94
|
export declare function fetchReport(projectId: string, reportId: string): Generator<import("redux-saga/effects").AllEffect<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").CallEffect<IMetadataObject[]>> | import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").CallEffect<number> | import("redux-saga/effects").CallEffect<import("@gooddata/sdk-model").IListedDashboard[]> | import("redux-saga/effects").CallEffect<IApplicationResetCarrier> | import("redux-saga/effects").CallEffect<import("../store/report/open_report_operation.js").IOpenReportResult> | import("redux-saga/effects").CallEffect<IParameterRestoreResult> | import("redux-saga/effects").CallEffect<{
|
|
89
95
|
itemCache: {
|
|
90
96
|
[x: string]: import("../typings/state_objects.js").ICatalogEntry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open_report_sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/open_report_sagas.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EACH,KAAK,QAAQ,EACb,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"open_report_sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/open_report_sagas.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EACH,KAAK,QAAQ,EACb,KAAK,eAAe,EAWvB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACH,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAKlC,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AA2BzD,OAAO,EACH,KAAK,uBAAuB,EAE/B,MAAM,iDAAiD,CAAC;AASzD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAKnD,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,KAAK,kBAAkB,EAA+B,MAAM,sBAAsB,CAAC;AAyB5F,wBAAgB,YAAY,WAE3B;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,UAE5C;AAED,wBAAiB,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,0BAA0B;;;;;6DAuBtG;AAED,wBAAiB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,kHAazE;AAcD,wBAAiB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,2LAa1E;AAED;;;GAGG;AACH,wBAAiB,6BAA6B,CAAC,mBAAmB,EAAE,eAAe,EAAE;;;;;qJAsCpF;AAED,wBAAiB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,oBAAoB,GAAE,OAAe;;;;;;;;;;;;;;;;;;;GAoBtG;AAED;;;;;;;;;;GAUG;AACH,wBAAiB,uBAAuB,CAAC,MAAM,GAAE,kBAAuB;;;;;mBAKvE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACnC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,QAAQ,EACjB,WAAW,EAAE,kBAAkB,EAC/B,eAAe,EAAE,OAAO,wEAwB3B;AAED,wBAAiB,qBAAqB,CAClC,OAAO,EAAE,QAAQ,EACjB,WAAW,EAAE,kBAAkB,EAC/B,eAAe,EAAE,OAAO,yIAI3B;AAED;;;;GAIG;AACH,wBAAiB,4BAA4B,uLAK5C;AAqBD;;;;;GAKG;AACH,wBAAiB,4BAA4B,CAAC,OAAO,EAAE,QAAQ,2HAU9D;AAED;;;;GAIG;AACH,wBAAgB,uCAAuC,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAQlF;AAKD,wBAAiB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGA6F/D;AAED,wBAAiB,eAAe,CAAC,SAAS,EAAE,MAAM,4MAOjD;AAED,wBAAiB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+HAyEpE;AAED,wBAAiB,8BAA8B,CAAC,OAAO,EAAE,QAAQ,8JAchE;AAED,wBAAiB,qBAAqB,CAAC,EACnC,OAAO,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,GACrD,EAAE,yBAAyB;;;;;;;;0EA0B3B;AAMD,wBAAiB,eAAe,6EAK/B"}
|
|
@@ -4,7 +4,7 @@ import { defineMessages } from "react-intl";
|
|
|
4
4
|
import { all, call, delay, put, select, take, takeEvery } from "redux-saga/effects";
|
|
5
5
|
import { v4 as uuid } from "uuid";
|
|
6
6
|
import { dateAttributeIdToSdkGranularity } from "@gooddata/sdk-backend-tiger";
|
|
7
|
-
import { insightParameters, insightSorts, insightUri, insightVisualizationUrl, isDateFilterGranularity, isRelativeDateFilter, isUriRef, objRefToString, uriRef, } from "@gooddata/sdk-model";
|
|
7
|
+
import { insightParameters, insightSorts, insightUri, insightVisualizationUrl, isAllTimeDateFilter, isDateFilterGranularity, isRelativeDateFilter, isUriRef, objRefToString, uriRef, } from "@gooddata/sdk-model";
|
|
8
8
|
import { changeDataset, updateInsightUsageOnDashboards, updateItemCache } from "../actions/data_actions.js";
|
|
9
9
|
import { addMessage, hideMessage, showWarningMessage } from "../actions/messages_actions.js";
|
|
10
10
|
import { openReportConfirmation, openReportFailed, openReportFinished, openReportStarted, } from "../actions/open_actions.js";
|
|
@@ -97,7 +97,6 @@ function stripQueryParams(uri) {
|
|
|
97
97
|
const questionMarkIndex = uri.indexOf("?");
|
|
98
98
|
// for some reason when we use includeObjectsWithTags or excludeObjectsWithTags, the URI contains a query parameter
|
|
99
99
|
// we need to strip it to get the correct URI
|
|
100
|
-
// see https://gooddata.atlassian.net/browse/EB-448
|
|
101
100
|
return questionMarkIndex === -1 ? uri : uri.substring(0, questionMarkIndex);
|
|
102
101
|
}
|
|
103
102
|
export function* getObjectsReferencing(projectId, insight) {
|
|
@@ -241,6 +240,17 @@ export function* failOnMissingDateFilterItems(insight) {
|
|
|
241
240
|
throw new MissingInsightItemsError(missingItems);
|
|
242
241
|
}
|
|
243
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Whether one of the insight's relative date filters has a granularity AD cannot load. All time is
|
|
245
|
+
* supported: it is stored as the real All time filter (ALL_TIME_GRANULARITY) when it carries the empty
|
|
246
|
+
* date values mode.
|
|
247
|
+
*/
|
|
248
|
+
export function hasDateFilterWithUnsupportedGranularity(insight) {
|
|
249
|
+
return insight.insight.filters
|
|
250
|
+
.filter(isRelativeDateFilter)
|
|
251
|
+
.some((filter) => !isAllTimeDateFilter(filter) &&
|
|
252
|
+
!isDateFilterGranularity(filter.relativeDateFilter.granularity));
|
|
253
|
+
}
|
|
244
254
|
const missingItemsOf = (error) => isMissingInsightItemsError(error) ? error.missingItems : undefined;
|
|
245
255
|
export function* fetchReport(projectId, reportId) {
|
|
246
256
|
try {
|
|
@@ -261,13 +271,7 @@ export function* fetchReport(projectId, reportId) {
|
|
|
261
271
|
const catalogSideloadEnabled = yield select(enableAnalyticalDesignerCatalogSideload);
|
|
262
272
|
const sideloadInsightItems = catalogSideloadEnabled && !!(includeObjectsWithTags.length || excludeObjectsWithTags.length);
|
|
263
273
|
const { insight, catalogItems } = yield call(getInsight, projectId, reportId, sideloadInsightItems);
|
|
264
|
-
|
|
265
|
-
.filter(isRelativeDateFilter)
|
|
266
|
-
.some((filter) => {
|
|
267
|
-
const granularity = filter.relativeDateFilter.granularity;
|
|
268
|
-
return !isDateFilterGranularity(granularity);
|
|
269
|
-
});
|
|
270
|
-
if (hasFilterWithInvalidGranularity) {
|
|
274
|
+
if (hasDateFilterWithUnsupportedGranularity(insight)) {
|
|
271
275
|
const reset = yield call(selectOpenReportFailureReset);
|
|
272
276
|
yield put(openReportFailed(reset, false, "incorrectMetadata"));
|
|
273
277
|
// uses delay, must be called after previous call to not block it
|
package/esm/sagas/sagas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/sagas.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"sagas.d.ts","sourceRoot":"","sources":["../../src/sagas/sagas.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,mCAAmC,CAAC;AAwDxF,wBAAiB,IAAI;;;;;;mBAgFpB"}
|
package/esm/sagas/sagas.js
CHANGED
|
@@ -38,7 +38,6 @@ import { watchDrillableItems } from "./drillable_items_sagas.js";
|
|
|
38
38
|
import { watchEmbedDialogSaga } from "./embed_dialog_sagas.js";
|
|
39
39
|
import { watchExecuteReport } from "./execute_report_sagas.js";
|
|
40
40
|
import { watchExportReport } from "./export_report_sagas.js";
|
|
41
|
-
import { watchLoadExternalScripts } from "./external_scripts_saga.js";
|
|
42
41
|
import { watchFeatureFlags } from "./featureFlags_sagas.js";
|
|
43
42
|
import { watchFilterBar } from "./filter_bar/filter_bar_saga.js";
|
|
44
43
|
import { highlightingWatcher } from "./highlighting/highlighting_saga.js";
|
|
@@ -99,7 +98,6 @@ export function* root() {
|
|
|
99
98
|
watchDrillableItems(),
|
|
100
99
|
watchIncomingCommands(),
|
|
101
100
|
watchDispatchPostponedAction(),
|
|
102
|
-
watchLoadExternalScripts(),
|
|
103
101
|
watchCatalog(),
|
|
104
102
|
watchFilterBar(),
|
|
105
103
|
watchFeatureFlags(),
|