@gooddata/sdk-ui-dashboard 11.62.0-alpha.2 → 11.62.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/NOTICE +33 -610
  2. package/esm/__version.d.ts +1 -1
  3. package/esm/__version.js +1 -1
  4. package/esm/_staging/dashboard/dashboardFilterContext.d.ts.map +1 -1
  5. package/esm/_staging/dashboard/dashboardFilterContext.js +4 -2
  6. package/esm/_staging/dashboard/dashboardFilterContextValidation.js +1 -1
  7. package/esm/index.d.ts +5 -3
  8. package/esm/index.d.ts.map +1 -1
  9. package/esm/index.js +1 -1
  10. package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts +3 -2
  11. package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
  12. package/esm/model/commandHandlers/dashboard/common/filterViews.js +12 -6
  13. package/esm/model/commandHandlers/dashboard/common/stateInitializers.d.ts.map +1 -1
  14. package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +5 -6
  15. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
  16. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +1 -1
  17. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.d.ts.map +1 -1
  18. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.js +2 -0
  19. package/esm/model/commandHandlers/dashboard/resetDashboardHandler.d.ts.map +1 -1
  20. package/esm/model/commandHandlers/dashboard/resetDashboardHandler.js +3 -1
  21. package/esm/model/commandHandlers/dashboard/saveDashboardHandler.d.ts.map +1 -1
  22. package/esm/model/commandHandlers/dashboard/saveDashboardHandler.js +6 -5
  23. package/esm/model/commandHandlers/drill/drillToDashboardHandler.d.ts.map +1 -1
  24. package/esm/model/commandHandlers/drill/drillToDashboardHandler.js +4 -1
  25. package/esm/model/commandHandlers/drill/keyDriverAnalysisHandler.d.ts.map +1 -1
  26. package/esm/model/commandHandlers/drill/keyDriverAnalysisHandler.js +5 -3
  27. package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +21 -1
  28. package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts.map +1 -1
  29. package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +56 -54
  30. package/esm/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.d.ts.map +1 -1
  31. package/esm/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.js +17 -4
  32. package/esm/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.d.ts.map +1 -1
  33. package/esm/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.js +6 -1
  34. package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.d.ts.map +1 -1
  35. package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.js +188 -70
  36. package/esm/model/commandHandlers/filterContext/common.d.ts +14 -2
  37. package/esm/model/commandHandlers/filterContext/common.d.ts.map +1 -1
  38. package/esm/model/commandHandlers/filterContext/common.js +43 -6
  39. package/esm/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.d.ts.map +1 -1
  40. package/esm/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.js +13 -3
  41. package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterConditionHandler.d.ts.map +1 -1
  42. package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterConditionHandler.js +11 -2
  43. package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterDimensionalityHandler.d.ts.map +1 -1
  44. package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterDimensionalityHandler.js +3 -0
  45. package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts +10 -2
  46. package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts.map +1 -1
  47. package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.js +20 -3
  48. package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.d.ts.map +1 -1
  49. package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.js +21 -4
  50. package/esm/model/commandHandlers/tabs/createDashboardTabHandler.d.ts.map +1 -1
  51. package/esm/model/commandHandlers/tabs/createDashboardTabHandler.js +27 -3
  52. package/esm/model/commands/filters.d.ts +16 -1
  53. package/esm/model/commands/filters.d.ts.map +1 -1
  54. package/esm/model/commands/filters.js +4 -3
  55. package/esm/model/commands/parameters.d.ts +4 -3
  56. package/esm/model/commands/parameters.d.ts.map +1 -1
  57. package/esm/model/commands/parameters.js +3 -2
  58. package/esm/model/store/drill/drillSelectors.d.ts +6 -0
  59. package/esm/model/store/drill/drillSelectors.d.ts.map +1 -1
  60. package/esm/model/store/drill/drillSelectors.js +9 -0
  61. package/esm/model/store/filtering/dashboardFilterSelectors.d.ts +6 -1
  62. package/esm/model/store/filtering/dashboardFilterSelectors.d.ts.map +1 -1
  63. package/esm/model/store/filtering/dashboardFilterSelectors.js +21 -19
  64. package/esm/model/store/filtering/restrictedFilterUtils.d.ts +26 -1
  65. package/esm/model/store/filtering/restrictedFilterUtils.d.ts.map +1 -1
  66. package/esm/model/store/filtering/restrictedFilterUtils.js +74 -6
  67. package/esm/model/store/meta/metaSelectors.d.ts +6 -0
  68. package/esm/model/store/meta/metaSelectors.d.ts.map +1 -1
  69. package/esm/model/store/meta/metaSelectors.js +13 -3
  70. package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts +48 -0
  71. package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts.map +1 -1
  72. package/esm/model/store/tabs/filterContext/filterContextReducers.js +362 -102
  73. package/esm/model/store/tabs/filterContext/filterContextSelectors.d.ts +74 -1
  74. package/esm/model/store/tabs/filterContext/filterContextSelectors.d.ts.map +1 -1
  75. package/esm/model/store/tabs/filterContext/filterContextSelectors.js +27 -21
  76. package/esm/model/store/tabs/filterContext/filterSync.d.ts +101 -0
  77. package/esm/model/store/tabs/filterContext/filterSync.d.ts.map +1 -0
  78. package/esm/model/store/tabs/filterContext/filterSync.js +361 -0
  79. package/esm/model/store/tabs/index.d.ts +2 -0
  80. package/esm/model/store/tabs/index.d.ts.map +1 -1
  81. package/esm/model/store/tabs/parameters/parametersReducers.d.ts +5 -0
  82. package/esm/model/store/tabs/parameters/parametersReducers.d.ts.map +1 -1
  83. package/esm/model/store/tabs/parameters/parametersReducers.js +9 -5
  84. package/esm/model/store/tabs/tabsReducers.d.ts +6 -0
  85. package/esm/model/store/tabs/tabsReducers.d.ts.map +1 -1
  86. package/esm/model/store/tabs/tabsReducers.js +14 -6
  87. package/esm/model/store/tabs/tabsState.d.ts +10 -0
  88. package/esm/model/store/tabs/tabsState.d.ts.map +1 -1
  89. package/esm/model/store/tabs/tabsState.js +20 -0
  90. package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts +5 -3
  91. package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts.map +1 -1
  92. package/esm/model/store/unavailableObjects/copyBlockingReferences.js +9 -16
  93. package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts +0 -16
  94. package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts.map +1 -1
  95. package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.js +0 -18
  96. package/esm/model/utils/attributeFilterMatching.d.ts +38 -0
  97. package/esm/model/utils/attributeFilterMatching.d.ts.map +1 -0
  98. package/esm/model/utils/attributeFilterMatching.js +110 -0
  99. package/esm/model/utils/attributeFilterSelectionTypeCompatibility.d.ts.map +1 -0
  100. package/esm/presentation/automations/alerting/state/types.d.ts +2 -2
  101. package/esm/presentation/automations/alerting/state/types.d.ts.map +1 -1
  102. package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.d.ts.map +1 -1
  103. package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.js +7 -3
  104. package/esm/presentation/automations/contexts/AutomationsContext.d.ts +6 -2
  105. package/esm/presentation/automations/contexts/AutomationsContext.d.ts.map +1 -1
  106. package/esm/presentation/automations/scheduledEmail/state/types.d.ts +2 -2
  107. package/esm/presentation/automations/scheduledEmail/state/types.d.ts.map +1 -1
  108. package/esm/presentation/automations/scheduledEmail/types.d.ts +2 -2
  109. package/esm/presentation/automations/scheduledEmail/types.d.ts.map +1 -1
  110. package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts +11 -1
  111. package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts.map +1 -1
  112. package/esm/presentation/automations/shared/automationFilters/automationParameters.js +2 -0
  113. package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts +3 -3
  114. package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts.map +1 -1
  115. package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.js +3 -13
  116. package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.d.ts +1 -1
  117. package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.d.ts.map +1 -1
  118. package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.js +1 -1
  119. package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts.map +1 -1
  120. package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.js +1 -1
  121. package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts +2 -2
  122. package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts.map +1 -1
  123. package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts +6 -2
  124. package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts.map +1 -1
  125. package/esm/presentation/automations/shared/automationFilters/useAutomationFilters.d.ts.map +1 -1
  126. package/esm/presentation/automations/shared/automationFilters/useAutomationFilters.js +2 -2
  127. package/esm/presentation/automations/shared/automationFilters/utils.d.ts.map +1 -1
  128. package/esm/presentation/automations/shared/automationFilters/utils.js +8 -0
  129. package/esm/presentation/automations/shared/filters/conversions.d.ts +1 -1
  130. package/esm/presentation/automations/shared/filters/conversions.d.ts.map +1 -1
  131. package/esm/presentation/automations/shared/filters/conversions.js +5 -3
  132. package/esm/presentation/automations/shared/slots/types.d.ts +2 -2
  133. package/esm/presentation/automations/shared/slots/types.d.ts.map +1 -1
  134. package/esm/presentation/dashboardSettingsDialog/useDialogData.js +1 -1
  135. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.d.ts.map +1 -1
  136. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +1 -4
  137. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.d.ts +2 -11
  138. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.d.ts.map +1 -1
  139. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.js +17 -16
  140. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.d.ts +11 -0
  141. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.d.ts.map +1 -0
  142. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.js +7 -0
  143. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.d.ts +2 -11
  144. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.d.ts.map +1 -1
  145. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.js +0 -6
  146. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.d.ts +34 -0
  147. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.d.ts.map +1 -0
  148. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.js +41 -0
  149. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.d.ts.map +1 -1
  150. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.js +4 -17
  151. package/esm/presentation/filterBar/attributeFilter/useDependentDateFilters.d.ts.map +1 -1
  152. package/esm/presentation/filterBar/attributeFilter/useDependentDateFilters.js +4 -13
  153. package/esm/presentation/filterBar/attributeFilter/useParentFilters.d.ts.map +1 -1
  154. package/esm/presentation/filterBar/attributeFilter/useParentFilters.js +3 -10
  155. package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.d.ts.map +1 -1
  156. package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +0 -9
  157. package/esm/presentation/filterBar/filterBar/DefaultFilterBarItem.d.ts.map +1 -1
  158. package/esm/presentation/filterBar/filterBar/DefaultFilterBarItem.js +15 -3
  159. package/esm/presentation/filterBar/filterBar/hooks/useResetFiltersButton.d.ts.map +1 -1
  160. package/esm/presentation/filterBar/filterBar/hooks/useResetFiltersButton.js +4 -0
  161. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +8 -0
  162. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  163. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +8 -0
  164. package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts +2 -3
  165. package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts.map +1 -1
  166. package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.js +29 -133
  167. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.d.ts.map +1 -1
  168. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.js +1 -1
  169. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.d.ts.map +1 -1
  170. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.js +1 -1
  171. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceMeasureFilterToOption.d.ts.map +1 -1
  172. package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceMeasureFilterToOption.js +1 -1
  173. package/esm/sdk-ui-dashboard.d.ts +135 -13
  174. package/package.json +23 -23
  175. package/styles/css/main.css +4 -0
  176. package/styles/css/main.css.map +1 -1
  177. package/esm/model/commandHandlers/dashboard/common/attributeFilterSelectionTypeCompatibility.d.ts.map +0 -1
  178. /package/esm/model/{commandHandlers/dashboard/common → utils}/attributeFilterSelectionTypeCompatibility.d.ts +0 -0
  179. /package/esm/model/{commandHandlers/dashboard/common → utils}/attributeFilterSelectionTypeCompatibility.js +0 -0
