@gooddata/sdk-ui-dashboard 11.58.0-alpha.5 → 11.58.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/_staging/insight/insightWidgetDescription.d.ts +9 -0
  4. package/esm/_staging/insight/insightWidgetDescription.d.ts.map +1 -0
  5. package/esm/_staging/insight/insightWidgetDescription.js +12 -0
  6. package/esm/_staging/sharedHooks/useRichTextFilters.d.ts +4 -22
  7. package/esm/_staging/sharedHooks/useRichTextFilters.d.ts.map +1 -1
  8. package/esm/_staging/sharedHooks/useRichTextFilters.js +11 -15
  9. package/esm/_staging/sharedHooks/useRichTextInputs.d.ts +35 -0
  10. package/esm/_staging/sharedHooks/useRichTextInputs.d.ts.map +1 -0
  11. package/esm/_staging/sharedHooks/useRichTextInputs.js +37 -0
  12. package/esm/index.d.ts +2 -2
  13. package/esm/index.d.ts.map +1 -1
  14. package/esm/index.js +1 -1
  15. package/esm/model/DashboardTester.d.ts.map +1 -1
  16. package/esm/model/DashboardTester.js +2 -4
  17. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
  18. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +21 -13
  19. package/esm/model/commandHandlers/parameters/dashboardParameterRoots.d.ts +20 -0
  20. package/esm/model/commandHandlers/parameters/dashboardParameterRoots.d.ts.map +1 -0
  21. package/esm/model/commandHandlers/parameters/dashboardParameterRoots.js +61 -0
  22. package/esm/model/commandHandlers/parameters/loadParameterDependencies.d.ts +27 -0
  23. package/esm/model/commandHandlers/parameters/loadParameterDependencies.d.ts.map +1 -0
  24. package/esm/model/commandHandlers/parameters/loadParameterDependencies.js +114 -0
  25. package/esm/model/commandHandlers/parameters/parameterDependenciesWorker.d.ts +6 -0
  26. package/esm/model/commandHandlers/parameters/parameterDependenciesWorker.d.ts.map +1 -0
  27. package/esm/model/commandHandlers/parameters/parameterDependenciesWorker.js +107 -0
  28. package/esm/model/react/useInitializeDashboardStore.d.ts.map +1 -1
  29. package/esm/model/react/useInitializeDashboardStore.js +2 -4
  30. package/esm/model/react/useTextParameters.d.ts +34 -0
  31. package/esm/model/react/useTextParameters.d.ts.map +1 -0
  32. package/esm/model/react/useTextParameters.js +68 -0
  33. package/esm/model/react/useWidgetExecConfig.d.ts.map +1 -1
  34. package/esm/model/react/useWidgetExecConfig.js +3 -2
  35. package/esm/model/store/catalog/catalogReducers.d.ts +8 -8
  36. package/esm/model/store/catalog/catalogReducers.d.ts.map +1 -1
  37. package/esm/model/store/catalog/catalogReducers.js +25 -12
  38. package/esm/model/store/catalog/catalogSelectors.d.ts +8 -16
  39. package/esm/model/store/catalog/catalogSelectors.d.ts.map +1 -1
  40. package/esm/model/store/catalog/catalogSelectors.js +7 -15
  41. package/esm/model/store/catalog/catalogState.d.ts +15 -30
  42. package/esm/model/store/catalog/catalogState.d.ts.map +1 -1
  43. package/esm/model/store/catalog/catalogState.js +1 -2
  44. package/esm/model/store/catalog/index.d.ts +4 -4
  45. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts +25 -9
  46. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts.map +1 -1
  47. package/esm/model/store/tabs/parameters/parametersHelpers.js +46 -13
  48. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +9 -9
  49. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts.map +1 -1
  50. package/esm/model/store/tabs/parameters/parametersSelectors.js +26 -22
  51. package/esm/presentation/dashboard/DashboardSidebar/SidebarResizeContext.d.ts.map +1 -1
  52. package/esm/presentation/dashboard/DashboardSidebar/SidebarResizeContext.js +7 -1
  53. package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/DashboardLayoutSectionHeaderDescription.d.ts.map +1 -1
  54. package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/DashboardLayoutSectionHeaderDescription.js +3 -10
  55. package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/EditableHeader/SectionHeaderEditable.d.ts.map +1 -1
  56. package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/EditableHeader/SectionHeaderEditable.js +5 -10
  57. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +6 -1
  58. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
  59. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +8 -3
  60. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +6 -1
  61. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
  62. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +8 -3
  63. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +6 -1
  64. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
  65. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +8 -3
  66. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +6 -1
  67. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
  68. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +13 -8
  69. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +6 -1
  70. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
  71. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +8 -3
  72. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +6 -1
  73. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
  74. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +8 -3
  75. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +6 -1
  76. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
  77. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +8 -3
  78. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +6 -1
  79. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
  80. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +8 -3
  81. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +6 -1
  82. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
  83. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +8 -3
  84. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +6 -1
  85. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
  86. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +10 -5
  87. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +6 -1
  88. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
  89. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +8 -3
  90. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +6 -1
  91. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
  92. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +9 -4
  93. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +6 -1
  94. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
  95. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +8 -3
  96. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +6 -1
  97. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
  98. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +8 -3
  99. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +6 -1
  100. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
  101. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +8 -3
  102. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +6 -1
  103. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
  104. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +8 -3
  105. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +6 -1
  106. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
  107. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +8 -3
  108. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +6 -1
  109. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
  110. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +9 -4
  111. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +6 -1
  112. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
  113. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +9 -4
  114. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +6 -1
  115. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
  116. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +9 -4
  117. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +6 -1
  118. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
  119. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +18 -13
  120. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +6 -1
  121. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
  122. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +9 -4
  123. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +6 -1
  124. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
  125. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +10 -5
  126. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +6 -1
  127. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
  128. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +9 -4
  129. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +6 -1
  130. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
  131. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +12 -7
  132. package/esm/presentation/widget/description/ExportModeInsightWidgetDescription.d.ts.map +1 -1
  133. package/esm/presentation/widget/description/ExportModeInsightWidgetDescription.js +4 -11
  134. package/esm/presentation/widget/description/InsightWidgetDescriptionTrigger.d.ts.map +1 -1
  135. package/esm/presentation/widget/description/InsightWidgetDescriptionTrigger.js +4 -9
  136. package/esm/presentation/widget/description/types.d.ts +3 -5
  137. package/esm/presentation/widget/description/types.d.ts.map +1 -1
  138. package/esm/presentation/widget/description/useInsightWidgetDescription.d.ts.map +1 -1
  139. package/esm/presentation/widget/description/useInsightWidgetDescription.js +2 -5
  140. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
  141. package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +5 -10
  142. package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescription.d.ts +4 -3
  143. package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescription.d.ts.map +1 -1
  144. package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescription.js +5 -7
  145. package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescriptionConfig.d.ts.map +1 -1
  146. package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescriptionConfig.js +1 -3
  147. package/esm/presentation/widget/richText/EditModeDashboardRichText.d.ts.map +1 -1
  148. package/esm/presentation/widget/richText/EditModeDashboardRichText.js +5 -9
  149. package/esm/presentation/widget/richText/ViewModeDashboardRichText.d.ts.map +1 -1
  150. package/esm/presentation/widget/richText/ViewModeDashboardRichText.js +4 -10
  151. package/esm/sdk-ui-dashboard.d.ts +34 -60
  152. package/package.json +21 -21
  153. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts +0 -45
  154. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts.map +0 -1
  155. package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.js +0 -99
  156. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts +0 -11
  157. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts.map +0 -1
  158. package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.js +0 -71
  159. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts +0 -22
  160. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts.map +0 -1
  161. package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.js +0 -39
  162. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts +0 -21
  163. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts.map +0 -1
  164. package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.js +0 -86
