@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.
Files changed (157) hide show
  1. package/NOTICE +8 -8
  2. package/esm/__version.d.ts +1 -1
  3. package/esm/__version.js +1 -1
  4. package/esm/index.d.ts +3 -3
  5. package/esm/index.d.ts.map +1 -1
  6. package/esm/index.js +1 -1
  7. package/esm/model/DashboardTester.d.ts.map +1 -1
  8. package/esm/model/DashboardTester.js +7 -1
  9. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
  10. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +13 -6
  11. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts +45 -0
  12. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts.map +1 -0
  13. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.js +99 -0
  14. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts +11 -0
  15. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts.map +1 -0
  16. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.js +71 -0
  17. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts +22 -0
  18. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts.map +1 -0
  19. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.js +39 -0
  20. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts +21 -0
  21. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts.map +1 -0
  22. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.js +86 -0
  23. package/esm/model/react/useInitializeDashboardStore.d.ts.map +1 -1
  24. package/esm/model/react/useInitializeDashboardStore.js +4 -0
  25. package/esm/model/react/useWidgetExecConfig.d.ts +4 -4
  26. package/esm/model/react/useWidgetExecConfig.d.ts.map +1 -1
  27. package/esm/model/react/useWidgetExecConfig.js +2 -2
  28. package/esm/model/store/catalog/catalogReducers.d.ts +16 -4
  29. package/esm/model/store/catalog/catalogReducers.d.ts.map +1 -1
  30. package/esm/model/store/catalog/catalogReducers.js +15 -3
  31. package/esm/model/store/catalog/catalogSelectors.d.ts +21 -6
  32. package/esm/model/store/catalog/catalogSelectors.d.ts.map +1 -1
  33. package/esm/model/store/catalog/catalogSelectors.js +20 -5
  34. package/esm/model/store/catalog/catalogState.d.ts +30 -9
  35. package/esm/model/store/catalog/catalogState.d.ts.map +1 -1
  36. package/esm/model/store/catalog/catalogState.js +2 -1
  37. package/esm/model/store/catalog/index.d.ts +4 -1
  38. package/esm/model/store/catalog/index.d.ts.map +1 -1
  39. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts +42 -8
  40. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts.map +1 -1
  41. package/esm/model/store/tabs/parameters/parametersHelpers.js +88 -19
  42. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +13 -6
  43. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts.map +1 -1
  44. package/esm/model/store/tabs/parameters/parametersSelectors.js +24 -13
  45. package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.d.ts.map +1 -1
  46. package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.js +16 -2
  47. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -0
  48. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
  49. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +5 -2
  50. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -0
  51. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
  52. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +5 -2
  53. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -0
  54. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
  55. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +5 -2
  56. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +2 -2
  57. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -0
  58. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
  59. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +5 -2
  60. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -0
  61. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
  62. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +5 -2
  63. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -0
  64. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
  65. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +5 -2
  66. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -0
  67. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
  68. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +5 -2
  69. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -0
  70. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
  71. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +5 -2
  72. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -0
  73. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
  74. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +5 -2
  75. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -0
  76. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
  77. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +5 -2
  78. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -0
  79. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
  80. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +5 -2
  81. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -0
  82. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
  83. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +5 -2
  84. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -0
  85. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
  86. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +5 -2
  87. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -0
  88. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
  89. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +5 -2
  90. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -0
  91. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
  92. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +5 -2
  93. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -0
  94. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
  95. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +5 -2
  96. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -0
  97. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
  98. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +5 -2
  99. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -0
  100. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
  101. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +5 -2
  102. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -0
  103. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
  104. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +5 -2
  105. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -0
  106. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
  107. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +5 -2
  108. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -0
  109. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
  110. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +5 -2
  111. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -0
  112. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
  113. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +5 -2
  114. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -0
  115. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
  116. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +5 -2
  117. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -0
  118. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
  119. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +5 -2
  120. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -0
  121. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
  122. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +5 -2
  123. package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts +4 -8
  124. package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts.map +1 -1
  125. package/esm/presentation/widget/common/RestrictedPlaceholder.js +16 -23
  126. package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.d.ts.map +1 -1
  127. package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.js +2 -4
  128. package/esm/presentation/widget/insight/LayeredTableView.d.ts +1 -1
  129. package/esm/presentation/widget/insight/LayeredTableView.d.ts.map +1 -1
  130. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.d.ts.map +1 -1
  131. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.js +2 -3
  132. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
  133. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +1 -1
  134. package/esm/presentation/widget/insight/types.d.ts +1 -1
  135. package/esm/presentation/widget/insight/types.d.ts.map +1 -1
  136. package/esm/presentation/widget/richText/RestrictedReferencesDialog.d.ts.map +1 -1
  137. package/esm/presentation/widget/richText/RestrictedReferencesDialog.js +5 -6
  138. package/esm/presentation/widget/visualizationSwitcher/ViewModeDashboardVisualizationSwitcher.js +1 -1
  139. package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.d.ts.map +1 -1
  140. package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.js +1 -4
  141. package/esm/presentation/widget/widget/InsightWidget/DefaultDashboardInsightWidget.js +2 -3
  142. package/esm/sdk-ui-dashboard.d.ts +68 -42
  143. package/package.json +21 -21
  144. package/styles/css/main.css +8 -7
  145. package/styles/css/main.css.map +1 -1
  146. package/styles/css/richTextWidget.css +4 -0
  147. package/styles/css/richTextWidget.css.map +1 -1
  148. package/styles/scss/richTextWidget.scss +5 -1
  149. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts +0 -13
  150. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts.map +0 -1
  151. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.js +0 -98
  152. package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts +0 -5
  153. package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts.map +0 -1
  154. package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.js +0 -28
  155. package/esm/presentation/widget/insight/insightToTable.d.ts +0 -74
  156. package/esm/presentation/widget/insight/insightToTable.d.ts.map +0 -1
  157. 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
- }