@@ -14,7 +14,7 @@ import { dashboardSaved } from "../../events/dashboard.js";
14
14
  import { dispatchDashboardEvent } from "../../store/_infra/eventDispatcher.js";
15
15
  import { accessibleDashboardsActions } from "../../store/accessibleDashboards/index.js";
16
16
  import { selectBackendCapabilities } from "../../store/backendCapabilities/backendCapabilitiesSelectors.js";
17
- import { selectLocale } from "../../store/config/configSelectors.js";
17
+ import { selectIsAiMode, selectLocale } from "../../store/config/configSelectors.js";
18
18
  import { insightsActions } from "../../store/insights/index.js";
19
19
  import { selectDraftInsightsUsedOnDashboard, selectInsights, } from "../../store/insights/insightsSelectors.js";
20
20
  import { listedDashboardsActions } from "../../store/listedDashboards/index.js";
@@ -141,7 +141,7 @@ function saveDashboard(ctx, saveCtx) {
141
141
  return ctx.backend
142
142
  .workspace(ctx.workspace)
143
143
  .dashboards()
144
- .createDashboard(dashboardToSave, !ctx.config?.isAiMode)
144
+ .createDashboard(dashboardToSave, !saveCtx.isAiMode)
145
145
  .then((dashboard) => ({ dashboard, created: true }));
146
146
  }
