@gooddata/sdk-ui-dashboard 11.36.0-alpha.3 → 11.36.0-alpha.7

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 (173) hide show
  1. package/NOTICE +74 -162
  2. package/esm/__version.d.ts +1 -1
  3. package/esm/__version.js +1 -1
  4. package/esm/index.d.ts +5 -13
  5. package/esm/index.js +2 -10
  6. package/esm/internal.d.ts +1 -1
  7. package/esm/model/commandHandlers/dashboard/common/filterViews.js +24 -1
  8. package/esm/model/commandHandlers/dashboard/common/parameterHydration.d.ts +7 -1
  9. package/esm/model/commandHandlers/dashboard/common/parameterHydration.js +16 -2
  10. package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +4 -2
  11. package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +7 -1
  12. package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +80 -4
  13. package/esm/model/commandHandlers/filterContext/filterViewHandler.js +10 -0
  14. package/esm/model/commandHandlers/filterContext/filterViewParameters.d.ts +7 -0
  15. package/esm/model/commandHandlers/filterContext/filterViewParameters.js +11 -0
  16. package/esm/model/store/config/configSelectors.d.ts +0 -12
  17. package/esm/model/store/config/configSelectors.js +2 -18
  18. package/esm/model/store/tabs/index.d.ts +4 -0
  19. package/esm/model/store/tabs/parameters/parametersReducers.d.ts +11 -1
  20. package/esm/model/store/tabs/parameters/parametersReducers.js +16 -8
  21. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +7 -0
  22. package/esm/model/store/tabs/parameters/parametersSelectors.js +17 -0
  23. package/esm/model/store/widgetDrills/widgetDrillSelectors.js +10 -18
  24. package/esm/model/types/commonTypes.d.ts +11 -2
  25. package/esm/model/utils/measureValueFilterUtils.d.ts +14 -0
  26. package/esm/model/utils/measureValueFilterUtils.js +21 -0
  27. package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.d.ts → DefaultAlertingDialog.d.ts} +1 -1
  28. package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.js → DefaultAlertingDialog.js} +6 -12
  29. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelect.js +43 -9
  30. package/esm/presentation/alerting/DefaultAlertingDialog/hooks/useSaveAlertToBackend.js +13 -25
  31. package/esm/presentation/alerting/DefaultAlertingDialog/utils/items.js +5 -2
  32. package/esm/presentation/alerting/types.d.ts +1 -72
  33. package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +1 -2
  34. package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.js +5 -5
  35. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProvider.js +1 -8
  36. package/esm/presentation/dashboard/DashboardHeader/ScheduledEmailDialogProvider.js +17 -8
  37. package/esm/presentation/dashboard/DashboardHeader/ShareDialogDashboardHeader.js +5 -2
  38. package/esm/presentation/dashboard/components/DashboardRenderer.js +2 -2
  39. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +97 -13
  40. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.d.ts +1 -1
  41. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.js +3 -3
  42. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts +3 -2
  43. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +17 -4
  44. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts +4 -2
  45. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +37 -4
  46. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.d.ts +4 -3
  47. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.js +3 -4
  48. package/esm/presentation/drill/DrillSelect/DrillSelectDropdown.js +1 -3
  49. package/esm/presentation/drill/hooks/useDrillSelectDropdownMenuItems.js +1 -5
  50. package/esm/presentation/export/DefaultDashboardExportVariables.js +5 -2
  51. package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts +2 -1
  52. package/esm/presentation/export/hooks/useDashboardRelatedFilters.js +9 -0
  53. package/esm/presentation/export/types.d.ts +2 -1
  54. package/esm/presentation/export/types.js +1 -1
  55. package/esm/presentation/export/useExportData.js +4 -0
  56. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
  57. package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +4 -1
  58. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -9
  59. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +3 -9
  60. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -9
  61. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +3 -9
  62. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -9
  63. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +4 -10
  64. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +4 -36
  65. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +4 -36
  66. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -9
  67. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +4 -10
  68. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -9
  69. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +4 -10
  70. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -9
  71. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +3 -9
  72. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -9
  73. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +3 -9
  74. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -9
  75. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +3 -9
  76. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -9
  77. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +3 -9
  78. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -9
  79. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +3 -9
  80. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -9
  81. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +3 -9
  82. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -9
  83. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +3 -9
  84. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -9
  85. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +3 -9
  86. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -9
  87. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +3 -9
  88. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -9
  89. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +3 -9
  90. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -9
  91. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +3 -9
  92. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -9
  93. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +3 -9
  94. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -9
  95. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +3 -9
  96. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -9
  97. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +3 -9
  98. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -9
  99. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +3 -9
  100. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -9
  101. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +3 -9
  102. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -9
  103. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +3 -9
  104. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -9
  105. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +3 -9
  106. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -9
  107. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +3 -9
  108. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -9
  109. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +3 -9
  110. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +26 -59
  111. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +2 -6
  112. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +22 -104
  113. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useSaveScheduledEmailToBackend.js +12 -33
  114. package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.d.ts +3 -0
  115. package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.js +46 -0
  116. package/esm/presentation/scheduledEmail/types.d.ts +1 -7
  117. package/esm/presentation/scheduledEmail/utils/filters.d.ts +2 -0
  118. package/esm/presentation/scheduledEmail/utils/filters.js +5 -0
  119. package/esm/presentation/shareDialog/DefaultShareDialog.d.ts +1 -1
  120. package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -2
  121. package/esm/presentation/shareDialog/types.d.ts +5 -1
  122. package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts +2 -2
  123. package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +36 -5
  124. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/EditAlert.js +2 -2
  125. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useInsightWidgetAlerting.js +3 -6
  126. package/esm/presentation/widget/insight/configuration/InsightAlerts.js +1 -9
  127. package/esm/presentation/widget/insight/configuration/InsightDrillConfigPanel/useInsightDrillConfigPanel.js +4 -10
  128. package/esm/sdk-ui-dashboard.d.ts +31 -249
  129. package/package.json +20 -20
  130. package/esm/model/react/filtering/shared.d.ts +0 -6
  131. package/esm/model/react/filtering/shared.js +0 -38
  132. package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.d.ts +0 -13
  133. package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.js +0 -54
  134. package/esm/model/react/filtering/useDashboardScheduledExportFilters.d.ts +0 -19
  135. package/esm/model/react/filtering/useDashboardScheduledExportFilters.js +0 -18
  136. package/esm/model/react/filtering/useScheduledExportFilters.d.ts +0 -26
  137. package/esm/model/react/filtering/useScheduledExportFilters.js +0 -23
  138. package/esm/model/react/filtering/useWidgetAlertFilters.d.ts +0 -33
  139. package/esm/model/react/filtering/useWidgetAlertFilters.js +0 -48
  140. package/esm/model/react/filtering/useWidgetScheduledExportFilters.d.ts +0 -33
  141. package/esm/model/react/filtering/useWidgetScheduledExportFilters.js +0 -48
  142. package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.d.ts +0 -4
  143. package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.js +0 -20
  144. package/esm/model/react/useDashboardAlertsOld.d.ts +0 -32
  145. package/esm/model/react/useDashboardAlertsOld.js +0 -141
  146. package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.d.ts +0 -5
  147. package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.js +0 -36
  148. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.d.ts +0 -17
  149. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.js +0 -103
  150. package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.d.ts +0 -5
  151. package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.js +0 -53
  152. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.d.ts +0 -9
  153. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.js +0 -84
  154. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.d.ts +0 -11
  155. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.js +0 -16
  156. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.d.ts +0 -1
  157. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.js +0 -12
  158. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.d.ts +0 -29
  159. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.js +0 -61
  160. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.d.ts +0 -6
  161. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.js +0 -12
  162. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.d.ts +0 -17
  163. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.js +0 -68
  164. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.d.ts +0 -4
  165. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.js +0 -6
  166. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.d.ts +0 -15
  167. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.js +0 -42
  168. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.d.ts +0 -18
  169. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.js +0 -25
  170. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.d.ts +0 -2
  171. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.js +0 -2
  172. package/esm/presentation/widget/insight/configuration/InsightAlertsOld.d.ts +0 -2
  173. package/esm/presentation/widget/insight/configuration/InsightAlertsOld.js +0 -43