@@ -30,8 +30,8 @@ import { uiActions } from "../../../store/ui/index.js";
30
30
  import { unavailableObjectsActions } from "../../../store/unavailableObjects/index.js";
31
31
  import { selectUnavailableObjects } from "../../../store/unavailableObjects/unavailableObjectsSelectors.js";
32
32
  import { userActions } from "../../../store/user/index.js";
33
- import { collectDashboardFilterContextItems, loadFilterParameterDependencies, } from "../../parameters/loadFilterParameterDependencies.js";
34
- import { loadInsightParameterDependencies } from "../../parameters/loadInsightParameterDependencies.js";
33
+ import { collectDashboardParameterRoots } from "../../parameters/dashboardParameterRoots.js";
34
+ import { loadParameterDependencies } from "../../parameters/loadParameterDependencies.js";
35
35
  import { changeDashboardTimezoneOverrideHandler } from "../../timezone/changeDashboardTimezoneOverrideHandler.js";
36
36
  import { applyDefaultFilterView } from "../common/filterViews.js";
37
37
  import { actionsToInitializeExistingDashboard, actionsToInitializeNewDashboard, } from "../common/stateInitializers.js";
@@ -195,11 +195,11 @@ function* loadExistingDashboard(ctx, cmd, dashboardRef) {
195
195
  // Note: activeTabLocalIdentifier is app state only, NOT persisted to/read from dashboard MD
196
196
  const resolvedActiveTabId = resolveActiveTabId(dashboardWithFilterView.tabs, cmd.payload.initialTabId, undefined);
197
197
  const dashboard = dashboardWithFilterView;
198
- const [{ tabsAttributeFilterConfigs, tabsDateFilterConfig, tabsDateFilterConfigSource }, workspaceParameters, insightParameterDependencies, filterParameterDependencies,] = yield all([
198
+ const enableParameters = config.settings?.enableParameters ?? false;
199
+ const [{ tabsAttributeFilterConfigs, tabsDateFilterConfig, tabsDateFilterConfigSource }, workspaceParameters, parameterDependencies,] = yield all([
199
200
  call(getTabsFilterConfigs, dashboard, config, ctx, cmd),
200
201
  call(loadWorkspaceParametersWithStatus, ctx, config.settings),
201
- call(loadInsightParameterDependencies, ctx, insights, config.settings?.enableParameters ?? false),
202
- call(loadFilterParameterDependencies, ctx, collectDashboardFilterContextItems(dashboard), config.settings?.enableParameters ?? false),
202
+ call(loadParameterDependencies, ctx, enableParameters ? collectDashboardParameterRoots(dashboard, insights) : []),
203
203
  ]);
204
204
  const workspaceParametersList = Array.isArray(workspaceParameters) ? workspaceParameters : [];
205
205
  const initActions = yield call(actionsToInitializeExistingDashboard, ctx, dashboard, insights, config.settings, config.settings.enableImmediateAttributeFilterDisplayAsLabelMigration ?? false, undefined, undefined, tabsAttributeFilterConfigs, tabsDateFilterConfig, tabsDateFilterConfigSource, createDisplayFormMap([], []), cmd.payload.persistedDashboard, resolvedActiveTabId, workspaceParametersList);
@@ -214,8 +214,13 @@ function* loadExistingDashboard(ctx, cmd, dashboardRef) {
214
214
  permissionsActions.setPermissions(permissions),
215
215
  catalogActions.setCatalogItems(catalogPayload),
216
216
  catalogActions.setCatalogParameters(makeCatalogParametersPayload(workspaceParameters)),
217
- catalogActions.setCatalogInsightParameters(insightParameterDependencies),
218
- catalogActions.setCatalogFilterParameters(filterParameterDependencies),
217
+ catalogActions.setCatalogParameterDependencies({
218
+ status: enableParameters ? "loaded" : "uninitialized",
219
+ byRoot: {},
220
+ requestedRoots: {},
221
+ }),
222
+ catalogActions.mergeCatalogParameterDependencies(parameterDependencies.byRoot),
223
+ catalogActions.markParameterDependenciesFailed(parameterDependencies.failedRoots),
219
224
  ...initActions,
220
225
  // NOTE: Tab configs (dateFilterConfig, dateFilterConfigs, attributeFilterConfigs, filterContext)
221
226
  // are now initialized as part of the tabs state in initActions via setTabs action
@@ -259,10 +264,8 @@ function* initializeNewDashboard(ctx, cmd) {
259
264
  const { initActions, dashboard, insights } = yield call(actionsToInitializeNewDashboard, ctx, config.settings, dateFilterConfig, loadedCatalog
260
265
  ? createDisplayFormMapFromCatalog(loadedCatalog.catalog, loadedCatalog.computedAttributes)
261
266
  : createDisplayFormMap([], []), cmd.payload.initialTabId, workspaceParametersList);
262
- const insightParameterDependencies = yield call(loadInsightParameterDependencies, ctx, insights, config.settings?.enableParameters ?? false);
263
- // a new dashboard starts with the default (date-only) filter context, so there is nothing to
264
- // resolve yet; this only records the status so the widgets do not wait for a load that never comes
265
- const filterParameterDependencies = yield call(loadFilterParameterDependencies, ctx, [], config.settings?.enableParameters ?? false);
267
+ const enableParameters = config.settings?.enableParameters ?? false;
268
+ const parameterDependencies = yield call(loadParameterDependencies, ctx, enableParameters ? collectDashboardParameterRoots(dashboard, insights) : []);
266
269
  const batch = batchActions([
267
270
  backendCapabilitiesActions.setBackendCapabilities(backend.capabilities),
268
271
  configActions.setConfig(config),
@@ -279,8 +282,13 @@ function* initializeNewDashboard(ctx, cmd) {
279
282
  dateHierarchyTemplates: dateHierarchyTemplates,
280
283
  }),
281
284
  catalogActions.setCatalogParameters(makeCatalogParametersPayload(workspaceParameters)),
282
- catalogActions.setCatalogInsightParameters(insightParameterDependencies),
283
- catalogActions.setCatalogFilterParameters(filterParameterDependencies),
285
+ catalogActions.setCatalogParameterDependencies({
286
+ status: enableParameters ? "loaded" : "uninitialized",
287
+ byRoot: {},
288
+ requestedRoots: {},
289
+ }),
290
+ catalogActions.mergeCatalogParameterDependencies(parameterDependencies.byRoot),
291
+ catalogActions.markParameterDependenciesFailed(parameterDependencies.failedRoots),
284
292
  listedDashboardsActions.setListedDashboards(listedDashboards),
285
293
  accessibleDashboardsActions.setAccessibleDashboards(listedDashboards),
286
294
  executionResultsActions.clearAllExecutionResults(),
@@ -0,0 +1,20 @@
1
+ import { type IDashboard, type IInsight, type IdentifierRef } from "@gooddata/sdk-model";
2
+ /**
3
+ * Every dependency root the dashboard needs parameters for: its insights, text references, and
4
+ * dashboard filters across all tabs. Collected at initialization so one references call covers the
5
+ * whole dashboard.
6
+ *
7
+ * A widget whose insight did not load keeps its own description, which is what it renders.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function collectDashboardParameterRoots(dashboard: IDashboard | undefined, insights: IInsight[]): IdentifierRef[];
12
+ /**
13
+ * The dependency roots of a text: the metrics and computed attributes it references, which the
14
+ * text executes and whose parameters therefore apply to it. Labels resolve through their own
15
+ * display form and parameters are never executed, so neither is a root.
16
+ *
17
+ * @internal
18
+ */
19
+ export declare function collectTextReferenceRoots(content: string): IdentifierRef[];
20
+ //# sourceMappingURL=dashboardParameterRoots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardParameterRoots.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/dashboardParameterRoots.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,KAAK,UAAU,EAEf,KAAK,QAAQ,EACb,KAAK,aAAa,EAKrB,MAAM,qBAAqB,CAAC;AAS7B;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC1C,SAAS,EAAE,UAAU,GAAG,SAAS,EACjC,QAAQ,EAAE,QAAQ,EAAE,GACrB,aAAa,EAAE,CA+BjB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAM1E"}
@@ -0,0 +1,61 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { uniqBy } from "lodash-es";
3
+ import { walkLayout } from "@gooddata/sdk-backend-spi";
4
+ import { isIdentifierRef, isInsightWidget, isRichTextWidget, serializeObjRef, } from "@gooddata/sdk-model";
5
+ import { collectReferences } from "@gooddata/sdk-ui-kit";
6
+ import { insightWidgetDescription } from "../../../_staging/insight/insightWidgetDescription.js";
7
+ import { newInsightMap } from "../../../_staging/metadata/objRefMap.js";
8
+ import { collectFilterParameterRoots } from "../../store/tabs/parameters/parametersHelpers.js";
9
+ import { insightRoots } from "./loadParameterDependencies.js";
10
+ /**
11
+ * Every dependency root the dashboard needs parameters for: its insights, text references, and
12
+ * dashboard filters across all tabs. Collected at initialization so one references call covers the
13
+ * whole dashboard.
14
+ *
15
+ * A widget whose insight did not load keeps its own description, which is what it renders.
16
+ *
17
+ * @internal
18
+ */
19
+ export function collectDashboardParameterRoots(dashboard, insights) {
20
+ const insightMap = newInsightMap(insights);
21
+ const roots = insightRoots(insights);
22
+ function textRoots(content) {
23
+ return content ? collectTextReferenceRoots(content) : [];
24
+ }
25
+ function widgetText(widget) {
26
+ if (isRichTextWidget(widget)) {
27
+ return widget.content;
28
+ }
29
+ return isInsightWidget(widget)
30
+ ? insightWidgetDescription(widget, insightMap.get(widget.insight))
31
+ : undefined;
32
+ }
33
+ for (const layout of [dashboard?.layout, ...(dashboard?.tabs ?? []).map((tab) => tab.layout)]) {
34
+ if (layout) {
35
+ walkLayout(layout, {
36
+ sectionCallback: (section) => roots.push(...textRoots(section.header?.description)),
37
+ widgetCallback: (widget) => roots.push(...textRoots(widgetText(widget))),
38
+ });
39
+ }
40
+ }
41
+ const filters = [
42
+ ...(dashboard?.tabs ?? []).flatMap((tab) => tab.filterContext?.filters ?? []),
43
+ ...(dashboard?.filterContext?.filters ?? []),
44
+ ];
45
+ roots.push(...collectFilterParameterRoots(filters));
46
+ return uniqBy(roots, serializeObjRef);
47
+ }
48
+ /**
49
+ * The dependency roots of a text: the metrics and computed attributes it references, which the
50
+ * text executes and whose parameters therefore apply to it. Labels resolve through their own
51
+ * display form and parameters are never executed, so neither is a root.
52
+ *
53
+ * @internal
54
+ */
55
+ export function collectTextReferenceRoots(content) {
56
+ const roots = Object.values(collectReferences(content))
57
+ .filter(({ type }) => type === "measure" || type === "computedAttribute")
58
+ .map(({ ref }) => ref)
59
+ .filter(isIdentifierRef);
60
+ return uniqBy(roots, serializeObjRef);
61
+ }
@@ -0,0 +1,27 @@
1
+ import { type IInsight, type IdentifierRef } from "@gooddata/sdk-model";
2
+ import { type DashboardContext } from "../../types/commonTypes.js";
3
+ interface IParameterDependenciesLoadResult {
4
+ byRoot: Record<string, IdentifierRef[]>;
5
+ failedRoots: IdentifierRef[];
6
+ }
7
+ /**
8
+ * Loads the root -> parameter dependencies of `roots` from the workspace references service.
9
+ *
10
+ * @remarks
11
+ * Walks the dependency graph in `direction: "down"` from each root, then collects the parameter
12
+ * nodes reachable from it through metrics and computed attributes. Each root is keyed by
13
+ * `serializeObjRef` of the ref exactly as it was supplied, so a caller looks its own refs up again.
14
+ * A batch the backend rejects for one unknown root is retried root by root, so the remaining roots
15
+ * stay available and only the rejected ones fail. Any other failure is endpoint-wide and fails every
16
+ * root at once.
17
+ */
18
+ export declare function loadParameterDependencies(ctx: DashboardContext, roots: IdentifierRef[]): Promise<IParameterDependenciesLoadResult>;
19
+ /**
20
+ * The dependency roots of insights: their own refs, less the ones spelled by uri - the graph is
21
+ * walked by identifier.
22
+ *
23
+ * @internal
24
+ */
25
+ export declare function insightRoots(insights: IInsight[]): IdentifierRef[];
26
+ export {};
27
+ //# sourceMappingURL=loadParameterDependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadParameterDependencies.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/loadParameterDependencies.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,QAAQ,EACb,KAAK,aAAa,EAIrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,UAAU,gCAAgC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IACxC,WAAW,EAAE,aAAa,EAAE,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC3C,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,gCAAgC,CAAC,CAwB3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,CAElE"}
@@ -0,0 +1,114 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { isUnexpectedResponseError } from "@gooddata/sdk-backend-spi";
3
+ import { insightRef, isIdentifierRef, serializeObjRef, } from "@gooddata/sdk-model";
4
+ /**
5
+ * Loads the root -> parameter dependencies of `roots` from the workspace references service.
6
+ *
7
+ * @remarks
8
+ * Walks the dependency graph in `direction: "down"` from each root, then collects the parameter
9
+ * nodes reachable from it through metrics and computed attributes. Each root is keyed by
10
+ * `serializeObjRef` of the ref exactly as it was supplied, so a caller looks its own refs up again.
11
+ * A batch the backend rejects for one unknown root is retried root by root, so the remaining roots
12
+ * stay available and only the rejected ones fail. Any other failure is endpoint-wide and fails every
13
+ * root at once.
14
+ */
15
+ export async function loadParameterDependencies(ctx, roots) {
16
+ if (roots.length === 0) {
17
+ return { byRoot: {}, failedRoots: [] };
18
+ }
19
+ try {
20
+ return { byRoot: await loadReachableParameterMap(ctx, roots), failedRoots: [] };
21
+ }
22
+ catch (error) {
23
+ if (roots.length === 1 || !rejectsWholeBatch(error)) {
24
+ return { byRoot: {}, failedRoots: roots };
25
+ }
26
+ const results = await Promise.allSettled(roots.map((root) => loadReachableParameterMap(ctx, [root])));
27
+ const byRoot = {};
28
+ const failedRoots = [];
29
+ for (let i = 0; i < roots.length; i++) {
30
+ const result = results[i];
31
+ if (result.status === "fulfilled") {
32
+ Object.assign(byRoot, result.value);
33
+ }
34
+ else {
35
+ failedRoots.push(roots[i]);
36
+ }
37
+ }
38
+ return { byRoot, failedRoots };
39
+ }
40
+ }
41
+ /**
42
+ * The dependency roots of insights: their own refs, less the ones spelled by uri - the graph is
43
+ * walked by identifier.
44
+ *
45
+ * @internal
46
+ */
47
+ export function insightRoots(insights) {
48
+ return insights.map(insightRef).filter(isIdentifierRef);
49
+ }
50
+ /**
51
+ * The graph endpoint answers a batch holding one root it does not know with `400`, so the other
52
+ * roots are lost with it and only a per-root retry tells them apart. Every other failure - the
53
+ * endpoint down, the session gone - fails a retry the same way, for every root.
54
+ */
55
+ function rejectsWholeBatch(error) {
56
+ return isUnexpectedResponseError(error) && error.httpStatus === 400;
57
+ }
58
+ async function loadReachableParameterMap(ctx, roots) {
59
+ const result = await ctx.backend
60
+ .workspace(ctx.workspace)
61
+ .references()
62
+ .getReferences(roots, { direction: "down" });
63
+ return buildReachableParameterMap(roots, result.edges);
64
+ }
65
+ function buildReachableParameterMap(roots, edges) {
66
+ const adjacency = buildAdjacency(edges);
67
+ const result = {};
68
+ for (const root of roots) {
69
+ result[serializeObjRef(root)] = reachableParameterRefs(graphInsightRef(root), adjacency);
70
+ }
71
+ return result;
72
+ }
73
+ /**
74
+ * Only insight roots arrive untyped, and the graph needs the type to start the walk. The map key
75
+ * keeps the ref as it was supplied, so the coercion never reaches it.
76
+ */
77
+ function graphInsightRef(root) {
78
+ return root.type ? root : { ...root, type: "insight" };
79
+ }
80
+ function buildAdjacency(edges) {
81
+ const adjacency = new Map();
82
+ for (const edge of edges) {
83
+ const fromKey = serializeObjRef(edge.from);
84
+ const neighbors = adjacency.get(fromKey);
85
+ if (neighbors) {
86
+ neighbors.push(edge.to);
87
+ }
88
+ else {
89
+ adjacency.set(fromKey, [edge.to]);
90
+ }
91
+ }
92
+ return adjacency;
93
+ }
94
+ function reachableParameterRefs(start, adjacency) {
95
+ const parameters = [];
96
+ const visited = new Set([serializeObjRef(start)]);
97
+ const queue = [start];
98
+ for (let i = 0; i < queue.length; i++) {
99
+ for (const neighbor of adjacency.get(serializeObjRef(queue[i])) ?? []) {
100
+ const key = serializeObjRef(neighbor);
101
+ if (visited.has(key)) {
102
+ continue;
103
+ }
104
+ visited.add(key);
105
+ if (neighbor.type === "parameter") {
106
+ parameters.push(neighbor);
107
+ }
108
+ else {
109
+ queue.push(neighbor);
110
+ }
111
+ }
112
+ }
113
+ return parameters;
114
+ }
@@ -0,0 +1,6 @@
1
+ import { type SagaIterator } from "redux-saga";
2
+ import { type IdentifierRef } from "@gooddata/sdk-model";
3
+ import { type DashboardContext } from "../../types/commonTypes.js";
4
+ export declare const requestParameterDependencies: import("@reduxjs/toolkit").ActionCreatorWithPayload<IdentifierRef[], string>;
5
+ export declare function newParameterDependenciesWorker(): (ctx: DashboardContext) => SagaIterator<void>;
6
+ //# sourceMappingURL=parameterDependenciesWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameterDependenciesWorker.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/parameterDependenciesWorker.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAiB,KAAK,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAYzF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAOnE,eAAO,MAAM,4BAA4B,8EAAiE,CAAC;AAM3G,wBAAgB,8BAA8B,UACQ,gBAAgB,KAAG,YAAY,CAAC,IAAI,CAAC,CAM1F"}
@@ -0,0 +1,107 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { createAction } from "@reduxjs/toolkit";
3
+ import { uniqBy } from "lodash-es";
4
+ import { batchActions } from "redux-batched-actions";
5
+ import { call, put, select, takeEvery } from "redux-saga/effects";
6
+ import { serializeObjRef } from "@gooddata/sdk-model";
7
+ import { selectCatalogParameterDependencies, selectCatalogParameterDependenciesStatus, selectCatalogRequestedParameterRoots, } from "../../store/catalog/catalogSelectors.js";
8
+ import { catalogActions } from "../../store/catalog/index.js";
9
+ import { insightsActions } from "../../store/insights/index.js";
10
+ import { selectFiltersByTab } from "../../store/tabs/filterContext/filterContextSelectors.js";
11
+ import { tabsActions } from "../../store/tabs/index.js";
12
+ import { collectFilterParameterRoots } from "../../store/tabs/parameters/parametersHelpers.js";
13
+ import { insightRoots, loadParameterDependencies } from "./loadParameterDependencies.js";
14
+ const TABS_ACTION_PREFIX = `${tabsActions.setTabs.type.split("/")[0]}/`;
15
+ export const requestParameterDependencies = createAction("parameterDependencies/request");
16
+ export function newParameterDependenciesWorker() {
17
+ return function* parameterDependenciesWorker(ctx) {
18
+ const generation = { current: 0 };
19
+ yield takeEvery(writesParameterDependencyInputs, function* onInputsWritten(action) {
20
+ yield call(updateParameterDependencies, ctx, generation, action);
21
+ });
22
+ };
23
+ }
24
+ function* updateParameterDependencies(ctx, generation, action) {
25
+ const actions = unbatched(action);
26
+ if (actions.some(catalogActions.setCatalogParameterDependencies.match)) {
27
+ generation.current += 1;
28
+ }
29
+ const explicitlyRequestedRoots = actions.flatMap(requestedRootsOf);
30
+ const status = yield select(selectCatalogParameterDependenciesStatus);
31
+ if (status !== "loaded") {
32
+ if (explicitlyRequestedRoots.length > 0) {
33
+ yield put(catalogActions.markParameterDependenciesFailed(explicitlyRequestedRoots));
34
+ }
35
+ return;
36
+ }
37
+ const known = yield select(selectCatalogParameterDependencies);
38
+ const requested = yield select(selectCatalogRequestedParameterRoots);
39
+ const refreshRoots = insightRoots(actions.flatMap(writtenInsightsOf));
40
+ const requestedRoots = [
41
+ ...insightRoots(actions.flatMap(replacedInsightsOf)),
42
+ ...explicitlyRequestedRoots,
43
+ ];
44
+ if (actions.some(writesTabs)) {
45
+ const filtersByTab = yield select(selectFiltersByTab);
46
+ requestedRoots.push(...collectFilterParameterRoots(Object.values(filtersByTab).flat()));
47
+ }
48
+ const unknownRoots = requestedRoots.filter((root) => {
49
+ const key = serializeObjRef(root);
50
+ return !(key in known) && !(key in requested);
51
+ });
52
+ const roots = uniqBy([...refreshRoots, ...unknownRoots], serializeObjRef);
53
+ yield call(loadAndMergeParameterDependencies, ctx, generation, roots);
54
+ }
55
+ function* loadAndMergeParameterDependencies(ctx, generation, roots) {
56
+ if (roots.length === 0) {
57
+ return;
58
+ }
59
+ const requestGeneration = generation.current;
60
+ yield put(catalogActions.markParameterDependenciesPending(roots));
61
+ const loaded = yield call(loadParameterDependencies, ctx, roots);
62
+ if (generation.current !== requestGeneration) {
63
+ return;
64
+ }
65
+ yield put(batchActions([
66
+ catalogActions.mergeCatalogParameterDependencies(loaded.byRoot),
67
+ catalogActions.markParameterDependenciesFailed(loaded.failedRoots),
68
+ ]));
69
+ }
70
+ function writesParameterDependencyInputs(action) {
71
+ return unbatched(action).some((item) => catalogActions.setCatalogParameterDependencies.match(item) ||
72
+ requestParameterDependencies.match(item) ||
73
+ writtenInsightsOf(item).length > 0 ||
74
+ replacedInsightsOf(item).length > 0 ||
75
+ writesTabs(item));
76
+ }
77
+ function requestedRootsOf(action) {
78
+ return requestParameterDependencies.match(action) ? action.payload : [];
79
+ }
80
+ function writtenInsightsOf(action) {
81
+ if (insightsActions.addInsights.match(action)) {
82
+ return entityPayloadInsights(action.payload);
83
+ }
84
+ if (insightsActions.upsertInsight.match(action)) {
85
+ return [action.payload];
86
+ }
87
+ return [];
88
+ }
89
+ function replacedInsightsOf(action) {
90
+ return insightsActions.setInsights.match(action) ? entityPayloadInsights(action.payload) : [];
91
+ }
92
+ function entityPayloadInsights(payload) {
93
+ return Array.isArray(payload) ? [...payload] : Object.values(payload);
94
+ }
95
+ function writesTabs(action) {
96
+ return action.type.startsWith(TABS_ACTION_PREFIX);
97
+ }
98
+ function unbatched(action) {
99
+ return isBatchAction(action) ? action.payload.flatMap(unbatched) : [action];
100
+ }
101
+ function isBatchAction(action) {
102
+ return ("meta" in action &&
103
+ typeof action.meta === "object" &&
104
+ action.meta !== null &&
105
+ "batch" in action.meta &&
106
+ action.meta.batch === true);
107
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useInitializeDashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/react/useInitializeDashboardStore.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,sBAAsB,EAAwB,MAAM,4BAA4B,CAAC;AAI/F,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,YAAY,CAAC;AA6D/D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,UAC7B,4BAA4B,KACpC,sBAAsB,GAAG,IA4G3B,CAAC"}
1
+ {"version":3,"file":"useInitializeDashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/react/useInitializeDashboardStore.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,sBAAsB,EAAwB,MAAM,4BAA4B,CAAC;AAI/F,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,YAAY,CAAC;AA6D/D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,UAC7B,4BAA4B,KACpC,sBAAsB,GAAG,IA2G3B,CAAC"}
@@ -6,8 +6,7 @@ import { enrichMapboxToken, useMapboxToken } from "@gooddata/sdk-ui-geo";
6
6
  import { enrichAgGridToken, useAgGridToken } from "@gooddata/sdk-ui-pivot/next";
7
7
  import { shallowEqualObjects } from "@gooddata/util";
8
8
  import { newDashboardSummaryWorkflowWorker } from "../commandHandlers/dashboard/dashboardSummaryWorkflowWorker.js";
9
- import { newFilterParameterDependenciesWorker } from "../commandHandlers/parameters/filterParameterDependenciesWorker.js";
10
- import { newInsightParameterDependenciesWorker } from "../commandHandlers/parameters/insightParameterDependenciesWorker.js";
9
+ import { newParameterDependenciesWorker } from "../commandHandlers/parameters/parameterDependenciesWorker.js";
11
10
  import { newRenderingWorker } from "../commandHandlers/render/renderingWorker.js";
12
11
  import { InitialLoadCorrelationId, initializeDashboardWithPersistedDashboard, } from "../commands/dashboard.js";
13
12
  import { dashboardDeinitialized } from "../events/dashboard.js";
@@ -113,8 +112,7 @@ export const useInitializeDashboardStore = (props) => {
113
112
  isExport: config?.isExport,
114
113
  }),
115
114
  newDashboardSummaryWorkflowWorker(),
116
- newInsightParameterDependenciesWorker(),
117
- newFilterParameterDependenciesWorker(),
115
+ newParameterDependenciesWorker(),
118
116
  ];
119
117
  // Create new store and fire load dashboard command.
120
118
  const newDashboardStore = createDashboardStore({
@@ -0,0 +1,34 @@
1
+ import { type IExecutionConfig, type IInsight, type ObjRef } from "@gooddata/sdk-model";
2
+ /**
3
+ * @internal
4
+ */
5
+ export interface ITextParameters {
6
+ execConfig: IExecutionConfig;
7
+ parameterDisplayValues: ReadonlyMap<string, string> | undefined;
8
+ loading: boolean;
9
+ }
10
+ /**
11
+ * What a text needs from the parameters of the dashboard.
12
+ *
13
+ * `execConfig` is the execution config for the references the text resolves: the dashboard-level
14
+ * settings plus the parameters the referenced metrics and computed attributes depend on, so a number
15
+ * in a text reads the same as the chart beside it.
16
+ *
17
+ * `parameterDisplayValues` is the text every parameter shows in a `{parameter/<id>}` reference, by
18
+ * parameter identifier. It is `undefined` where the dashboard resolves no parameters at all, or where
19
+ * the workspace parameters did not load, so the host passes nothing on and the token stays as it was
20
+ * typed. A failed load must not show every parameter as unknown.
21
+ *
22
+ * `loading` is true while a root the text references, or a root of a dashboard filter that applies to
23
+ * the text, is neither in the map nor marked failed. The host defers the execution until then, so a
24
+ * reference is never executed without the parameters it depends on and then executed again with them.
25
+ *
26
+ * @param content - the text whose references are executed
27
+ * @param ref - the widget hosting the text; `undefined` for a host outside any widget, which takes
28
+ * the active tab
29
+ * @param insight - the insight the host shows, whose authored values take part in the resolution and
30
+ * whose own filters the text executes under, so its dependencies apply too
31
+ * @internal
32
+ */
33
+ export declare function useTextParameters(content: string, ref?: ObjRef, insight?: IInsight): ITextParameters;
34
+ //# sourceMappingURL=useTextParameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTextParameters.d.ts","sourceRoot":"","sources":["../../../src/model/react/useTextParameters.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAmB,MAAM,qBAAqB,CAAC;AAkBzG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,sBAAsB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAChE,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,eAAe,CA6DpG"}
@@ -0,0 +1,68 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useEffect, useMemo } from "react";
3
+ import { serializeObjRef } from "@gooddata/sdk-model";
4
+ import { collectTextReferenceRoots } from "../commandHandlers/parameters/dashboardParameterRoots.js";
5
+ import { insightRoots } from "../commandHandlers/parameters/loadParameterDependencies.js";
6
+ import { requestParameterDependencies } from "../commandHandlers/parameters/parameterDependenciesWorker.js";
7
+ import { selectCatalogParametersIsLoaded, selectCatalogRequestedParameterRoots, } from "../store/catalog/catalogSelectors.js";
8
+ import { resolveEffectiveParameterValuesForRoots, resolveParameterDisplayValues, } from "../store/tabs/parameters/parametersHelpers.js";
9
+ import { selectWidgetParameterContext } from "../store/tabs/parameters/parametersSelectors.js";
10
+ import { useDashboardDispatch, useDashboardSelector } from "./DashboardStoreProvider.js";
11
+ import { useDashboardExecConfig } from "./useWidgetExecConfig.js";
12
+ /**
13
+ * What a text needs from the parameters of the dashboard.
14
+ *
15
+ * `execConfig` is the execution config for the references the text resolves: the dashboard-level
16
+ * settings plus the parameters the referenced metrics and computed attributes depend on, so a number
17
+ * in a text reads the same as the chart beside it.
18
+ *
19
+ * `parameterDisplayValues` is the text every parameter shows in a `{parameter/<id>}` reference, by
20
+ * parameter identifier. It is `undefined` where the dashboard resolves no parameters at all, or where
21
+ * the workspace parameters did not load, so the host passes nothing on and the token stays as it was
22
+ * typed. A failed load must not show every parameter as unknown.
23
+ *
24
+ * `loading` is true while a root the text references, or a root of a dashboard filter that applies to
25
+ * the text, is neither in the map nor marked failed. The host defers the execution until then, so a
26
+ * reference is never executed without the parameters it depends on and then executed again with them.
27
+ *
28
+ * @param content - the text whose references are executed
29
+ * @param ref - the widget hosting the text; `undefined` for a host outside any widget, which takes
30
+ * the active tab
31
+ * @param insight - the insight the host shows, whose authored values take part in the resolution and
32
+ * whose own filters the text executes under, so its dependencies apply too
33
+ * @internal
34
+ */
35
+ export function useTextParameters(content, ref, insight) {
36
+ const dashboardExecConfig = useDashboardExecConfig();
37
+ const parameterContext = useDashboardSelector(selectWidgetParameterContext(ref));
38
+ const requestedRoots = useDashboardSelector(selectCatalogRequestedParameterRoots);
39
+ const isCatalogLoaded = useDashboardSelector(selectCatalogParametersIsLoaded);
40
+ const dispatch = useDashboardDispatch();
41
+ // the host executes the text under the insight's own filters, so the text depends on whatever
42
+ // the insight depends on, the same root the chart resolves
43
+ const roots = useMemo(() => insight
44
+ ? [...collectTextReferenceRoots(content), ...insightRoots([insight])]
45
+ : collectTextReferenceRoots(content), [content, insight]);
46
+ const missingRoots = useMemo(() => parameterContext
47
+ ? [...roots, ...parameterContext.filterRoots].filter((root) => !(serializeObjRef(root) in parameterContext.dependenciesByRoot))
48
+ : [], [roots, parameterContext]);
49
+ // a text edited here, shown for an insight the dashboard did not load with, or under a filter
50
+ // added later has roots the initial references call never saw; the worker loads them
51
+ useEffect(() => {
52
+ const rootsToRequest = missingRoots.filter((root) => !(serializeObjRef(root) in requestedRoots));
53
+ if (rootsToRequest.length > 0) {
54
+ dispatch(requestParameterDependencies(rootsToRequest));
55
+ }
56
+ }, [missingRoots, requestedRoots, dispatch]);
57
+ const parameterValues = useMemo(() => resolveEffectiveParameterValuesForRoots(parameterContext, roots, insight), [parameterContext, roots, insight]);
58
+ const execConfig = useMemo(() => ({
59
+ ...dashboardExecConfig,
60
+ // omit when empty so it does not bust the execution's defFingerprint
61
+ ...(parameterValues.length > 0 ? { parameterValues } : {}),
62
+ }), [dashboardExecConfig, parameterValues]);
63
+ const parameterDisplayValues = useMemo(() => parameterContext && isCatalogLoaded
64
+ ? resolveParameterDisplayValues(parameterContext, insight)
65
+ : undefined, [parameterContext, isCatalogLoaded, insight]);
66
+ const loading = useMemo(() => missingRoots.some((root) => requestedRoots[serializeObjRef(root)] !== "failed"), [missingRoots, requestedRoots]);
67
+ return useMemo(() => ({ execConfig, parameterDisplayValues, loading }), [execConfig, parameterDisplayValues, loading]);
68
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useWidgetExecConfig.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecConfig.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AASxF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAWzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAepF"}
1
+ {"version":3,"file":"useWidgetExecConfig.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecConfig.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAc,MAAM,qBAAqB,CAAC;AASpG;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAWzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAepF"}
@@ -1,7 +1,8 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useMemo } from "react";
3
+ import { insightRef } from "@gooddata/sdk-model";
3
4
  import { selectEffectiveDashboardTimezone } from "../store/meta/metaSelectors.js";
4
- import { resolveEffectiveParameterValuesForInsight } from "../store/tabs/parameters/parametersHelpers.js";
5
+ import { resolveEffectiveParameterValuesForRoots } from "../store/tabs/parameters/parametersHelpers.js";
5
6
  import { selectWidgetParameterContext } from "../store/tabs/parameters/parametersSelectors.js";
6
7
  import { selectExecutionTimestamp } from "../store/ui/uiSelectors.js";
7
8
  import { useDashboardSelector } from "./DashboardStoreProvider.js";
@@ -34,7 +35,7 @@ export function useDashboardExecConfig() {
34
35
  export function useWidgetExecConfig(ref, insight) {
35
36
  const dashboardExecConfig = useDashboardExecConfig();
36
37
  const parameterContext = useDashboardSelector(selectWidgetParameterContext(ref));
37
- const parameterValues = useMemo(() => resolveEffectiveParameterValuesForInsight(parameterContext, insight), [parameterContext, insight]);
38
+ const parameterValues = useMemo(() => resolveEffectiveParameterValuesForRoots(parameterContext, [insightRef(insight)], insight), [parameterContext, insight]);
38
39
  return useMemo(() => ({
39
40
  ...dashboardExecConfig,
40
41
  // omit when empty so it does not bust the execution's defFingerprint
@@ -1,6 +1,6 @@
1
1
  import { type Action, type CaseReducer } from "@reduxjs/toolkit";
2
2
  import { type ICatalogAttribute, type ICatalogAttributeHierarchy, type ICatalogComputedAttribute, type ICatalogDateDataset, type ICatalogFact, type ICatalogMeasure, type IDateHierarchyTemplate, type IdentifierRef } from "@gooddata/sdk-model";
3
- import { type CatalogState, type ICatalogFilterParametersState, type ICatalogInsightParametersState, type ICatalogParametersState } from "./catalogState.js";
3
+ import { type CatalogState, type ICatalogParameterDependenciesState, type ICatalogParametersState } from "./catalogState.js";
4
4
  type CatalogReducer<A extends Action> = CaseReducer<CatalogState, A>;
5
5
  /**
6
6
  * @public
@@ -46,20 +46,20 @@ export declare const catalogReducers: {
46
46
  payload: ICatalogParametersState;
47
47
  type: string;
48
48
  }>;
49
- setCatalogInsightParameters: CatalogReducer<{
50
- payload: ICatalogInsightParametersState;
49
+ setCatalogParameterDependencies: CatalogReducer<{
50
+ payload: ICatalogParameterDependenciesState;
51
51
  type: string;
52
52
  }>;
53
- mergeCatalogInsightParameters: CatalogReducer<{
53
+ mergeCatalogParameterDependencies: CatalogReducer<{
54
54
  payload: Record<string, IdentifierRef[]>;
55
55
  type: string;
56
56
  }>;
57
- setCatalogFilterParameters: CatalogReducer<{
58
- payload: ICatalogFilterParametersState;
57
+ markParameterDependenciesPending: CatalogReducer<{
58
+ payload: IdentifierRef[];
59
59
  type: string;
60
60
  }>;
61
- mergeCatalogFilterParameters: CatalogReducer<{
62
- payload: Record<string, IdentifierRef[]>;
61
+ markParameterDependenciesFailed: CatalogReducer<{
62
+ payload: IdentifierRef[];
63
63
  type: string;
64
64
  }>;
65
65
  };
@@ -1 +1 @@
1
- {"version":3,"file":"catalogReducers.d.ts","sourceRoot":"","sources":["../../../../src/model/store/catalog/catalogReducers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AAErF,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,KAAK,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,oBAAoB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACpD,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjD,sBAAsB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACrD,CAAC;AAsBF;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC5C,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AA0EF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAW3B,CAAC"}
1
+ {"version":3,"file":"catalogReducers.d.ts","sourceRoot":"","sources":["../../../../src/model/store/catalog/catalogReducers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AAErF,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAErB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,kCAAkC,EACvC,KAAK,uBAAuB,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,KAAK,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,oBAAoB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACpD,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjD,sBAAsB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACrD,CAAC;AAsBF;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC5C,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAiFF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAW3B,CAAC"}