147
147
  throw error;
@@ -259,7 +259,7 @@ function resolveProcessedTabs(tabs, rootFilterContext, layout, dateFilterConfig,
259
259
  * capability, this code should use either the selectBasicLayout (that strips any custom widgets) or
260
260
  * selectLayout (that keeps custom widgets).
261
261
  */
262
- function* createDashboardSaveContext(cmd, isNewDashboard) {
262
+ function* createDashboardSaveContext(cmd, isNewDashboard, isAiMode) {
263
263
  const persistedDashboard = yield select(selectPersistedDashboard);
264
264
  const dashboardDescriptor = yield select(selectDashboardDescriptor);
265
265
  const tabs = yield select(selectTabs);
@@ -337,6 +337,7 @@ function* createDashboardSaveContext(cmd, isNewDashboard) {
337
337
  const insights = yield select(selectInsights);
338
338
  return {
339
339
  cmd,
340
+ isAiMode,
340
341
  persistedDashboard,
341
342
  dashboardFromState,
342
343
  dashboardToSave: getDashboardWithSharing(dashboardWithDrillReferences(dashboardToSave, insights), capabilities.supportsAccessControl, isNewDashboard),
@@ -449,8 +450,8 @@ export function* saveDashboardHandler(ctx, cmd) {
449
450
  : [];
450
451
  const persistedDashboard = yield select(selectPersistedDashboard);
451
452
  const isNewDashboard = persistedDashboard === undefined;
452
- const isAiBuilder = ctx.config?.isAiMode;
453
- const saveCtx = yield call(createDashboardSaveContext, cmd, isNewDashboard);
453
+ const isAiBuilder = yield select(selectIsAiMode);
454
+ const saveCtx = yield call(createDashboardSaveContext, cmd, isNewDashboard, isAiBuilder);
454
455
  let result;
455
456
  if (isAiBuilder) {
456
457
  result = yield call(save, ctx, saveCtx, saveDashboard, "@@GDC.DASH.SAVE_BUILDED");
@@ -1 +1 @@
1
- {"version":3,"file":"drillToDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/drillToDashboardHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAiC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EACH,KAAK,kCAAkC,EAG1C,MAAM,uBAAuB,CAAC;AAkB/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAWnE,wBAAiB,uBAAuB,CACpC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,GACvB,YAAY,CAAC,kCAAkC,CAAC,CA+HlD"}
1
+ {"version":3,"file":"drillToDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/drillToDashboardHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAiC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EACH,KAAK,kCAAkC,EAG1C,MAAM,uBAAuB,CAAC;AAmB/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAWnE,wBAAiB,uBAAuB,CACpC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,GACvB,YAAY,CAAC,kCAAkC,CAAC,CAoIlD"}
@@ -8,6 +8,7 @@ import { drillToDashboardRequested, drillToDashboardResolved, } from "../../even
8
8
  import { generateFilterLocalIdentifier } from "../../store/_infra/generators.js";
9
9
  import { selectSupportsMultipleDateFilters } from "../../store/backendCapabilities/backendCapabilitiesSelectors.js";
10
10
  import { selectCatalogDateAttributes } from "../../store/catalog/catalogSelectors.js";
11
+ import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
11
12
  import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
12
13
  import { selectAttributeFilterConfigsDisplayAsLabelMap, selectAttributeFilterConfigsOverrides, } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
13
14
  import { selectFilterContextAttributeFilterItems, selectFilterContextDateFilter, selectFilterContextDraggableFilterItems, selectFilterContextMeasureValueFilters, } from "../../store/tabs/filterContext/filterContextSelectors.js";
@@ -40,7 +41,9 @@ export function* drillToDashboardHandler(ctx, cmd) {
40
41
  const allAttributeFilters = yield select(selectAllAttributeFilters);
41
42
  const allMeasureValueFilters = yield select(selectAllMeasureValueFilters);
42
43
  const allNonDateFilters = [...allAttributeFilters, ...allMeasureValueFilters];
43
- const dashboardFiltersToResolve = includeOtherDateFilters ? allDraggableFilters : allNonDateFilters;
44
+ const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
45
+ // a restricted filter is applied nowhere, so the target dashboard does not get it either
46
+ const dashboardFiltersToResolve = (includeOtherDateFilters ? allDraggableFilters : allNonDateFilters).filter((filter) => !restrictedLocalIdentifiers.has(dashboardFilterLocalIdentifier(filter) ?? ""));
44
47
  const widgetAwareFilters = isDrillingToSelf
45
48
  ? []
46
49
  : yield call(getWidgetAwareDashboardFilters, ctx, widget, dashboardFiltersToResolve);
@@ -1 +1 @@
1
- {"version":3,"file":"keyDriverAnalysisHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/keyDriverAnalysisHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,KAAK,mCAAmC,EAG3C,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,wBAAiB,wBAAwB,CACrC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,kBAAkB,GACxB,YAAY,CAAC,mCAAmC,CAAC,CA0HnD"}
1
+ {"version":3,"file":"keyDriverAnalysisHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/keyDriverAnalysisHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,KAAK,mCAAmC,EAG3C,MAAM,uBAAuB,CAAC;AAW/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,wBAAiB,wBAAwB,CACrC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,kBAAkB,GACxB,YAAY,CAAC,mCAAmC,CAAC,CA4HnD"}
@@ -5,7 +5,8 @@ import { keyDriverAnalysisRequested, keyDriverAnalysisResolved, } from "../../ev
5
5
  import { invalidArgumentsProvided } from "../../events/general.js";
6
6
  import { generateFilterLocalIdentifier } from "../../store/_infra/generators.js";
7
7
  import { selectCatalogDateAttributes } from "../../store/catalog/catalogSelectors.js";
8
- import { isDashboardFilterRestricted } from "../../store/filtering/restrictedFilterUtils.js";
8
+ import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
9
+ import { isDashboardFilterCopyRestricted, isDashboardFilterUsingRestrictedObject, } from "../../store/filtering/restrictedFilterUtils.js";
9
10
  import { selectWidgetByRef } from "../../store/tabs/layout/layoutSelectors.js";
10
11
  import { selectUnavailableObjects } from "../../store/unavailableObjects/unavailableObjectsSelectors.js";
11
12
  import { getAttributeFilters, removeIgnoredWidgetFilters } from "../../utils/widgetFilters.js";
@@ -55,14 +56,15 @@ export function* keyDriverAnalysisHandler(ctx, cmd) {
55
56
  });
56
57
  const widget = yield select(selectWidgetByRef(drillEvent.widgetRef));
57
58
  const unavailableObjects = yield select(selectUnavailableObjects);
58
- const executableFilters = availableFilters.filter((filter) => !isDashboardFilterRestricted(filter, unavailableObjects));
59
+ const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
60
+ const executableFilters = availableFilters.filter((filter) => !isDashboardFilterCopyRestricted(filter, restrictedLocalIdentifiers, unavailableObjects));
59
61
  const widgetFilters = removeIgnoredWidgetFilters(executableFilters, widget);
60
62
  // KDA defines its own date range — drop date filters. Keep attribute and measure value
61
63
  // filters so the change analysis respects the rest of the dashboard filter context.
62
64
  const attributeFilters = getAttributeFilters(widgetFilters);
63
65
  const measureValueFilters = widgetFilters.filter(isDashboardMeasureValueFilter);
64
66
  // the drill intersection brings its own attribute filters, which the check above did not see
65
- const filters = mergeFilters(intersectionFilters, attributeFilters).filter((filter) => !isDashboardFilterRestricted(filter, unavailableObjects));
67
+ const filters = mergeFilters(intersectionFilters, attributeFilters).filter((filter) => !isDashboardFilterUsingRestrictedObject(filter, unavailableObjects));
66
68
  return keyDriverAnalysisResolved(ctx, cmd.payload.drillDefinition, cmd.payload.drillEvent, {
67
69
  metric: {
68
70
  ...metric,
@@ -1,7 +1,9 @@
1
1
  import { type SagaIterator } from "redux-saga";
2
- import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type MeasureValueFilterCondition, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
2
+ import { type DashboardAttributeFilterItem, type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDashboardAttributeFilter, 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
+ import { selectAllCatalogDisplayFormsMap } from "../../store/catalog/catalogSelectors.js";
6
+ import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
5
7
  import { type DashboardContext } from "../../types/commonTypes.js";
6
8
  interface IDrillToUrlPlaceholderReplacement {
7
9
  toBeReplaced: string;
@@ -24,6 +26,24 @@ export declare function splitDFToLoadingAndMapping(attributesDisplayForms: IAttr
24
26
  }>;
25
27
  export declare function loadAttributeElementsForDrillIntersection(drillIntersectionElements: IDrillEventIntersectionElement[], attributesDisplayForms: IAttributeDisplayFormMetadataObject[], ctx: DashboardContext): SagaIterator<IDrillToUrlElement[]>;
26
28
  export declare function getAttributeIdentifiersReplacements(url: string, drillIntersectionElements: IDrillEventIntersectionElement[], ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
29
+ /**
30
+ * The filter a dashboard attribute filter placeholder names. A readable filter wins: a text filter with
31
+ * the placeholder's label, then a list filter with it, then a list filter displayed by it. A restricted
32
+ * filter matched in any of these ways is applied nowhere, so it filters nothing.
33
+ */
34
+ export type DashboardAttributeFilterPlaceholderMatch = {
35
+ type: "text";
36
+ filter: DashboardTextAttributeFilter;
37
+ } | {
38
+ type: "label";
39
+ filter: IDashboardAttributeFilter;
40
+ } | {
41
+ type: "displayAsLabel";
42
+ filter: IDashboardAttributeFilter;
43
+ } | {
44
+ type: "restricted";
45
+ };
46
+ export declare function findDashboardAttributeFilterPlaceholderMatch(ref: ObjRef, attributeFilters: DashboardAttributeFilterItem[], restrictedLocalIdentifiers: ReadonlySet<string>, catalogDisplayForms: ReturnType<typeof selectAllCatalogDisplayFormsMap>, attributeFilterConfigs: ReturnType<typeof selectAttributeFilterConfigsOverrides>): DashboardAttributeFilterPlaceholderMatch | undefined;
27
47
  export declare function getDashboardAttributeFilterReplacements(url: string, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
28
48
  export declare function getDashboardMeasureValueFilterReplacements(url: string): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
29
49
  export declare function getInsightMeasureValueFilterReplacements(url: string, widgetRef: ObjRef): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDrillToCustomUrl.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/resolveDrillToCustomUrl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolveDrillToCustomUrl.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/resolveDrillToCustomUrl.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,13 @@
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, dashboardFilterObjRef, filterAttributeElements, filterObjRef, insightFilters as insightDefinitionFilters, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isAttributeFilter, isComparisonCondition, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isIdentifierRef, isMeasureValueFilter, isNegativeAttributeFilter, isRangeCondition, isTextAttributeFilter, isUriRef, measureValueFilterConditions, measureValueFilterMeasure, } from "@gooddata/sdk-model";
5
+ import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemLocalIdentifier, dashboardFilterLocalIdentifier, dashboardMeasureValueFilterLocalIdentifier, filterAttributeElements, filterObjRef, insightFilters as insightDefinitionFilters, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isAttributeFilter, isComparisonCondition, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isIdentifierRef, isMeasureValueFilter, isNegativeAttributeFilter, isRangeCondition, isTextAttributeFilter, isUriRef, measureValueFilterConditions, measureValueFilterMeasure, } from "@gooddata/sdk-model";
6
6
  import { DRILL_TO_URL_PLACEHOLDER, displayFormPlaceholderRef, getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getDashboardMeasureValueFilterPlaceholdersFromUrl, getDrillUrlPlaceholderTypes, 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 { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
10
10
  import { selectEnableMeasureValueFilterKD } from "../../store/config/configSelectors.js";
11
+ import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
11
12
  import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
12
13
  import { selectDashboardId } from "../../store/meta/metaSelectors.js";
13
14
  import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
@@ -167,55 +168,51 @@ export function* getAttributeIdentifiersReplacements(url, drillIntersectionEleme
167
168
  };
168
169
  });
169
170
  }
170
- function* resolveDashboardAttributeFilterReplacement({ placeholder: toBeReplaced, ref }, attributeFilters, catalogDisplayForms, attributeFilterConfigs, ctx) {
171
- // Check for text filters (arbitrary/match) first — they use different value structures.
172
- const textFilter = attributeFilters.find((filter) => {
173
- if (!isDashboardTextAttributeFilter(filter)) {
174
- return false;
175
- }
171
+ export function findDashboardAttributeFilterPlaceholderMatch(ref, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs) {
172
+ const isReadable = (filter) => !restrictedLocalIdentifiers.has(dashboardFilterLocalIdentifier(filter) ?? "");
173
+ const hasLabel = (filter) => {
176
174
  const df = catalogDisplayForms.get(dashboardAttributeFilterItemDisplayForm(filter));
177
- return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
178
- });
179
- if (textFilter && isDashboardTextAttributeFilter(textFilter)) {
180
- const parsedFilter = stringifyTextFilterSelection(textFilter);
181
- const replacement = encodeParameterIfSet(parsedFilter);
182
- return {
183
- toBeReplaced,
184
- replacement: replacement,
185
- };
175
+ return !!df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
176
+ };
177
+ const isDisplayedByLabel = (filter) => attributeFilterConfigs.some((config) => config.localIdentifier === dashboardAttributeFilterItemLocalIdentifier(filter) &&
178
+ !!config.displayAsLabel &&
179
+ areObjRefsEqual(config.displayAsLabel, ref));
180
+ const textFilter = attributeFilters.find((filter) => isDashboardTextAttributeFilter(filter) && isReadable(filter) && hasLabel(filter));
181
+ if (textFilter) {
182
+ return { type: "text", filter: textFilter };
186
183
  }
187
- // Standard (element-based) attribute filters
188
- const standardFilters = attributeFilters.filter(isDashboardAttributeFilter);
189
- let usedFilter = standardFilters.find((filter) => {
190
- const df = catalogDisplayForms.get(filter.attributeFilter.displayForm);
191
- return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
192
- });
193
- let attributeElementsValues = [];
194
- if (usedFilter) {
195
- const elements = usedFilter?.attributeFilter.attributeElements;
196
- attributeElementsValues = isAttributeElementsByValue(elements)
197
- ? elements.values
198
- : (elements?.uris ?? []);
184
+ const labelFilter = attributeFilters.find((filter) => isDashboardAttributeFilter(filter) && isReadable(filter) && hasLabel(filter));
185
+ if (labelFilter) {
186
+ return { type: "label", filter: labelFilter };
199
187
  }
200
- else {
201
- const usedConfig = attributeFilterConfigs.find((config) => {
202
- return config.displayAsLabel && areObjRefsEqual(config.displayAsLabel, ref);
203
- });
204
- usedFilter = standardFilters.find((filter) => {
205
- return filter.attributeFilter.localIdentifier === usedConfig?.localIdentifier;
206
- });
207
- const elements = usedFilter?.attributeFilter.attributeElements;
208
- const primaryElementsValues = elements
209
- ? isAttributeElementsByValue(elements)
210
- ? elements.values
211
- : elements.uris
212
- : [];
213
- attributeElementsValues = yield call(loadSecondaryElementTitles, ref, primaryElementsValues, ctx);
188
+ const displayedFilter = attributeFilters.find((filter) => isDashboardAttributeFilter(filter) && isReadable(filter) && isDisplayedByLabel(filter));
189
+ if (displayedFilter) {
190
+ return { type: "displayAsLabel", filter: displayedFilter };
214
191
  }
215
- const isNegative = usedFilter?.attributeFilter.negativeSelection;
216
- const parsedFilter = usedFilter
217
- ? stringifyAttributeFilterSelection(attributeElementsValues, isNegative)
192
+ return attributeFilters.some((filter) => !isReadable(filter) && (hasLabel(filter) || isDisplayedByLabel(filter)))
193
+ ? { type: "restricted" }
218
194
  : undefined;
195
+ }
196
+ function* resolveDashboardAttributeFilterReplacement({ placeholder: toBeReplaced, ref }, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs, ctx) {
197
+ const match = findDashboardAttributeFilterPlaceholderMatch(ref, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs);
198
+ // a placeholder whose filter is missing from the dashboard stays unresolved, which rejects the drill
199
+ let parsedFilter;
200
+ if (match?.type === "text") {
201
+ parsedFilter = stringifyTextFilterSelection(match.filter);
202
+ }
203
+ else if (match?.type === "label") {
204
+ const elements = match.filter.attributeFilter.attributeElements;
205
+ parsedFilter = stringifyAttributeFilterSelection(isAttributeElementsByValue(elements) ? elements.values : elements.uris, match.filter.attributeFilter.negativeSelection);
206
+ }
207
+ else if (match?.type === "displayAsLabel") {
208
+ const elements = match.filter.attributeFilter.attributeElements;
209
+ const primaryElementsValues = isAttributeElementsByValue(elements) ? elements.values : elements.uris;
210
+ const elementTitles = yield call(loadSecondaryElementTitles, ref, primaryElementsValues, ctx);
211
+ parsedFilter = stringifyAttributeFilterSelection(elementTitles, match.filter.attributeFilter.negativeSelection);
212
+ }
213
+ else if (match?.type === "restricted") {
214
+ parsedFilter = stringifyAttributeFilterSelection([], true);
215
+ }
219
216
  const replacement = encodeParameterIfSet(parsedFilter);
220
217
  return {
221
218
  toBeReplaced,
@@ -228,17 +225,21 @@ export function* getDashboardAttributeFilterReplacements(url, ctx) {
228
225
  return [];
229
226
  }
230
227
  const attributeFilters = yield select(selectFilterContextAttributeFilterItems);
228
+ const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
231
229
  const catalogDisplayForms = yield select(selectAllCatalogDisplayFormsMap);
232
230
  const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverrides);
233
- return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, catalogDisplayForms, attributeFilterConfigs, ctx)));
231
+ return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs, ctx)));
234
232
  }
235
- function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, catalogMeasures) {
236
- const usedFilter = measureValueFilters.find((filter) => {
237
- const measureRef = dashboardFilterObjRef(filter);
238
- return dashboardMeasureValueFilterMatchesIdentifier(measureRef, identifier, catalogMeasures);
239
- });
240
- const parsedFilter = stringifyMeasureValueFilterCondition(usedFilter?.dashboardMeasureValueFilter.conditions);
241
- const replacement = usedFilter ? encodeParameterIfSet(parsedFilter) : undefined;
233
+ function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, restrictedLocalIdentifiers, catalogMeasures) {
234
+ const isPlaceholderFilter = (filter) => dashboardMeasureValueFilterMatchesIdentifier(filter.dashboardMeasureValueFilter.measure, identifier, catalogMeasures);
235
+ const usedFilter = measureValueFilters.find((filter) => !restrictedLocalIdentifiers.has(dashboardMeasureValueFilterLocalIdentifier(filter)) &&
236
+ isPlaceholderFilter(filter));
237
+ // A restricted filter is applied nowhere, so it filters nothing and resolves as "ALL". A
238
+ // placeholder whose filter is missing from the dashboard stays unresolved, which rejects the drill.
239
+ const parsedFilter = usedFilter || measureValueFilters.some(isPlaceholderFilter)
240
+ ? stringifyMeasureValueFilterCondition(usedFilter?.dashboardMeasureValueFilter.conditions)
241
+ : undefined;
242
+ const replacement = encodeParameterIfSet(parsedFilter);
242
243
  return {
243
244
  toBeReplaced,
244
245
  replacement: replacement,
@@ -250,8 +251,9 @@ export function* getDashboardMeasureValueFilterReplacements(url) {
250
251
  return [];
251
252
  }
252
253
  const measureValueFilters = yield select(selectFilterContextMeasureValueFilters);
254
+ const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
253
255
  const catalogMeasures = yield select(selectAllCatalogMeasuresMap);
254
- return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, catalogMeasures));
256
+ return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, restrictedLocalIdentifiers, catalogMeasures));
255
257
  }
256
258
  function resolveInsightMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters) {
257
259
  const usedFilter = measureValueFilters.find((filter) => {
@@ -1 +1 @@
1
- {"version":3,"file":"changeAttributeFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAiBnF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,wBAAiB,qCAAqC,CAClD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,8BAA8B,GACpC,YAAY,CAAC,IAAI,CAAC,CA4EpB"}
1
+ {"version":3,"file":"changeAttributeFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAmBnF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAStE,wBAAiB,qCAAqC,CAClD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,8BAA8B,GACpC,YAAY,CAAC,IAAI,CAAC,CA4FpB"}
@@ -1,14 +1,15 @@
1
- // (C) 2021-2025 GoodData Corporation
1
+ // (C) 2021-2026 GoodData Corporation
2
2
  import { all, call, put, select } from "redux-saga/effects";
3
3
  import { invariant } from "ts-invariant";
4
4
  import { attributeFilterSelectionChanged } from "../../../events/filters.js";
5
5
  import { invalidArgumentsProvided } from "../../../events/general.js";
6
6
  import { dispatchDashboardEvent } from "../../../store/_infra/eventDispatcher.js";
7
7
  import { selectEnableImmediateAttributeFilterDisplayAsLabelMigration, selectIsApplyFiltersAllAtOnceEnabledAndSet, } from "../../../store/config/configSelectors.js";
8
- import { selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
8
+ import { selectCrossFilteringFiltersLocalIdentifiersByTab, selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
9
+ import { selectEnablePersistentFiltersAcrossTabs } from "../../../store/meta/metaSelectors.js";
9
10
  import { selectAttributeFilterDescendants, selectFilterContextAttributeFilterByLocalId, } from "../../../store/tabs/filterContext/filterContextSelectors.js";
10
11
  import { tabsActions } from "../../../store/tabs/index.js";
11
- import { dispatchFilterContextChanged, resetCrossFiltering } from "../common.js";
12
+ import { captureFilterContextByTabSnapshot, dispatchFilterContextChanged, dispatchFilterContextChangedForMutatedTabs, resetCrossFiltering, } from "../common.js";
12
13
  export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
13
14
  const { elements, filterLocalId, selectionType, isWorkingSelectionChange, isResultOfMigration, isSelectionInvalid, } = cmd.payload;
14
15
  // validate filterLocalId
@@ -18,6 +19,9 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
18
19
  }
19
20
  const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
20
21
  const enableImmediateAttributeFilterDisplayAsLabelMigration = yield select(selectEnableImmediateAttributeFilterDisplayAsLabelMigration);
22
+ const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
23
+ const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
24
+ const filterContextSnapshot = yield call(captureFilterContextByTabSnapshot);
21
25
  yield put(tabsActions.updateAttributeFilterSelection({
22
26
  elements,
23
27
  filterLocalId,
@@ -26,6 +30,8 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
26
30
  enableImmediateAttributeFilterDisplayAsLabelMigration,
27
31
  isResultOfMigration,
28
32
  isSelectionInvalid,
33
+ crossFilteringLocalIdsByTab,
34
+ enablePersistentFiltersAcrossTabs,
29
35
  }));
30
36
  const changedFilter = yield select(selectFilterContextAttributeFilterByLocalId(cmd.payload.filterLocalId));
31
37
  invariant(changedFilter, "Inconsistent state in attributeFilterChangeSelectionCommandHandler");
@@ -38,6 +44,8 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
38
44
  },
39
45
  negativeSelection: true,
40
46
  isWorkingSelectionChange: isWorkingSelectionChange && isApplyAllAtOnceEnabledAndSet,
47
+ crossFilteringLocalIdsByTab,
48
+ enablePersistentFiltersAcrossTabs,
41
49
  }))));
42
50
  }
43
51
  const isCrossFiltering = yield select(selectIsCrossFiltering);
@@ -48,5 +56,10 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
48
56
  yield call(resetCrossFiltering, cmd);
49
57
  }