@@ -306,15 +306,17 @@ export function applyDefaultFilterView(dashboard, filterViews, settings) {
306
306
  // Use tab-specific default, or fall back to legacy global default only for the first tab
307
307
  const isFirstTab = index === 0;
308
308
  const effectiveDefaultView = tabDefaultView ?? (isFirstTab ? legacyDefaultView : undefined);
309
+ const parameters = applyFilterViewParameterValues(tab.parameters, effectiveDefaultView?.parameters);
309
310
  if (effectiveDefaultView && tab.filterContext && isFilterContext(tab.filterContext)) {
310
311
  const { filterContext: updatedFilterContext, configUpdates } = changeFilterContextSelection(tab.filterContext, effectiveDefaultView.filterContext.filters, tab.attributeFilterConfigs);
311
312
  return {
312
313
  ...tab,
314
+ ...(parameters === undefined ? {} : { parameters }),
313
315
  filterContext: updatedFilterContext,
314
316
  attributeFilterConfigs: applyConfigUpdates(tab.attributeFilterConfigs, configUpdates),
315
317
  };
316
318
  }
317
- return tab;
319
+ return parameters === undefined ? tab : { ...tab, parameters };
318
320
  });
319
321
  return {
320
322
  ...dashboard,
@@ -329,7 +331,28 @@ export function applyDefaultFilterView(dashboard, filterViews, settings) {
329
331
  ...dashboard,
330
332
  filterContext: updatedFilterContext,
331
333
  attributeFilterConfigs: applyConfigUpdates(dashboard.attributeFilterConfigs, configUpdates),
334
+ parameters: applyFilterViewParameterValues(dashboard.parameters, defaultFilterView.parameters),
332
335
  };
333
336
  }
334
337
  return dashboard;
335
338
  }
