@gooddata/sdk-ui-dashboard 11.58.0-alpha.2 → 11.58.0-alpha.3
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 +8 -8
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +3 -3
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/model/DashboardTester.d.ts.map +1 -1
- package/esm/model/DashboardTester.js +7 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +13 -6
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts +45 -0
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.js +99 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts +11 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.js +71 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts +22 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.js +39 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts +21 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.js +86 -0
- package/esm/model/react/useInitializeDashboardStore.d.ts.map +1 -1
- package/esm/model/react/useInitializeDashboardStore.js +4 -0
- package/esm/model/react/useWidgetExecConfig.d.ts +4 -4
- package/esm/model/react/useWidgetExecConfig.d.ts.map +1 -1
- package/esm/model/react/useWidgetExecConfig.js +2 -2
- package/esm/model/store/catalog/catalogReducers.d.ts +16 -4
- package/esm/model/store/catalog/catalogReducers.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogReducers.js +15 -3
- package/esm/model/store/catalog/catalogSelectors.d.ts +21 -6
- package/esm/model/store/catalog/catalogSelectors.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogSelectors.js +20 -5
- package/esm/model/store/catalog/catalogState.d.ts +30 -9
- package/esm/model/store/catalog/catalogState.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogState.js +2 -1
- package/esm/model/store/catalog/index.d.ts +4 -1
- package/esm/model/store/catalog/index.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersHelpers.d.ts +42 -8
- package/esm/model/store/tabs/parameters/parametersHelpers.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersHelpers.js +88 -19
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +13 -6
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersSelectors.js +24 -13
- package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.js +16 -2
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +2 -2
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -0
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +5 -2
- package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts +4 -8
- package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts.map +1 -1
- package/esm/presentation/widget/common/RestrictedPlaceholder.js +16 -23
- package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.d.ts.map +1 -1
- package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.js +2 -4
- package/esm/presentation/widget/insight/LayeredTableView.d.ts +1 -1
- package/esm/presentation/widget/insight/LayeredTableView.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.js +2 -3
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +1 -1
- package/esm/presentation/widget/insight/types.d.ts +1 -1
- package/esm/presentation/widget/insight/types.d.ts.map +1 -1
- package/esm/presentation/widget/richText/RestrictedReferencesDialog.d.ts.map +1 -1
- package/esm/presentation/widget/richText/RestrictedReferencesDialog.js +5 -6
- package/esm/presentation/widget/visualizationSwitcher/ViewModeDashboardVisualizationSwitcher.js +1 -1
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.d.ts.map +1 -1
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.js +1 -4
- package/esm/presentation/widget/widget/InsightWidget/DefaultDashboardInsightWidget.js +2 -3
- package/esm/sdk-ui-dashboard.d.ts +68 -42
- package/package.json +21 -21
- package/styles/css/main.css +8 -7
- package/styles/css/main.css.map +1 -1
- package/styles/css/richTextWidget.css +4 -0
- package/styles/css/richTextWidget.css.map +1 -1
- package/styles/scss/richTextWidget.scss +5 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts +0 -13
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts.map +0 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.js +0 -98
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts +0 -5
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts.map +0 -1
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.js +0 -28
- package/esm/presentation/widget/insight/insightToTable.d.ts +0 -74
- package/esm/presentation/widget/insight/insightToTable.d.ts.map +0 -1
- package/esm/presentation/widget/insight/insightToTable.js +0 -482
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
// (C) 2025-2026 GoodData Corporation
|
|
2
|
-
import { GeoLayerTypes, areObjRefsEqual, attributeAlias, attributeDisplayFormRef, attributeLocalId, bucketAttribute, bucketMeasure, bucketsFind, geoLayerTypeFromVisualizationType, idRef, insightBuckets, insightLayers, insightMeasures, insightProperties, insightSorts, insightVisualizationType, isGeoLayerType, isPoPMeasure, isPreviousPeriodMeasure, isUriRef, newAttribute, newVirtualArithmeticMeasure, serializeObjRef, uriRef, } from "@gooddata/sdk-model";
|
|
3
|
-
import { BucketNames, VisualizationTypes, convertGeoInsightToTableDefinition as convertGeoInsightToTableDefinitionShared, isGeoVisualizationUsingNewEngine, } from "@gooddata/sdk-ui";
|
|
4
|
-
import { resolveGeoDefaultDisplayFormRefs } from "./geoDefaultDisplayFormRefs.js";
|
|
5
|
-
/**
|
|
6
|
-
* Determines if a visualization type supports the "Show as Table" UI button.
|
|
7
|
-
* This controls whether users can manually toggle table view in the UI.
|
|
8
|
-
*
|
|
9
|
-
* @param insightType - The visualization type to check
|
|
10
|
-
* @returns true if the visualization supports the Show as Table UI feature
|
|
11
|
-
* @public
|
|
12
|
-
*/
|
|
13
|
-
export function supportsShowAsTable(insightType) {
|
|
14
|
-
return (insightType !== "table" &&
|
|
15
|
-
insightType !== "repeater" &&
|
|
16
|
-
insightType !== "headline" &&
|
|
17
|
-
insightType !== "xirr");
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Determines if a visualization type can be converted to table format.
|
|
21
|
-
* This is used for accessibility and export purposes, separate from UI controls.
|
|
22
|
-
*
|
|
23
|
-
* @param insightType - The visualization type to check
|
|
24
|
-
* @returns true if the visualization can be converted to table format
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
export function canConvertToTable(insightType) {
|
|
28
|
-
return insightType !== "table" && insightType !== "repeater" && insightType !== "xirr";
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Default format strings for comparison calculations
|
|
32
|
-
* These match the defaults from sdk-ui-charts/headlineHelper.ts CALCULATION_VALUES_DEFAULT
|
|
33
|
-
*
|
|
34
|
-
* @remarks
|
|
35
|
-
* - CHANGE: Percentage change between primary and secondary
|
|
36
|
-
* - RATIO: Ratio of primary to secondary as percentage
|
|
37
|
-
* - DIFFERENCE: Absolute difference (null means inherit from primary measure)
|
|
38
|
-
* - CHANGE_DIFFERENCE: Both percentage and absolute (sub-value uses null to inherit)
|
|
39
|
-
*/
|
|
40
|
-
const COMPARISON_FORMATS = {
|
|
41
|
-
change: "#,##0%",
|
|
42
|
-
ratio: "#,##0%",
|
|
43
|
-
difference: null, // null means inherit format from primary measure
|
|
44
|
-
change_difference: {
|
|
45
|
-
main: "#,##0%",
|
|
46
|
-
sub: null, // Absolute difference (inherit)
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Extracts comparison configuration from insight properties
|
|
51
|
-
*/
|
|
52
|
-
function getComparisonConfig(insight) {
|
|
53
|
-
const properties = insightProperties(insight);
|
|
54
|
-
return properties["controls"]?.comparison;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Checks if a headline insight has comparison enabled and exactly one secondary measure
|
|
58
|
-
* Matches the logic from HeadlineProviderFactory.isComparisonType in sdk-ui-charts
|
|
59
|
-
*
|
|
60
|
-
* @param insight - The insight to check
|
|
61
|
-
* @returns true if the insight is a headline with comparison enabled
|
|
62
|
-
*
|
|
63
|
-
* @remarks
|
|
64
|
-
* A headline qualifies for comparison if:
|
|
65
|
-
* 1. It's a "headline" visualization type
|
|
66
|
-
* 2. It has both a primary and secondary measure
|
|
67
|
-
* 3. Comparison is enabled in config (defaults to true)
|
|
68
|
-
*
|
|
69
|
-
*/
|
|
70
|
-
function isHeadlineWithComparison(insight) {
|
|
71
|
-
const type = insightVisualizationType(insight);
|
|
72
|
-
if (type !== "headline") {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
const buckets = insightBuckets(insight);
|
|
76
|
-
const primaryBucket = bucketsFind(buckets, BucketNames.MEASURES);
|
|
77
|
-
const secondaryBucket = bucketsFind(buckets, BucketNames.SECONDARY_MEASURES);
|
|
78
|
-
const primaryMeasure = primaryBucket && bucketMeasure(primaryBucket);
|
|
79
|
-
const secondaryMeasure = secondaryBucket && bucketMeasure(secondaryBucket);
|
|
80
|
-
if (!primaryMeasure || !secondaryMeasure) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
const comparison = getComparisonConfig(insight);
|
|
84
|
-
return comparison?.enabled ?? true;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Determines the calculation type for headline comparison
|
|
88
|
-
* Matches the logic from ComparisonProvider in sdk-ui-charts
|
|
89
|
-
*
|
|
90
|
-
* @param secondaryMeasure - The secondary measure to compare against
|
|
91
|
-
* @param comparison - Optional comparison configuration from insight properties
|
|
92
|
-
* @returns The calculation type to use
|
|
93
|
-
*
|
|
94
|
-
* @remarks
|
|
95
|
-
* Default logic (when no calculationType is configured):
|
|
96
|
-
* - If secondary measure is derived (PoP, Previous Period) → use "change" (percentage change)
|
|
97
|
-
* - If secondary measure is regular → use "ratio" (proportion)
|
|
98
|
-
*
|
|
99
|
-
*/
|
|
100
|
-
function getCalculationType(secondaryMeasure, comparison) {
|
|
101
|
-
if (comparison?.calculationType) {
|
|
102
|
-
return comparison.calculationType;
|
|
103
|
-
}
|
|
104
|
-
if (isPoPMeasure(secondaryMeasure) || isPreviousPeriodMeasure(secondaryMeasure)) {
|
|
105
|
-
return "change";
|
|
106
|
-
}
|
|
107
|
-
return "ratio";
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Creates virtual arithmetic measures for headline comparison
|
|
111
|
-
* Replicates the logic from ComparisonProvider in sdk-ui-charts
|
|
112
|
-
*
|
|
113
|
-
* @param primaryMeasure - The primary measure
|
|
114
|
-
* @param secondaryMeasure - The secondary measure to compare against
|
|
115
|
-
* @param calculationType - The type of calculation to perform
|
|
116
|
-
* @returns Array of virtual arithmetic measures (1 or 2 depending on calculation type)
|
|
117
|
-
*
|
|
118
|
-
* @remarks
|
|
119
|
-
* Virtual arithmetic measures are calculated by the backend:
|
|
120
|
-
* - "change": ((primary - secondary) / secondary) * 100
|
|
121
|
-
* - "ratio": (primary / secondary)
|
|
122
|
-
* - "difference": (primary - secondary)
|
|
123
|
-
* - "change_difference": Both change AND difference as separate measures
|
|
124
|
-
*
|
|
125
|
-
* The backend performs all calculations; we just create the measure definitions.
|
|
126
|
-
* Format strings are applied so values display correctly (e.g., "25%" instead of "0.25").
|
|
127
|
-
*
|
|
128
|
-
* @see {@link sdk-backend-tiger/MeasureConverter.ts#convertArithmeticMeasureDefinition}
|
|
129
|
-
*/
|
|
130
|
-
function createHeadlineComparisonMeasures(primaryMeasure, secondaryMeasure, calculationType) {
|
|
131
|
-
const createVirtualArithmeticMeasure = (operator, format, shouldCombineLocalIdAndOperator) => {
|
|
132
|
-
return newVirtualArithmeticMeasure([primaryMeasure, secondaryMeasure], operator, (builder) => {
|
|
133
|
-
if (shouldCombineLocalIdAndOperator) {
|
|
134
|
-
builder.combineLocalIdWithOperator();
|
|
135
|
-
}
|
|
136
|
-
// Apply format: null means inherit from primary measure, string means use explicit format
|
|
137
|
-
if (format !== null) {
|
|
138
|
-
builder.format(format);
|
|
139
|
-
}
|
|
140
|
-
return builder;
|
|
141
|
-
});
|
|
142
|
-
};
|
|
143
|
-
switch (calculationType) {
|
|
144
|
-
case "difference":
|
|
145
|
-
return [createVirtualArithmeticMeasure("difference", COMPARISON_FORMATS.difference)];
|
|
146
|
-
case "ratio":
|
|
147
|
-
return [createVirtualArithmeticMeasure("ratio", COMPARISON_FORMATS.ratio)];
|
|
148
|
-
case "change":
|
|
149
|
-
return [createVirtualArithmeticMeasure("change", COMPARISON_FORMATS.change)];
|
|
150
|
-
case "change_difference":
|
|
151
|
-
return [
|
|
152
|
-
createVirtualArithmeticMeasure("change", COMPARISON_FORMATS.change_difference.main, true),
|
|
153
|
-
createVirtualArithmeticMeasure("difference", COMPARISON_FORMATS.change_difference.sub, true),
|
|
154
|
-
];
|
|
155
|
-
default:
|
|
156
|
-
return [];
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Transforms a geo bucket attribute to use tooltipText display form (legacy pushpin only).
|
|
161
|
-
*
|
|
162
|
-
* @remarks
|
|
163
|
-
* This is used only when legacy pushpin behavior is active (new geo flags disabled).
|
|
164
|
-
*/
|
|
165
|
-
function transformGeoBucketAttributeUsingTooltipText(bucket, insight, uniqueLocalIdSuffix) {
|
|
166
|
-
if (!bucket) {
|
|
167
|
-
return undefined;
|
|
168
|
-
}
|
|
169
|
-
const geoAttr = bucketAttribute(bucket);
|
|
170
|
-
if (!geoAttr) {
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
const properties = insightProperties(insight);
|
|
174
|
-
const tooltipTextId = properties?.["controls"]?.["tooltipText"];
|
|
175
|
-
if (!tooltipTextId) {
|
|
176
|
-
return geoAttr;
|
|
177
|
-
}
|
|
178
|
-
const ref = isUriRef(attributeDisplayFormRef(geoAttr))
|
|
179
|
-
? uriRef(tooltipTextId)
|
|
180
|
-
: idRef(tooltipTextId, "displayForm");
|
|
181
|
-
// Generate a unique localId to avoid conflicts with existing attributes
|
|
182
|
-
const uniqueLocalId = `${attributeLocalId(geoAttr)}_${uniqueLocalIdSuffix}`;
|
|
183
|
-
const alias = attributeAlias(geoAttr);
|
|
184
|
-
return newAttribute(ref, (m) => {
|
|
185
|
-
m.localId(uniqueLocalId);
|
|
186
|
-
if (alias) {
|
|
187
|
-
m.alias(alias);
|
|
188
|
-
}
|
|
189
|
-
return m;
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Transforms a geo bucket attribute to use the default display form.
|
|
194
|
-
*
|
|
195
|
-
* @remarks
|
|
196
|
-
* Used for new GeoChartNext variants when feature flags are enabled.
|
|
197
|
-
*/
|
|
198
|
-
function transformGeoBucketAttributeUsingDefaultDisplayForm(bucket, defaultDisplayFormRefs, uniqueLocalIdSuffix) {
|
|
199
|
-
if (!bucket) {
|
|
200
|
-
return undefined;
|
|
201
|
-
}
|
|
202
|
-
const geoAttr = bucketAttribute(bucket);
|
|
203
|
-
if (!geoAttr) {
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
const geoDisplayFormRef = attributeDisplayFormRef(geoAttr);
|
|
207
|
-
const defaultDisplayFormRef = defaultDisplayFormRefs?.get(serializeObjRef(geoDisplayFormRef));
|
|
208
|
-
if (!defaultDisplayFormRef || areObjRefsEqual(defaultDisplayFormRef, geoDisplayFormRef)) {
|
|
209
|
-
return geoAttr;
|
|
210
|
-
}
|
|
211
|
-
const uniqueLocalId = `${attributeLocalId(geoAttr)}_${uniqueLocalIdSuffix}`;
|
|
212
|
-
const alias = attributeAlias(geoAttr);
|
|
213
|
-
return newAttribute(defaultDisplayFormRef, (m) => {
|
|
214
|
-
m.localId(uniqueLocalId);
|
|
215
|
-
if (alias) {
|
|
216
|
-
m.alias(alias);
|
|
217
|
-
}
|
|
218
|
-
return m;
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
function transformGeoLocationAttribute(locationBucket, insight) {
|
|
222
|
-
return transformGeoBucketAttributeUsingTooltipText(locationBucket, insight, "table_name");
|
|
223
|
-
}
|
|
224
|
-
function resolveGeoPrimaryAttribute(options, insight, buckets, layerType) {
|
|
225
|
-
if (layerType) {
|
|
226
|
-
return resolveGeoPrimaryAttributeByLayerType(layerType, buckets, options.defaultDisplayFormRefs);
|
|
227
|
-
}
|
|
228
|
-
const type = insightVisualizationType(insight);
|
|
229
|
-
const isLegacyGeoPushpin = type === VisualizationTypes.PUSHPIN && !options.settings?.enableNewGeoPushpin;
|
|
230
|
-
const isNewGeoVisualization = isGeoVisualizationUsingNewEngine(type, options.settings);
|
|
231
|
-
if (isLegacyGeoPushpin) {
|
|
232
|
-
return transformGeoLocationAttribute(bucketsFind(buckets, BucketNames.LOCATION), insight);
|
|
233
|
-
}
|
|
234
|
-
if (isNewGeoVisualization) {
|
|
235
|
-
const rootLayerType = geoLayerTypeFromVisualizationType(type);
|
|
236
|
-
if (rootLayerType) {
|
|
237
|
-
return resolveGeoPrimaryAttributeByLayerType(rootLayerType, buckets, options.defaultDisplayFormRefs);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return undefined;
|
|
241
|
-
}
|
|
242
|
-
function getGeoTableAttributesWithSegmentAndPrimary(buckets, primaryAttribute) {
|
|
243
|
-
const segmentBucket = bucketsFind(buckets, BucketNames.SEGMENT);
|
|
244
|
-
const rowAttributes = [];
|
|
245
|
-
const segmentAttr = segmentBucket ? bucketAttribute(segmentBucket) : undefined;
|
|
246
|
-
if (segmentAttr) {
|
|
247
|
-
rowAttributes.push(segmentAttr);
|
|
248
|
-
}
|
|
249
|
-
if (primaryAttribute) {
|
|
250
|
-
rowAttributes.push(primaryAttribute);
|
|
251
|
-
}
|
|
252
|
-
return { rowAttributes, columnAttributes: [] };
|
|
253
|
-
}
|
|
254
|
-
function getGeoTableAttributes(insight, buckets, options, layerType) {
|
|
255
|
-
const type = insightVisualizationType(insight);
|
|
256
|
-
const isLegacyGeoPushpin = type === VisualizationTypes.PUSHPIN && !options.settings?.enableNewGeoPushpin;
|
|
257
|
-
const isNewGeoVisualization = isGeoVisualizationUsingNewEngine(type, options.settings);
|
|
258
|
-
if (!layerType && !isLegacyGeoPushpin && !isNewGeoVisualization) {
|
|
259
|
-
return null;
|
|
260
|
-
}
|
|
261
|
-
const primaryAttribute = resolveGeoPrimaryAttribute(options, insight, buckets, layerType);
|
|
262
|
-
return getGeoTableAttributesWithSegmentAndPrimary(buckets, primaryAttribute);
|
|
263
|
-
}
|
|
264
|
-
function resolveGeoPrimaryAttributeByLayerType(layerType, buckets, defaultDisplayFormRefs) {
|
|
265
|
-
const bucketName = layerType === GeoLayerTypes.AREA ? BucketNames.AREA : BucketNames.LOCATION;
|
|
266
|
-
return transformGeoBucketAttributeUsingDefaultDisplayForm(bucketsFind(buckets, bucketName), defaultDisplayFormRefs, "table_default_label");
|
|
267
|
-
}
|
|
268
|
-
function buildTableInsightFromBuckets(insight, buckets, layerType, defaultDisplayFormRefs) {
|
|
269
|
-
const measureBucketIdentifiers = new Set([
|
|
270
|
-
BucketNames.MEASURES,
|
|
271
|
-
BucketNames.SIZE,
|
|
272
|
-
BucketNames.COLOR,
|
|
273
|
-
BucketNames.SECONDARY_MEASURES,
|
|
274
|
-
]);
|
|
275
|
-
const measures = buckets
|
|
276
|
-
.filter((b) => measureBucketIdentifiers.has(b.localIdentifier ?? ""))
|
|
277
|
-
.flatMap((b) => b.items);
|
|
278
|
-
const { rowAttributes, columnAttributes } = getGeoTableAttributes(insight, buckets, { defaultDisplayFormRefs }, layerType) ?? { rowAttributes: [], columnAttributes: [] };
|
|
279
|
-
const tableBuckets = [
|
|
280
|
-
{ localIdentifier: BucketNames.MEASURES, items: measures },
|
|
281
|
-
{ localIdentifier: BucketNames.ATTRIBUTE, items: rowAttributes },
|
|
282
|
-
{ localIdentifier: BucketNames.COLUMNS, items: columnAttributes },
|
|
283
|
-
];
|
|
284
|
-
const onlyMeasures = !rowAttributes.length && !columnAttributes.length;
|
|
285
|
-
const propertiesProp = onlyMeasures
|
|
286
|
-
? { properties: { controls: { measureGroupDimension: "rows" } } }
|
|
287
|
-
: {};
|
|
288
|
-
const tableInsight = {
|
|
289
|
-
...insight,
|
|
290
|
-
insight: {
|
|
291
|
-
...insight.insight,
|
|
292
|
-
visualizationUrl: "local:table",
|
|
293
|
-
buckets: tableBuckets,
|
|
294
|
-
...propertiesProp,
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
return {
|
|
298
|
-
...tableInsight,
|
|
299
|
-
insight: {
|
|
300
|
-
...tableInsight.insight,
|
|
301
|
-
// Keep only sorts that reference attributes/measures present in this layer table.
|
|
302
|
-
sorts: insightSorts(tableInsight),
|
|
303
|
-
},
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Converts a multi-layer geo insight into per-layer table definitions.
|
|
308
|
-
*
|
|
309
|
-
* Returns `undefined` when the insight is not a new-geo type (flags off, non-geo, etc.).
|
|
310
|
-
* Returns an array of {@link ILayerTableDefinition} with root layer first, then
|
|
311
|
-
* additional layers in their original order.
|
|
312
|
-
*
|
|
313
|
-
* @internal
|
|
314
|
-
*/
|
|
315
|
-
export function convertGeoInsightToLayerTables(insight, options) {
|
|
316
|
-
if (!options.settings?.["enableGeoChartA11yImprovements"]) {
|
|
317
|
-
return undefined;
|
|
318
|
-
}
|
|
319
|
-
const type = insightVisualizationType(insight);
|
|
320
|
-
if (!isGeoVisualizationUsingNewEngine(type, options.settings)) {
|
|
321
|
-
return undefined;
|
|
322
|
-
}
|
|
323
|
-
const rootLayerType = geoLayerTypeFromVisualizationType(type);
|
|
324
|
-
if (!rootLayerType) {
|
|
325
|
-
return undefined;
|
|
326
|
-
}
|
|
327
|
-
const rootBuckets = insightBuckets(insight);
|
|
328
|
-
const rootDisplayFormRefs = resolveGeoDefaultDisplayFormRefs(rootLayerType, rootBuckets, options.catalogAttributes ?? [], options.preloadedAttributesWithReferences);
|
|
329
|
-
const rootTable = buildTableInsightFromBuckets(insight, rootBuckets, rootLayerType, rootDisplayFormRefs);
|
|
330
|
-
const rootDef = {
|
|
331
|
-
layerId: "root",
|
|
332
|
-
layerName: insight.insight.title,
|
|
333
|
-
layerType: rootLayerType,
|
|
334
|
-
tableInsight: rootTable,
|
|
335
|
-
};
|
|
336
|
-
const layers = insightLayers(insight);
|
|
337
|
-
const layerDefs = layers.flatMap((layer) => {
|
|
338
|
-
if (!isGeoLayerType(layer.type)) {
|
|
339
|
-
return [];
|
|
340
|
-
}
|
|
341
|
-
const layerType = layer.type;
|
|
342
|
-
const displayFormRefs = resolveGeoDefaultDisplayFormRefs(layerType, layer.buckets, options.catalogAttributes ?? [], options.preloadedAttributesWithReferences);
|
|
343
|
-
const tableInsight = buildTableInsightFromBuckets(insight, layer.buckets, layerType, displayFormRefs);
|
|
344
|
-
return [
|
|
345
|
-
{
|
|
346
|
-
layerId: layer.id,
|
|
347
|
-
layerName: layer.name ?? layer.id,
|
|
348
|
-
layerType,
|
|
349
|
-
tableInsight,
|
|
350
|
-
},
|
|
351
|
-
];
|
|
352
|
-
});
|
|
353
|
-
return [rootDef, ...layerDefs];
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Converts an insight to layered table definitions.
|
|
357
|
-
*
|
|
358
|
-
* @remarks
|
|
359
|
-
* Currently supports geo insights only and is gated by `enableGeoChartA11yImprovements`.
|
|
360
|
-
*
|
|
361
|
-
* @internal
|
|
362
|
-
*/
|
|
363
|
-
export function convertInsightToLayerTables(insight, options) {
|
|
364
|
-
return convertGeoInsightToLayerTables(insight, options);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Converts any insight (except of type "table", "repeater", or "xirr") to a table insight definition.
|
|
368
|
-
* For table, repeater, or xirr insights, returns the original insight.
|
|
369
|
-
*
|
|
370
|
-
* @param insight - The input insight to convert.
|
|
371
|
-
* @returns IInsight with table visualization or the original insight if conversion is not supported.
|
|
372
|
-
* @public
|
|
373
|
-
*/
|
|
374
|
-
export function convertInsightToTableDefinition(insight, options = {}) {
|
|
375
|
-
const type = insightVisualizationType(insight);
|
|
376
|
-
if (!canConvertToTable(type)) {
|
|
377
|
-
return insight;
|
|
378
|
-
}
|
|
379
|
-
const geoTableInsight = convertGeoInsightToTableDefinitionShared(insight, options);
|
|
380
|
-
if (geoTableInsight) {
|
|
381
|
-
return geoTableInsight;
|
|
382
|
-
}
|
|
383
|
-
// Use sdk-model utils to extract all measures and attributes
|
|
384
|
-
// and build table buckets according to PluggablePivotTable conventions
|
|
385
|
-
// - 'measures' bucket: all measures
|
|
386
|
-
// - 'attributes' bucket: all attributes
|
|
387
|
-
// - 'columns' bucket: empty (can be customized if needed)
|
|
388
|
-
// This is a safe default for generic conversion
|
|
389
|
-
// If more advanced splitting is needed (e.g. from view/stack by), logic can be extended
|
|
390
|
-
//
|
|
391
|
-
// Note: IBucket type is imported from sdk-model
|
|
392
|
-
//
|
|
393
|
-
// The output insight will have only these three buckets
|
|
394
|
-
// Import bucket utilities for splitting attributes
|
|
395
|
-
// PluggablePivotTable convention: row attributes come from the first attribute bucket (view by, trend by, etc),
|
|
396
|
-
// column attributes come from the second attribute bucket (columns, stack by, etc)
|
|
397
|
-
// Measures always from 'measures' bucket
|
|
398
|
-
// See getRowAttributes and getColumnAttributes in PluggablePivotTable
|
|
399
|
-
const buckets = insightBuckets(insight);
|
|
400
|
-
const baseMeasures = insightMeasures(insight);
|
|
401
|
-
// Handle headline comparison: add virtual arithmetic measures for change/difference/ratio
|
|
402
|
-
const comparisonMeasures = [];
|
|
403
|
-
if (isHeadlineWithComparison(insight)) {
|
|
404
|
-
const primaryBucket = bucketsFind(buckets, BucketNames.MEASURES);
|
|
405
|
-
const secondaryBucket = bucketsFind(buckets, BucketNames.SECONDARY_MEASURES);
|
|
406
|
-
const primaryMeasure = primaryBucket && bucketMeasure(primaryBucket);
|
|
407
|
-
const secondaryMeasure = secondaryBucket && bucketMeasure(secondaryBucket);
|
|
408
|
-
if (primaryMeasure && secondaryMeasure) {
|
|
409
|
-
const comparison = getComparisonConfig(insight);
|
|
410
|
-
const calculationType = getCalculationType(secondaryMeasure, comparison);
|
|
411
|
-
comparisonMeasures.push(...createHeadlineComparisonMeasures(primaryMeasure, secondaryMeasure, calculationType));
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
const measures = [...baseMeasures, ...comparisonMeasures];
|
|
415
|
-
/**
|
|
416
|
-
* Keep conversion logic aligned with `PluggablePivotTable`:
|
|
417
|
-
* - row attributes: see `getRowAttributes` in `sdk-ui-ext`
|
|
418
|
-
* - column attributes: see `getColumnAttributes` in `sdk-ui-ext`
|
|
419
|
-
*
|
|
420
|
-
* Note: using `BucketNames.*` avoids fragile magic strings.
|
|
421
|
-
*/
|
|
422
|
-
const rowBucketIdentifiers = [
|
|
423
|
-
BucketNames.ATTRIBUTE,
|
|
424
|
-
BucketNames.ATTRIBUTES,
|
|
425
|
-
BucketNames.ATTRIBUTE_FROM,
|
|
426
|
-
BucketNames.ATTRIBUTE_TO,
|
|
427
|
-
BucketNames.VIEW,
|
|
428
|
-
BucketNames.TREND,
|
|
429
|
-
BucketNames.LOCATION,
|
|
430
|
-
BucketNames.AREA,
|
|
431
|
-
];
|
|
432
|
-
const columnBucketIdentifiers = [BucketNames.COLUMNS, BucketNames.STACK, BucketNames.SEGMENT];
|
|
433
|
-
const isRowBucket = (bucket) => rowBucketIdentifiers.includes(bucket.localIdentifier ?? "");
|
|
434
|
-
const isColumnBucket = (bucket) => columnBucketIdentifiers.includes(bucket.localIdentifier ?? "");
|
|
435
|
-
let rowAttributes;
|
|
436
|
-
let columnAttributes;
|
|
437
|
-
const geoAttributes = getGeoTableAttributes(insight, buckets, options);
|
|
438
|
-
if (geoAttributes) {
|
|
439
|
-
rowAttributes = geoAttributes.rowAttributes;
|
|
440
|
-
columnAttributes = geoAttributes.columnAttributes;
|
|
441
|
-
}
|
|
442
|
-
else {
|
|
443
|
-
const rowBuckets = buckets.filter(isRowBucket);
|
|
444
|
-
const columnBuckets = buckets.filter(isColumnBucket);
|
|
445
|
-
rowAttributes = rowBuckets.map((bucket) => bucket.items).flat();
|
|
446
|
-
columnAttributes = columnBuckets.map((bucket) => bucket.items).flat();
|
|
447
|
-
}
|
|
448
|
-
const tableBuckets = [
|
|
449
|
-
{
|
|
450
|
-
localIdentifier: BucketNames.MEASURES,
|
|
451
|
-
items: measures,
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
localIdentifier: BucketNames.ATTRIBUTE,
|
|
455
|
-
items: rowAttributes,
|
|
456
|
-
},
|
|
457
|
-
{
|
|
458
|
-
localIdentifier: BucketNames.COLUMNS,
|
|
459
|
-
items: columnAttributes,
|
|
460
|
-
},
|
|
461
|
-
];
|
|
462
|
-
const onlyMeasures = !rowAttributes.length && !columnAttributes.length;
|
|
463
|
-
const propertiesProp = onlyMeasures
|
|
464
|
-
? {
|
|
465
|
-
properties: {
|
|
466
|
-
controls: {
|
|
467
|
-
measureGroupDimension: "rows",
|
|
468
|
-
},
|
|
469
|
-
},
|
|
470
|
-
}
|
|
471
|
-
: {};
|
|
472
|
-
const tableInsight = {
|
|
473
|
-
...insight,
|
|
474
|
-
insight: {
|
|
475
|
-
...insight.insight,
|
|
476
|
-
visualizationUrl: "local:table",
|
|
477
|
-
buckets: tableBuckets,
|
|
478
|
-
...propertiesProp,
|
|
479
|
-
},
|
|
480
|
-
};
|
|
481
|
-
return tableInsight;
|
|
482
|
-
}
|