50
58
  yield dispatchDashboardEvent(attributeFilterSelectionChanged(ctx, changedFilter, cmd.correlationId));
51
- yield call(dispatchFilterContextChanged, ctx, cmd);
59
+ if (enablePersistentFiltersAcrossTabs) {
60
+ yield call(dispatchFilterContextChangedForMutatedTabs, ctx, cmd, filterContextSnapshot);
61
+ }
62
+ else {
63
+ yield call(dispatchFilterContextChanged, ctx, cmd);
64
+ }
52
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"replaceAttributeFilterItemSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;AAWxF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKtE,wBAAiB,0CAA0C,CACvD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,mCAAmC,GACzC,YAAY,CAAC,IAAI,CAAC,CAoDpB"}
1
+ {"version":3,"file":"replaceAttributeFilterItemSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;AAaxF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKtE,wBAAiB,0CAA0C,CACvD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,mCAAmC,GACzC,YAAY,CAAC,IAAI,CAAC,CA0DpB"}
@@ -5,7 +5,8 @@ import { attributeFilterItemSelectionReplaced } from "../../../events/filters.js
5
5
  import { invalidArgumentsProvided } from "../../../events/general.js";
6
6
  import { dispatchDashboardEvent } from "../../../store/_infra/eventDispatcher.js";