339
+ /**
340
+ * Default filter views are applied before tab parameters are hydrated into runtime state.
341
+ * Copy captured filter view values into matching dashboard parameters so hydration initializes chips
342
+ * from the default view.
343
+ */
344
+ function applyFilterViewParameterValues(dashboardParameters, filterViewParameters) {
345
+ if (!dashboardParameters || !filterViewParameters || filterViewParameters.length === 0) {
346
+ return dashboardParameters;
347
+ }
348
+ return dashboardParameters.map((parameter) => {
349
+ const filterViewParameter = filterViewParameters.find((item) => areObjRefsEqual(item.ref, parameter.ref));
350
+ if (!filterViewParameter) {
351
+ return parameter;
352
+ }
353
+ if (filterViewParameter.value === undefined) {
354
+ return omit(parameter, ["value"]);
355
+ }
356
+ return { ...parameter, value: filterViewParameter.value };
357
+ });
358
+ }
@@ -17,5 +17,11 @@ export declare function hydrateParameterEntries(dashboardParameters: IDashboardP
17
17
  *
18
18
  * For legacy single-tab dashboards (no `tabs[]`), a synthetic tab with `DEFAULT_TAB_ID` is used
19
19
  * so the V1 root-level `parameters` migrate transparently.
20
+ *
21
+ * `activeTabOverride` patches `runtimeOverride` on its named tab for refs that match an entry;
22
+ * non-matching refs are silently ignored (see `overrideDefaultParameters` on DashboardConfig).
20
23
  */
21
- export declare function distributeParametersToTabs(tabs: IDashboardTab[] | undefined, rootParameters: IDashboardParameter[] | undefined, workspaceParameters: IParameterMetadataObject[]): Record<string, IDashboardParameterEntry[]>;
24
+ export declare function distributeParametersToTabs(tabs: IDashboardTab[] | undefined, rootParameters: IDashboardParameter[] | undefined, workspaceParameters: IParameterMetadataObject[], activeTabOverride?: {
25
+ tabId: string;
26
+ overrides: IDashboardParameter[];
27
+ }): Record<string, IDashboardParameterEntry[]>;
@@ -34,15 +34,29 @@ export function hydrateParameterEntries(dashboardParameters, workspaceParameters
34
34
  *
35
35
  * For legacy single-tab dashboards (no `tabs[]`), a synthetic tab with `DEFAULT_TAB_ID` is used
36
36
  * so the V1 root-level `parameters` migrate transparently.
37
+ *
38
+ * `activeTabOverride` patches `runtimeOverride` on its named tab for refs that match an entry;
39
+ * non-matching refs are silently ignored (see `overrideDefaultParameters` on DashboardConfig).
37
40
  */
38
- export function distributeParametersToTabs(tabs, rootParameters, workspaceParameters) {
41
+ export function distributeParametersToTabs(tabs, rootParameters, workspaceParameters, activeTabOverride) {
39
42
  const effectiveTabs = tabs ?? [
40
43
  { localIdentifier: DEFAULT_TAB_ID, title: "", parameters: rootParameters },
41
44
  ];
42
45
  const result = {};
43
46
  for (const tab of effectiveTabs) {
44
47
  const source = pickTabParametersSource(tab, effectiveTabs, rootParameters);
45
- result[tab.localIdentifier] = hydrateParameterEntries(source, workspaceParameters);
48
+ const entries = hydrateParameterEntries(source, workspaceParameters);
49
+ result[tab.localIdentifier] =
50
+ tab.localIdentifier === activeTabOverride?.tabId
51
+ ? applyRuntimeOverrides(entries, activeTabOverride.overrides)
52
+ : entries;
46
53
  }
47
54
  return result;
48
55
  }
56
+ function applyRuntimeOverrides(entries, overrides) {
57
+ const overrideByRef = new Map(overrides.map((o) => [objRefToString(o.ref), o.value]));
58
+ return entries.map((entry) => {
59
+ const key = objRefToString(entry.parameter.ref);
60
+ return overrideByRef.has(key) ? { ...entry, runtimeOverride: overrideByRef.get(key) } : entry;
61
+ });
62
+ }
@@ -394,8 +394,10 @@ export function* actionsToInitializeExistingDashboard(ctx, dashboard, insights,
394
394
  */
395
395
  const dashboardLayout = dashboardLayoutSanitize(customizedDashboard.layout ?? EmptyDashboardLayout, insights, settings);
396
396
  const screen = yield select(selectScreen);
397
- const parameterSourceDashboard = persistedDashboard ?? dashboard;
398
- const parametersByTab = distributeParametersToTabs(parameterSourceDashboard.tabs, parameterSourceDashboard.parameters, workspaceParameters);
397
+ const overrideDefaultParameters = ctx.config?.overrideDefaultParameters;
398
+ const parametersByTab = distributeParametersToTabs(dashboard.tabs, dashboard.parameters, workspaceParameters, overrideDefaultParameters
399
+ ? { tabId: effectiveActiveTabId, overrides: overrideDefaultParameters }
400
+ : undefined);
399
401
  // Process tabs with complete filterContext initialization for each tab
400
402
  let tabsAction = null;
401
403
  const validationResults = [];
@@ -1,5 +1,5 @@
1
1
  import { type SagaIterator } from "redux-saga";
2
- import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
2
+ import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type MeasureValueFilterCondition, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
3
3
  import { type IDrillEvent, type IDrillEventIntersectionElement } from "@gooddata/sdk-ui";
4
4
  import { type IDrillToCustomUrl } from "../../commands/drill.js";
5
5
  import { type DashboardContext } from "../../types/commonTypes.js";
@@ -22,6 +22,8 @@ export declare function loadAttributeElementsForDrillIntersection(drillIntersect
22
22
  export declare function getAttributeDisplayForms(projectId: string, objRefs: ObjRef[], ctx: DashboardContext): Promise<IAttributeDisplayFormMetadataObject[]>;
23
23
  export declare function getAttributeIdentifiersReplacements(url: string, drillIntersectionElements: IDrillEventIntersectionElement[], ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
24
24
  export declare function getDashboardAttributeFilterReplacements(url: string, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
25
+ export declare function getDashboardMeasureValueFilterReplacements(url: string): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
26
+ export declare function getInsightMeasureValueFilterReplacements(url: string, widgetRef: ObjRef): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
25
27
  export declare function getInsightAttributeFilterReplacements(url: string, widgetRef: ObjRef): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
26
28
  export declare function getInsightIdentifiersReplacements(customUrl: string, widgetRef: ObjRef, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
27
29
  export declare function resolveDrillToCustomUrl(drillConfig: IDrillToCustomUrlModel, widgetRef: ObjRef, event: IDrillEvent, ctx: DashboardContext, cmd: IDrillToCustomUrl): SagaIterator<string>;
@@ -29,4 +31,8 @@ export declare function resolveDrillToCustomUrl(drillConfig: IDrillToCustomUrlMo
29
31
  * @internal
30
32
  */
31
33
  export declare function stringifyTextFilterSelection(filter: DashboardTextAttributeFilter | TextAttributeFilter): string;
34
+ /**
35
+ * @internal
36
+ */
37
+ export declare function stringifyMeasureValueFilterCondition(conditions: MeasureValueFilterCondition[] | undefined): string;
32
38
  export {};
@@ -2,19 +2,21 @@
2
2
  import stringify from "json-stable-stringify";
3
3
  import { groupBy } from "lodash-es";
4
4
  import { all, call, select } from "redux-saga/effects";
5
- import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, filterAttributeElements, filterObjRef, idRef, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isNegativeAttributeFilter, isTextAttributeFilter, } from "@gooddata/sdk-model";
6
- import { getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getInsightAttributeFilterPlaceholdersFromUrl, } from "@gooddata/sdk-model/internal";
5
+ import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardFilterObjRef, filterAttributeElements, filterObjRef, idRef, insightFilters as insightDefinitionFilters, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isComparisonCondition, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isRangeCondition, isTextAttributeFilter, measureValueFilterConditions, measureValueFilterMeasure, } from "@gooddata/sdk-model";
6
+ import { getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getDashboardMeasureValueFilterPlaceholdersFromUrl, getInsightAttributeFilterPlaceholdersFromUrl, getInsightMeasureValueFilterPlaceholdersFromUrl, } from "@gooddata/sdk-model/internal";
7
7
  import { isDrillIntersectionAttributeItem, } from "@gooddata/sdk-ui";
8
8
  import { invalidArgumentsProvided } from "../../events/general.js";
9
9
  import { queryWidgetFilters } from "../../queries/widgets.js";
10
10
  import { query } from "../../store/_infra/queryCall.js";
11
- import { selectAllCatalogDisplayFormsMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
11
+ import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
12
+ import { selectEnableMeasureValueFilterKD } from "../../store/config/configSelectors.js";
12
13
  import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
13
14
  import { selectDashboardId } from "../../store/meta/metaSelectors.js";
14
15
  import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
15
- import { selectFilterContextAttributeFilterItems } from "../../store/tabs/filterContext/filterContextSelectors.js";
16
+ import { selectFilterContextAttributeFilterItems, selectFilterContextMeasureValueFilters, } from "../../store/tabs/filterContext/filterContextSelectors.js";
16
17
  import { selectAnalyticalWidgetByRef } from "../../store/tabs/layout/layoutSelectors.js";
17
18
  import { DRILL_TO_URL_PLACEHOLDER } from "../../types/drillTypes.js";
19
+ import { dashboardMeasureValueFilterMatchesIdentifier, insightMeasureValueFilterMatchesIdentifier, } from "../../utils/measureValueFilterUtils.js";
18
20
  import { getElementTitle, getElementsSecondaryTitles } from "./getElementTitle.js";
19
21
  export function* loadElementTitle(dfRef, dfIdentifier, attrElementUri, ctx) {
20
22
  const elementTitle = yield call(getElementTitle, ctx.workspace, dfRef, attrElementUri, ctx);
@@ -164,6 +166,49 @@ export function* getDashboardAttributeFilterReplacements(url, ctx) {
164
166
  const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverrides);
165
167
  return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, catalogDisplayForms, attributeFilterConfigs, ctx)));
166
168
  }
169
+ function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, catalogMeasures) {
170
+ const usedFilter = measureValueFilters.find((filter) => {
171
+ const measureRef = dashboardFilterObjRef(filter);
172
+ return dashboardMeasureValueFilterMatchesIdentifier(measureRef, identifier, catalogMeasures);
173
+ });
174
+ const parsedFilter = stringifyMeasureValueFilterCondition(usedFilter?.dashboardMeasureValueFilter.conditions);
175
+ const replacement = usedFilter ? encodeParameterIfSet(parsedFilter) : undefined;
176
+ return {
177
+ toBeReplaced,
178
+ replacement: replacement,
179
+ };
180
+ }
181
+ export function* getDashboardMeasureValueFilterReplacements(url) {
182
+ const measureValueFilterPlaceholders = getDashboardMeasureValueFilterPlaceholdersFromUrl(url);
183
+ if (measureValueFilterPlaceholders.length === 0) {
184
+ return [];
185
+ }
186
+ const measureValueFilters = yield select(selectFilterContextMeasureValueFilters);
187
+ const catalogMeasures = yield select(selectAllCatalogMeasuresMap);
188
+ return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, catalogMeasures));
189
+ }
190
+ function resolveInsightMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters) {
191
+ const usedFilter = measureValueFilters.find((filter) => {
192
+ const measureRef = measureValueFilterMeasure(filter);
193
+ return insightMeasureValueFilterMatchesIdentifier(measureRef, identifier);
194
+ });
195
+ const parsedFilter = stringifyMeasureValueFilterCondition(usedFilter ? measureValueFilterConditions(usedFilter) : undefined);
196
+ const replacement = usedFilter ? encodeParameterIfSet(parsedFilter) : undefined;
197
+ return {
198
+ toBeReplaced,
199
+ replacement: replacement,
200
+ };
201
+ }
202
+ export function* getInsightMeasureValueFilterReplacements(url, widgetRef) {
203
+ const measureValueFilterPlaceholders = getInsightMeasureValueFilterPlaceholdersFromUrl(url);
204
+ if (measureValueFilterPlaceholders.length === 0) {
205
+ return [];
206
+ }
207
+ const widget = yield select(selectAnalyticalWidgetByRef(widgetRef));
208
+ const insight = yield select(selectInsightByRef(widget.insight));
209
+ const measureValueFilters = insight ? insightDefinitionFilters(insight).filter(isMeasureValueFilter) : [];
210
+ return measureValueFilterPlaceholders.map((placeholder) => resolveInsightMeasureValueFilterReplacement(placeholder, measureValueFilters));
211
+ }
167
212
  export function* getInsightAttributeFilterReplacements(url, widgetRef) {
168
213
  const attributeFilterPlaceholders = getInsightAttributeFilterPlaceholdersFromUrl(url);
169
214
  if (attributeFilterPlaceholders.length === 0) {
@@ -224,10 +269,20 @@ export function* resolveDrillToCustomUrl(drillConfig, widgetRef, event, ctx, cmd
224
269
  const attributeIdentifiersReplacements = yield call(getAttributeIdentifiersReplacements, customUrl, event.drillContext.intersection, ctx);
225
270
  const dashboardAttributeFilterReplacements = yield call(getDashboardAttributeFilterReplacements, customUrl, ctx);
226
271
  const insightAttributeFilterReplacements = yield call(getInsightAttributeFilterReplacements, customUrl, widgetRef);
272
+ const dashboardMeasureValueFilterReplacements = yield call(getDashboardMeasureValueFilterReplacements, customUrl);
273
+ const enableMeasureValueFilterKD = yield select(selectEnableMeasureValueFilterKD);
274
+ const insightMeasureValueFilterReplacements = enableMeasureValueFilterKD
275
+ ? yield call(getInsightMeasureValueFilterReplacements, customUrl, widgetRef)
276
+ : getInsightMeasureValueFilterPlaceholdersFromUrl(customUrl).map(({ placeholder }) => ({
277
+ toBeReplaced: placeholder,
278
+ replacement: undefined,
279
+ }));
227
280
  const missingReplacement = [
228
281
  ...attributeIdentifiersReplacements,
229
282
  ...dashboardAttributeFilterReplacements,
230
283
  ...insightAttributeFilterReplacements,
284
+ ...dashboardMeasureValueFilterReplacements,
285
+ ...insightMeasureValueFilterReplacements,
231
286
  ].find(({ replacement }) => replacement === undefined);
232
287
  if (missingReplacement) {
233
288
  throw invalidArgumentsProvided(ctx, cmd, `Drill to custom URL unable to resolve missing parameter ${missingReplacement.toBeReplaced}`);
@@ -237,6 +292,8 @@ export function* resolveDrillToCustomUrl(drillConfig, widgetRef, event, ctx, cmd
237
292
  ...attributeIdentifiersReplacements,
238
293
  ...dashboardAttributeFilterReplacements,
239
294
  ...insightAttributeFilterReplacements,
295
+ ...dashboardMeasureValueFilterReplacements,
296
+ ...insightMeasureValueFilterReplacements,
240
297
  ...insightIdentifiersReplacements,
241
298
  ];
242
299
  return applyReplacements(customUrl, replacements);
@@ -265,3 +322,22 @@ function stringifyMatchFilterSelection(literal, operator, isNegative) {
265
322
  const prefix = isNegative ? `NOT_${operatorStr}` : operatorStr;
266
323
  return `${prefix}${stringify([literal])}`;
267
324
  }
325
+ /**
326
+ * @internal
327
+ */
328
+ export function stringifyMeasureValueFilterCondition(conditions) {
329
+ if (!conditions || conditions.length === 0) {
330
+ return "ALL";
331
+ }
332
+ return conditions
333
+ .map((condition) => {
334
+ if (isComparisonCondition(condition)) {
335
+ return `${condition.comparison.operator}(${condition.comparison.value})`;
336
+ }
337
+ if (isRangeCondition(condition)) {
338
+ return `${condition.range.operator}(${condition.range.from},${condition.range.to})`;
339
+ }
340
+ return "ALL";
341
+ })
342
+ .join("|");
343
+ }
@@ -4,6 +4,7 @@ import { areObjRefsEqual, isDashboardAttributeFilter, } from "@gooddata/sdk-mode
4
4
  import { defaultErrorHandler } from "@gooddata/sdk-ui";
5
5
  import { changeFilterContextSelectionByParams, reloadFilterViews, } from "../../commands/filters.js";
6
6
  import { filterViewApplicationFailed, filterViewApplicationSucceeded, filterViewCreationFailed, filterViewCreationSucceeded, filterViewDefaultStatusChangeFailed, filterViewDefaultStatusChangeSucceeded, filterViewDeletionFailed, filterViewDeletionSucceeded, } from "../../events/filters.js";
7
+ import { selectCatalogParameters } from "../../store/catalog/catalogSelectors.js";
7
8
  import { selectIsApplyFiltersAllAtOnceEnabledAndSet } from "../../store/config/configSelectors.js";
8
9
  import { selectCrossFilteringFiltersLocalIdentifiers } from "../../store/drill/drillSelectors.js";
9
10
  import { selectFilterViews } from "../../store/filterViews/filterViewsReducersSelectors.js";
@@ -11,9 +12,11 @@ import { filterViewsActions } from "../../store/filterViews/index.js";
11
12
  import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
12
13
  import { selectFilterContextDefinition, selectWorkingFilterContextDefinition, } from "../../store/tabs/filterContext/filterContextSelectors.js";
13
14
  import { tabsActions } from "../../store/tabs/index.js";
15
+ import { selectFilterViewParameters } from "../../store/tabs/parameters/parametersSelectors.js";
14
16
  import { selectActiveTabLocalIdentifier } from "../../store/tabs/tabsSelectors.js";
15
17
  import { loadFilterViews } from "../dashboard/initializeDashboardHandler/loadFilterViews.js";
16
18
  import { resetCrossFiltering } from "./common.js";
19
+ import { resolveFilterViewParameterValues } from "./filterViewParameters.js";
17
20
  function createFilterView(ctx, filterView) {
18
21
  return ctx.backend.workspace(ctx.workspace).dashboards().createFilterView(filterView);
19
22
  }
@@ -36,6 +39,7 @@ export function* saveFilterViewHandler(ctx, cmd) {
36
39
  !filter.attributeFilter.localIdentifier ||
37
40
  !virtualFilters.includes(filter.attributeFilter.localIdentifier)),
38
41
  };
42
+ const parameters = yield select(selectFilterViewParameters);
39
43
  const filterView = {
40
44
  name: cmd.payload.name,
41
45
  dashboard: ctx.dashboardRef,
@@ -43,6 +47,7 @@ export function* saveFilterViewHandler(ctx, cmd) {
43
47
  isDefault: cmd.payload.isDefault,
44
48
  // Include tabId if there's an active tab
45
49
  ...(activeTabLocalIdentifier ? { tabLocalIdentifier: activeTabLocalIdentifier } : {}),
50
+ ...(parameters ? { parameters } : {}),
46
51
  };
47
52
  try {
48
53
  const newFilterView = yield call(createFilterView, ctx, filterView);
@@ -91,6 +96,11 @@ export function* applyFilterViewHandler(ctx, cmd) {
91
96
  resetOthers: true,
92
97
  correlationId: cmd.correlationId,
93
98
  }));
99
+ if (filterView.parameters && filterView.parameters.length > 0) {
100
+ const workspaceParameters = yield select(selectCatalogParameters);
101
+ const values = resolveFilterViewParameterValues(filterView.parameters, workspaceParameters);
102
+ yield put(tabsActions.setParameterRuntimeValues({ values }));
103
+ }
94
104
  yield put(filterViewApplicationSucceeded(ctx, filterView, cmd.correlationId));
95
105
  }
96
106
  else {
@@ -0,0 +1,7 @@
1
+ import { type IDashboardParameter, type IParameterMetadataObject, type ObjRef } from "@gooddata/sdk-model";
2
+ interface IResolvedFilterViewParameter {
3
+ ref: ObjRef;
4
+ value: number | undefined;
5
+ }
6
+ export declare function resolveFilterViewParameterValues(parameters: ReadonlyArray<IDashboardParameter>, workspaceParameters: ReadonlyArray<IParameterMetadataObject>): IResolvedFilterViewParameter[];
7
+ export {};
@@ -0,0 +1,11 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { areObjRefsEqual, } from "@gooddata/sdk-model";
3
+ export function resolveFilterViewParameterValues(parameters, workspaceParameters) {
4
+ return parameters.map((parameter) => {
5
+ if (parameter.value !== undefined) {
6
+ return { ref: parameter.ref, value: parameter.value };
7
+ }
8
+ const workspaceParameter = workspaceParameters.find((item) => areObjRefsEqual(item.ref, parameter.ref));
9
+ return { ref: parameter.ref, value: workspaceParameter?.definition.defaultValue };
10
+ });
11
+ }
@@ -467,12 +467,6 @@ export declare const selectEnableExecutionCancelling: DashboardSelector<boolean>
467
467
  * @internal
468
468
  */
469
469
  export declare const selectEnableDashboardShareLink: DashboardSelector<boolean>;
470
- /**
471
- * Selector for the automation filter context feature flag
472
- *
473
- * @internal
474
- */
475
- export declare const selectEnableAutomationFilterContext: DashboardSelector<boolean>;
476
470
  /**
477
471
  * Selector for the date filter local identifiers feature flag
478
472
  *
@@ -563,12 +557,6 @@ export declare const selectEnableSnapshotExport: DashboardSelector<boolean>;
563
557
  * @internal
564
558
  */
565
559
  export declare const selectEnableAccessibilityMode: DashboardSelector<boolean>;
566
- /**
567
- * Returns whether implicit drill to url feature is enabled.
568
- *
569
- * @alpha
570
- */
571
- export declare const selectEnableImplicitDrillToUrl: DashboardSelector<boolean>;
572
560
  /**
573
561
  * Returns the timeout to use when polling for export results (in milliseconds).
574
562
  *
@@ -630,14 +630,6 @@ export const selectEnableExecutionCancelling = createSelector(selectConfig, (sta
630
630
  export const selectEnableDashboardShareLink = createSelector(selectConfig, (state) => {
631
631
  return Boolean(state.settings?.enableDashboardShareLink);
632
632
  });
633
- /**
634
- * Selector for the automation filter context feature flag
635
- *
636
- * @internal
637
- */
638
- export const selectEnableAutomationFilterContext = createSelector(selectConfig, (state) => {
639
- return Boolean(state.settings?.enableAutomationFilterContext);
640
- });
641
633
  /**
642
634
  * Selector for the date filter local identifiers feature flag
643
635
  *
@@ -758,14 +750,6 @@ export const selectEnableSnapshotExport = createSelector(selectConfig, (state) =
758
750
  export const selectEnableAccessibilityMode = createSelector(selectConfig, (state) => {
759
751
  return Boolean(state.settings?.enableAccessibilityMode);
760
752
  });
761
- /**
762
- * Returns whether implicit drill to url feature is enabled.
763
- *
764
- * @alpha
765
- */
766
- export const selectEnableImplicitDrillToUrl = createSelector(selectConfig, (state) => {
767
- return state.settings?.enableImplicitDrillToUrl ?? true;
768
- });
769
753
  /**
770
754
  * Returns the timeout to use when polling for export results (in milliseconds).
771
755
  *
@@ -784,8 +768,8 @@ export const selectExportResultPollingTimeout = createSelector(selectConfig, (st
784
768
  *
785
769
  * @alpha
786
770
  */
787
- export const selectEnableDrillToUrlByDefault = createSelector(selectConfig, selectEnableImplicitDrillToUrl, (state, enableImplicitDrillToUrl) => {
788
- return enableImplicitDrillToUrl ? (state.settings?.enableDrillToUrlByDefault ?? false) : false;
771
+ export const selectEnableDrillToUrlByDefault = createSelector(selectConfig, (state) => {
772
+ return state.settings?.enableDrillToUrlByDefault ?? false;
789
773
  });
790
774
  /**
791
775
  * Returns whether fiscal calendars feature flag is enabled.
@@ -575,6 +575,10 @@ export declare const tabsActions: import("@reduxjs/toolkit").CaseReducerActions<
575
575
  payload: import("./parameters/parametersReducers.js").ISetParameterRuntimeValuePayload;
576
576
  type: string;
577
577
  }) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
578
+ readonly setParameterRuntimeValues: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
579
+ payload: import("./parameters/parametersReducers.js").ISetParameterRuntimeValuesPayload;
580
+ type: string;
581
+ }) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
578
582
  readonly removeParameter: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
579
583
  payload: import("./parameters/parametersReducers.js").IRemoveParameterPayload;
580
584
  type: string;
@@ -17,7 +17,13 @@ export interface IAddParameterPayload {
17
17
  */
18
18
  export interface ISetParameterRuntimeValuePayload {
19
19
  ref: ObjRef;
20
- value: number;
20
+ value: number | undefined;
21
+ }
22
+ /**
23
+ * @alpha
24
+ */
25
+ export interface ISetParameterRuntimeValuesPayload {
26
+ values: ISetParameterRuntimeValuePayload[];
21
27
  }
22
28
  /**
23
29
  * @alpha
@@ -34,6 +40,10 @@ export declare const parametersReducers: {
34
40
  payload: ISetParameterRuntimeValuePayload;
35
41
  type: string;
36
42
  }>;
43
+ setParameterRuntimeValues: ParametersReducer<{
44
+ payload: ISetParameterRuntimeValuesPayload;
45
+ type: string;
46
+ }>;
37
47
  removeParameter: ParametersReducer<{
38
48
  payload: IRemoveParameterPayload;
39
49
  type: string;
@@ -20,14 +20,11 @@ const addParameter = (state, action) => {
20
20
  };
21
21
  };
22
22
  const setParameterRuntimeValue = (state, action) => {
23
- const activeTab = getActiveTab(state);
24
- if (!activeTab?.parameters) {
25
- return;
26
- }
27
- const { ref, value } = action.payload;
28
- const entry = activeTab.parameters.parameters.find((item) => areObjRefsEqual(item.parameter.ref, ref));
29
- if (entry) {
30
- entry.runtimeOverride = value;
23
+ setRuntimeOverride(state, action.payload);
24
+ };
25
+ const setParameterRuntimeValues = (state, action) => {
26
+ for (const entry of action.payload.values) {
27
+ setRuntimeOverride(state, entry);
31
28
  }
32
29
  };
33
30
  const removeParameter = (state, action) => {
@@ -39,8 +36,19 @@ const removeParameter = (state, action) => {
39
36
  parameters: activeTab.parameters.parameters.filter((entry) => !areObjRefsEqual(entry.parameter.ref, action.payload.ref)),
40
37
  };
41
38
  };
39
+ function setRuntimeOverride(state, { ref, value }) {
40
+ const activeTab = getActiveTab(state);
41
+ if (!activeTab?.parameters) {
42
+ return;
43
+ }
44
+ const entry = activeTab.parameters.parameters.find((item) => areObjRefsEqual(item.parameter.ref, ref));
45
+ if (entry && entry.runtimeOverride !== value) {
46
+ entry.runtimeOverride = value;
47
+ }
48
+ }
42
49
  export const parametersReducers = {
43
50
  addParameter,
44
51
  setParameterRuntimeValue,
52
+ setParameterRuntimeValues,
45
53
  removeParameter,
46
54
  };
@@ -20,6 +20,13 @@ export declare const selectActiveParameterRefKeys: DashboardSelector<ReadonlySet
20
20
  * @internal
21
21
  */
22
22
  export declare const selectDashboardParameterEntries: DashboardSelector<IDashboardParameterEntry[]>;
23
+ /**
24
+ * Returns the active tab's parameters in the shape persisted by a filter view.
25
+ * Runtime overrides become persisted `value`; existing parameter values are kept when no runtime value exists.
26
+ *
27
+ * @internal
28
+ */
29
+ export declare const selectFilterViewParameters: DashboardSelector<IDashboardParameter[] | undefined>;
23
30
  /**
24
31
  * Returns a selector that yields the entry held by the active tab for a given parameter ref,
25
32
  * or `undefined` if no such entry exists.
@@ -35,6 +35,23 @@ export const selectActiveParameterRefKeys = createSelector(selectDashboardParame
35
35
  * @internal
36
36
  */
37
37
  export const selectDashboardParameterEntries = createSelector(selectParametersState, (state) => state.parameters);
38
+ /**
39
+ * Returns the active tab's parameters in the shape persisted by a filter view.
40
+ * Runtime overrides become persisted `value`; existing parameter values are kept when no runtime value exists.
41
+ *
42
+ * @internal
43
+ */
44
+ export const selectFilterViewParameters = createSelector(selectDashboardParameterEntries, (entries) => {
45
+ if (entries.length === 0) {
46
+ return undefined;
47
+ }
48
+ return entries.map((entry) => {
49
+ if (entry.runtimeOverride === undefined) {
50
+ return entry.parameter;
51
+ }
52
+ return { ...entry.parameter, value: entry.runtimeOverride };
53
+ });
54
+ });
38
55
  /**
39
56
  * Returns a selector that yields the entry held by the active tab for a given parameter ref,
40
57
  * or `undefined` if no such entry exists.
@@ -10,7 +10,7 @@ import { createMemoizedSelector } from "../_infra/selectors.js";
10
10
  import { selectAccessibleDashboardsLoaded, selectAccessibleDashboardsMap, } from "../accessibleDashboards/accessibleDashboardsSelectors.js";
11
11
  import { selectBackendCapabilities, selectSupportsAttributeHierarchies, selectSupportsCrossFiltering, } from "../backendCapabilities/backendCapabilitiesSelectors.js";
12
12
  import { selectAllCatalogAttributeHierarchies, selectAllCatalogAttributesMap, selectAllCatalogDisplayFormsMap, selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectCatalogDateAttributes, selectCatalogIsLoaded, } from "../catalog/catalogSelectors.js";
13
- import { selectDisableDefaultDrills, selectEnableDrillToUrlByDefault, selectEnableImplicitDrillToUrl, selectEnableKDCrossFiltering, selectEnableKda, selectIsDisabledCrossFiltering, selectIsDisabledKda, selectIsEmbedded, } from "../config/configSelectors.js";
13
+ import { selectDisableDefaultDrills, selectEnableDrillToUrlByDefault, selectEnableKDCrossFiltering, selectEnableKda, selectIsDisabledCrossFiltering, selectIsDisabledKda, selectIsEmbedded, } from "../config/configSelectors.js";
14
14
  import { selectDrillableItems } from "../drill/drillSelectors.js";
15
15
  import { selectDrillTargetsByWidgetRef } from "../drillTargets/drillTargetsSelectors.js";
16
16
  import { selectInsightByWidgetRef, selectInsightsMap } from "../insights/insightsSelectors.js";
@@ -126,14 +126,11 @@ function getDrillDownDefinitionsWithPredicates(availableDrillAttributes, attribu
126
126
  });
127
127
  });
128
128
  }
129
- function getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithDisplayFormLink, ignoredDrillToUrlAttributes, enableImplicitDrillToUrl) {
129
+ function getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithDisplayFormLink, ignoredDrillToUrlAttributes) {
130
130
  const matchingAvailableDrillAttributes = availableDrillAttributes.filter((candidate) => {
131
131
  return attributesWithDisplayFormLink.some((attr) => areObjRefsEqual(attr.attribute.ref, candidate.attribute.attributeHeader.formOf.ref));
132
132
  });
133
133
  const filterIgnoredDrillToUrlAttributes = (targetAttribute) => {
134
- if (!enableImplicitDrillToUrl) {
135
- return true;
136
- }
137
134
  return !ignoredDrillToUrlAttributes?.some((ignoredAttributeRef) => areObjRefsEqual(targetAttribute.attribute.attributeHeader.ref, ignoredAttributeRef));
138
135
  };
139
136
  const mapDrillTargetToDefinition = (targetAttribute) => {
@@ -304,10 +301,7 @@ export const selectGlobalDrillsDownAttributeHierarchyByWidgetRef = createMemoize
304
301
  /**
305
302
  * @internal
306
303
  */
307
- export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectIgnoredDrillToUrlAttributesByWidgetRef(ref), selectInsightByWidgetRef(ref), selectAllCatalogDisplayFormsMap, selectAllCatalogAttributesMap, selectEnableDrillToUrlByDefault, selectEnableImplicitDrillToUrl, (availableDrillTargets, ignoredDrillToUrlAttributes, widgetInsight, allCatalogDisplayFormsMap, allCatalogAttributesMap, enableDrillToUrlByDefault, enableImplicitDrillToUrl) => {
308
- if (!enableImplicitDrillToUrl) {
309
- return [];
310
- }
304
+ export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectIgnoredDrillToUrlAttributesByWidgetRef(ref), selectInsightByWidgetRef(ref), selectAllCatalogDisplayFormsMap, selectAllCatalogAttributesMap, selectEnableDrillToUrlByDefault, (availableDrillTargets, ignoredDrillToUrlAttributes, widgetInsight, allCatalogDisplayFormsMap, allCatalogAttributesMap, enableDrillToUrlByDefault) => {
311
305
  const disableDrillIntoURL = widgetInsight?.insight?.properties?.["controls"]?.disableDrillIntoURL ??
312
306
  !enableDrillToUrlByDefault;
313
307
  if (disableDrillIntoURL) {
@@ -341,9 +335,9 @@ export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref
341
335
  /**
342
336
  * @internal
343
337
  */
344
- export const selectImplicitDrillsToUrlByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectAttributesWithDisplayFormLink, selectIgnoredDrillToUrlAttributesByWidgetRef(ref), selectEnableImplicitDrillToUrl, (availableDrillTargets, attributesWithLink, ignoredDrillToUrlAttributes, enableImplicitDrillToUrl) => {
338
+ export const selectImplicitDrillsToUrlByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectAttributesWithDisplayFormLink, selectIgnoredDrillToUrlAttributesByWidgetRef(ref), (availableDrillTargets, attributesWithLink, ignoredDrillToUrlAttributes) => {
345
339
  const availableDrillAttributes = availableDrillTargets?.availableDrillTargets?.attributes ?? [];
346
- return getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, ignoredDrillToUrlAttributes, enableImplicitDrillToUrl);
340
+ return getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, ignoredDrillToUrlAttributes);
347
341
  }));
348
342
  /**
349
343
  * @internal
@@ -433,9 +427,9 @@ const selectKeyDriverAnalysisPredicates = createMemoizedSelector((ref) => create
433
427
  /**
434
428
  * @internal
435
429
  */
436
- export const selectConfiguredAndImplicitDrillsByWidgetRef = createMemoizedSelector((ref) => createSelector(selectCatalogIsLoaded, selectAccessibleDashboardsLoaded, selectValidConfiguredDrillsByWidgetRef(ref), selectImplicitDrillsDownByWidgetRef(ref), selectImplicitDrillsToUrlByWidgetRef(ref), selectCrossFilteringByWidgetRef(ref), selectKdaByWidgetRef(ref), selectInsightByWidgetRef(ref), selectEnableDrillToUrlByDefault, selectEnableImplicitDrillToUrl, (catalogIsLoaded, accessibleDashboardsLoaded, configuredDrills, implicitDrillDownDrills, implicitDrillToUrlDrills, crossFiltering, keyDriverAnalysis, insight, enableDrillToUrlByDefault, enableImplicitDrillToUrl) => {
430
+ export const selectConfiguredAndImplicitDrillsByWidgetRef = createMemoizedSelector((ref) => createSelector(selectCatalogIsLoaded, selectAccessibleDashboardsLoaded, selectValidConfiguredDrillsByWidgetRef(ref), selectImplicitDrillsDownByWidgetRef(ref), selectImplicitDrillsToUrlByWidgetRef(ref), selectCrossFilteringByWidgetRef(ref), selectKdaByWidgetRef(ref), selectInsightByWidgetRef(ref), selectEnableDrillToUrlByDefault, (catalogIsLoaded, accessibleDashboardsLoaded, configuredDrills, implicitDrillDownDrills, implicitDrillToUrlDrills, crossFiltering, keyDriverAnalysis, insight, enableDrillToUrlByDefault) => {
437
431
  const disableDrillIntoURL = insight?.insight.properties["controls"]?.disableDrillIntoURL ?? !enableDrillToUrlByDefault;
438
- const isDrillToUrlDisabled = !enableImplicitDrillToUrl || disableDrillIntoURL;
432
+ const isDrillToUrlDisabled = disableDrillIntoURL;
439
433
  // disable drilling until all necessary items are loaded (catalog, dash list, ...)
440
434
  const drillActive = catalogIsLoaded && accessibleDashboardsLoaded;
441
435
  return drillActive
@@ -464,16 +458,14 @@ export const selectDrillableItemsByWidgetRef = createMemoizedSelector((ref) => c
464
458
  /**
465
459
  * @internal
466
460
  */
467
- export const selectImplicitDrillsByAvailableDrillTargets = createMemoizedSelector((availableDrillTargets, ignoredDrillDownHierarchies = [], disableDrillIntoURL) => createSelector(selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectAllCatalogAttributesMap, selectSupportsAttributeHierarchies, selectAllCatalogAttributeHierarchies, selectBackendCapabilities, selectEnableDrillToUrlByDefault, selectEnableImplicitDrillToUrl, (attributesWithLink, attributesWithHierarchyDescendants, allCatalogAttributesMap, isDrillDownEnabled, allCatalogHierarchies, backendCapabilities, enableDrillToUrlByDefault, enableImplicitDrillToUrl) => {
461
+ export const selectImplicitDrillsByAvailableDrillTargets = createMemoizedSelector((availableDrillTargets, ignoredDrillDownHierarchies = [], disableDrillIntoURL) => createSelector(selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectAllCatalogAttributesMap, selectSupportsAttributeHierarchies, selectAllCatalogAttributeHierarchies, selectBackendCapabilities, selectEnableDrillToUrlByDefault, (attributesWithLink, attributesWithHierarchyDescendants, allCatalogAttributesMap, isDrillDownEnabled, allCatalogHierarchies, backendCapabilities, enableDrillToUrlByDefault) => {
468
462
  const isDrillToUrlDisabled = disableDrillIntoURL ?? !enableDrillToUrlByDefault;
469
463
  const availableDrillAttributes = availableDrillTargets?.attributes ?? [];
470
464
  const drillDownDrills = isDrillDownEnabled
471
465
  ? getDrillDownDefinitionsWithPredicates(availableDrillAttributes, attributesWithHierarchyDescendants, allCatalogAttributesMap, allCatalogHierarchies, ignoredDrillDownHierarchies, backendCapabilities.supportsAttributeHierarchies)
472
466
  : [];
473
- const drillToUrlDrills = getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, [], enableImplicitDrillToUrl);
474
- return !enableImplicitDrillToUrl || isDrillToUrlDisabled
475
- ? drillDownDrills
476
- : [...drillDownDrills, ...drillToUrlDrills];
467
+ const drillToUrlDrills = getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, []);
468
+ return isDrillToUrlDisabled ? drillDownDrills : [...drillDownDrills, ...drillToUrlDrills];
477
469
  }));
478
470
  /**
479
471
  * @internal