7
7
  import { selectIsApplyFiltersAllAtOnceEnabledAndSet } from "../../../store/config/configSelectors.js";
8
- import { selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
8
+ import { selectCrossFilteringFiltersLocalIdentifiersByTab, selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
9
+ import { selectEnablePersistentFiltersAcrossTabs } from "../../../store/meta/metaSelectors.js";
9
10
  import { selectFilterContextAttributeFilterItemByLocalId } from "../../../store/tabs/filterContext/filterContextSelectors.js";
10
11
  import { tabsActions } from "../../../store/tabs/index.js";
11
12
  import { dispatchFilterContextChanged, resetCrossFiltering } from "../common.js";
@@ -18,11 +19,15 @@ export function* replaceAttributeFilterItemSelectionHandler(ctx, cmd) {
18
19
  throw invalidArgumentsProvided(ctx, cmd, `Filter with filterLocalId ${filterLocalId} not found.`);
19
20
  }
20
21
  const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
22
+ const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
23
+ const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
21
24
  yield put(tabsActions.replaceAttributeFilterItem({
22
25
  filterLocalId,
23
26
  filter,
24
27
  isWorkingSelectionChange: isWorkingSelectionChange && isApplyAllAtOnceEnabledAndSet,
25
28
  isSelectionInvalid,
29
+ crossFilteringLocalIdsByTab,
30
+ enablePersistentFiltersAcrossTabs,
26
31
  }));
27
32
  // Ensure the new filter's displayForm is registered in the displayFormsMap.
28
33
  // This is needed for cross-type migration (e.g. text→list) where the new filter's
@@ -1 +1 @@
1
- {"version":3,"file":"changeFilterContextSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAwC/C,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAqC9E,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAoGnE,wBAAiB,mCAAmC,CAChD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,4BAA4B,GAClC,YAAY,CAAC,IAAI,CAAC,CA2LpB"}
1
+ {"version":3,"file":"changeFilterContextSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAyC/C,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAyC9E,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAyNnE,wBAAiB,mCAAmC,CAChD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,4BAA4B,GAClC,YAAY,CAAC,IAAI,CAAC,CA4OpB"}