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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/NOTICE +63 -115
  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 -6
  17. package/esm/model/store/config/configSelectors.js +0 -8
  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/types/commonTypes.d.ts +11 -2
  24. package/esm/model/utils/measureValueFilterUtils.d.ts +14 -0
  25. package/esm/model/utils/measureValueFilterUtils.js +21 -0
  26. package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.d.ts → DefaultAlertingDialog.d.ts} +1 -1
  27. package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.js → DefaultAlertingDialog.js} +6 -12
  28. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelect.js +43 -9
  29. package/esm/presentation/alerting/DefaultAlertingDialog/hooks/useSaveAlertToBackend.js +13 -25
  30. package/esm/presentation/alerting/types.d.ts +1 -72
  31. package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +1 -2
  32. package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.js +5 -5
  33. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProvider.js +1 -8
  34. package/esm/presentation/dashboard/DashboardHeader/ScheduledEmailDialogProvider.js +17 -8
  35. package/esm/presentation/dashboard/DashboardHeader/ShareDialogDashboardHeader.js +5 -2
  36. package/esm/presentation/dashboard/components/DashboardRenderer.js +2 -2
  37. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +97 -13
  38. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.d.ts +1 -1
  39. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.js +3 -3
  40. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts +3 -2
  41. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +17 -4
  42. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts +4 -2
  43. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +37 -4
  44. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.d.ts +4 -3
  45. package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.js +3 -4
  46. package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
  47. package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +4 -1
  48. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +2 -9
  49. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +2 -9
  50. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +2 -9
  51. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +2 -9
  52. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +2 -9
  53. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +2 -9
  54. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +4 -36
  55. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +4 -36
  56. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +2 -9
  57. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +2 -9
  58. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +2 -9
  59. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +2 -9
  60. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +2 -9
  61. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +2 -9
  62. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +2 -9
  63. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +2 -9
  64. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +2 -9
  65. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +2 -9
  66. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +2 -9
  67. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +2 -9
  68. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +2 -9
  69. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +2 -9
  70. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +2 -9
  71. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +2 -9
  72. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +2 -9
  73. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +2 -9
  74. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +2 -9
  75. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +2 -9
  76. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +2 -9
  77. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +2 -9
  78. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +2 -9
  79. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +2 -9
  80. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +2 -9
  81. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +2 -9
  82. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +2 -9
  83. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +2 -9
  84. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +2 -9
  85. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +2 -9
  86. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +2 -9
  87. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +2 -9
  88. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +2 -9
  89. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +2 -9
  90. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +2 -9
  91. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +2 -9
  92. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +2 -9
  93. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +2 -9
  94. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +2 -9
  95. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +2 -9
  96. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +2 -9
  97. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +2 -9
  98. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +2 -9
  99. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +2 -9
  100. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +26 -59
  101. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +2 -6
  102. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +22 -104
  103. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useSaveScheduledEmailToBackend.js +12 -33
  104. package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.d.ts +3 -0
  105. package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.js +46 -0
  106. package/esm/presentation/scheduledEmail/types.d.ts +1 -7
  107. package/esm/presentation/scheduledEmail/utils/filters.d.ts +2 -0
  108. package/esm/presentation/scheduledEmail/utils/filters.js +5 -0
  109. package/esm/presentation/shareDialog/DefaultShareDialog.d.ts +1 -1
  110. package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -2
  111. package/esm/presentation/shareDialog/types.d.ts +5 -1
  112. package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts +2 -2
  113. package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +36 -5
  114. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/EditAlert.js +2 -2
  115. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useInsightWidgetAlerting.js +3 -6
  116. package/esm/presentation/widget/insight/configuration/InsightAlerts.js +1 -9
  117. package/esm/sdk-ui-dashboard.d.ts +28 -240
  118. package/package.json +20 -20
  119. package/esm/model/react/filtering/shared.d.ts +0 -6
  120. package/esm/model/react/filtering/shared.js +0 -38
  121. package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.d.ts +0 -13
  122. package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.js +0 -54
  123. package/esm/model/react/filtering/useDashboardScheduledExportFilters.d.ts +0 -19
  124. package/esm/model/react/filtering/useDashboardScheduledExportFilters.js +0 -18
  125. package/esm/model/react/filtering/useScheduledExportFilters.d.ts +0 -26
  126. package/esm/model/react/filtering/useScheduledExportFilters.js +0 -23
  127. package/esm/model/react/filtering/useWidgetAlertFilters.d.ts +0 -33
  128. package/esm/model/react/filtering/useWidgetAlertFilters.js +0 -48
  129. package/esm/model/react/filtering/useWidgetScheduledExportFilters.d.ts +0 -33
  130. package/esm/model/react/filtering/useWidgetScheduledExportFilters.js +0 -48
  131. package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.d.ts +0 -4
  132. package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.js +0 -20
  133. package/esm/model/react/useDashboardAlertsOld.d.ts +0 -32
  134. package/esm/model/react/useDashboardAlertsOld.js +0 -141
  135. package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.d.ts +0 -5
  136. package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.js +0 -36
  137. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.d.ts +0 -17
  138. package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.js +0 -103
  139. package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.d.ts +0 -5
  140. package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.js +0 -53
  141. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.d.ts +0 -9
  142. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.js +0 -84
  143. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.d.ts +0 -11
  144. package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.js +0 -16
  145. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.d.ts +0 -1
  146. package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.js +0 -12
  147. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.d.ts +0 -29
  148. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.js +0 -61
  149. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.d.ts +0 -6
  150. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.js +0 -12
  151. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.d.ts +0 -17
  152. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.js +0 -68
  153. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.d.ts +0 -4
  154. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.js +0 -6
  155. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.d.ts +0 -15
  156. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.js +0 -42
  157. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.d.ts +0 -18
  158. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.js +0 -25
  159. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.d.ts +0 -2
  160. package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.js +0 -2
  161. package/esm/presentation/widget/insight/configuration/InsightAlertsOld.d.ts +0 -2
  162. package/esm/presentation/widget/insight/configuration/InsightAlertsOld.js +0 -43
@@ -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
  *
@@ -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
  *
@@ -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.
@@ -1,5 +1,5 @@
1
1
  import { type IAnalyticalBackend, type IDashboardReferences } from "@gooddata/sdk-backend-spi";
2
- import { type FilterContextItem, type IColorPalette, type IDashboard, type IDashboardLayout, type IDateFilterConfig, type IEntitlementDescriptor, type IInsight, type IMeasureValueFilter, type ISeparators, type ISettings, type Identifier, type ObjRef } from "@gooddata/sdk-model";
2
+ import { type FilterContextItem, type IColorPalette, type IDashboard, type IDashboardLayout, type IDashboardParameter, type IDateFilterConfig, type IEntitlementDescriptor, type IInsight, type IMeasureValueFilter, type ISeparators, type ISettings, type Identifier, type ObjRef } from "@gooddata/sdk-model";
3
3
  import { type ILocale } from "@gooddata/sdk-ui";
4
4
  import { type IDashboardFilter, type IMenuButtonItemsVisibility, type RenderMode } from "../../types.js";
5
5
  import { type ExtendedDashboardWidget } from "./layoutTypes.js";
@@ -112,6 +112,15 @@ export type DashboardConfig = {
112
112
  * Incompatible overrides/conversions will lead to a toast message with warning.
113
113
  */
114
114
  overrideDefaultFilters?: FilterContextItem[];
115
+ /**
116
+ * Override runtime values of dashboard parameters on the active tab.
117
+ *
118
+ * @remarks
119
+ * Each entry's `value` is applied as the parameter's `runtimeOverride` when its `ref` matches
120
+ * a parameter on the loaded dashboard. Refs that don't match are silently ignored.
121
+ * The override applies only to the active tab — other tabs keep their hydrated defaults.
122
+ */
123
+ overrideDefaultParameters?: IDashboardParameter[];
115
124
  /**
116
125
  * Override dashboard title.
117
126
  */
@@ -415,7 +424,7 @@ export interface IDashboardFocusObject {
415
424
  *
416
425
  * @public
417
426
  */
418
- export type ResolvedDashboardConfig = Omit<Required<DashboardConfig>, "mapboxToken" | "agGridToken" | "maxZoomLevel" | "exportId" | "exportType" | "exportMetadata" | "focusObject" | "slideConfig" | "references" | "entitlements" | "initialContent" | "executionTimestamp" | "overrideDefaultFilters" | "overrideTitle" | "hideWidgetTitles" | "workspaceDescriptor" | "evaluationFrequency" | "externalRecipient" | "openAutomationOnLoad" | "hideAddTabButton"> & DashboardConfig;
427
+ export type ResolvedDashboardConfig = Omit<Required<DashboardConfig>, "mapboxToken" | "agGridToken" | "maxZoomLevel" | "exportId" | "exportType" | "exportMetadata" | "focusObject" | "slideConfig" | "references" | "entitlements" | "initialContent" | "executionTimestamp" | "overrideDefaultFilters" | "overrideDefaultParameters" | "overrideTitle" | "hideWidgetTitles" | "workspaceDescriptor" | "evaluationFrequency" | "externalRecipient" | "openAutomationOnLoad" | "hideAddTabButton"> & DashboardConfig;
419
428
  /**
420
429
  *
421
430
  * @beta
@@ -0,0 +1,14 @@
1
+ import { type ICatalogMeasure, type ObjRef, type ObjRefInScope } from "@gooddata/sdk-model";
2
+ import { type ObjRefMap } from "../../_staging/metadata/objRefMap.js";
3
+ /**
4
+ * Matches a dashboard MVF measure reference against the identifier used in drill URL placeholders.
5
+ *
6
+ * @internal
7
+ */
8
+ export declare function dashboardMeasureValueFilterMatchesIdentifier(measureRef: ObjRef, identifier: string, catalogMeasures: ObjRefMap<ICatalogMeasure>): boolean;
9
+ /**
10
+ * Matches an insight MVF measure reference against the identifier used in drill URL placeholders.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function insightMeasureValueFilterMatchesIdentifier(measureRef: ObjRefInScope, identifier: string): boolean;
@@ -0,0 +1,21 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { areObjRefsEqual, idRef, objRefToString, } from "@gooddata/sdk-model";
3
+ /**
4
+ * Matches a dashboard MVF measure reference against the identifier used in drill URL placeholders.
5
+ *
6
+ * @internal
7
+ */
8
+ export function dashboardMeasureValueFilterMatchesIdentifier(measureRef, identifier, catalogMeasures) {
9
+ const catalogMeasure = catalogMeasures.get(measureRef);
10
+ return (catalogMeasure?.measure.id === identifier ||
11
+ objRefToString(measureRef) === identifier ||
12
+ areObjRefsEqual(measureRef, idRef(identifier, "measure")));
13
+ }
14
+ /**
15
+ * Matches an insight MVF measure reference against the identifier used in drill URL placeholders.
16
+ *
17
+ * @internal
18
+ */
19
+ export function insightMeasureValueFilterMatchesIdentifier(measureRef, identifier) {
20
+ return (objRefToString(measureRef) === identifier || areObjRefsEqual(measureRef, idRef(identifier, "measure")));
21
+ }
@@ -3,4 +3,4 @@ export declare function AlertingDialogRenderer({ alertToEdit, users, usersError,
3
3
  /**
4
4
  * @alpha
5
5
  */
6
- export declare function DefaultAlertingDialogNew(props: IAlertingDialogProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function DefaultAlertingDialog(props: IAlertingDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -6,7 +6,6 @@ import { FormattedMessage, defineMessage, useIntl } from "react-intl";
6
6
  import { ValidationContextStore, convertError, createInvalidDatapoint, createInvalidNode, useValidationContextValue, } from "@gooddata/sdk-ui";
7
7
  import { Button, ConfirmDialogBase, ContentDivider, Hyperlink, Message, Overlay, OverlayController, OverlayControllerProvider, ScrollablePanel, UiIcon, UiIconButton, UiTooltip, useId, } from "@gooddata/sdk-ui-kit";
8
8
  import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
9
- import { useEnableAlertingAutomationFilterContext } from "../../../model/react/useDashboardAlerting/useEnableAutomationFilterContext.js";
10
9
  import { selectEnableAlertOncePerInterval, selectEnableAnomalyDetectionAlert, selectEnableAutomationManagement, selectExternalRecipient, selectIsWhiteLabeled, selectLocale, } from "../../../model/store/config/configSelectors.js";
11
10
  import { selectMaxAutomationRecipients } from "../../../model/store/entitlements/entitlementsSelectors.js";
12
11
  import { selectCanUseAiAssistant } from "../../../model/store/permissions/permissionsSelectors.js";
@@ -59,7 +58,7 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
59
58
  onDeleteSuccess?.(alert);
60
59
  setAlertToDelete(null);
61
60
  };
62
- const { maxAutomationsRecipients, isExecutionTimestampMode, enableAutomationFilterContext } = useDefaultAlertingDialogData();
61
+ const { maxAutomationsRecipients, isExecutionTimestampMode } = useDefaultAlertingDialogData();
63
62
  const { editedAutomationFilters, setEditedAutomationFilters, availableFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, } = useAutomationFiltersSelect({
64
63
  automationToEdit: alertToEdit,
65
64
  widget,
@@ -80,7 +79,6 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
80
79
  automationToEdit: alertToEdit,
81
80
  widget,
82
81
  insight,
83
- enableAutomationFilterContext,
84
82
  });
85
83
  const [isApplyCurrentFiltersDialogOpen, setIsApplyCurrentFiltersDialogOpen] = useState(!isValid);
86
84
  const { isSavingAlert, handleCreateAlert, handleUpdateAlert } = useSaveAlertToBackend({
@@ -138,7 +136,7 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
138
136
  } })),
139
137
  };
140
138
  }, [widget, intl]);
141
- if (isApplyCurrentFiltersDialogOpen && enableAutomationFilterContext) {
139
+ if (isApplyCurrentFiltersDialogOpen) {
142
140
  return (_jsx(ApplyCurrentFiltersConfirmDialog, { automationType: "alert", onCancel: () => onCancel?.(), onEdit: () => {
143
141
  onApplyCurrentFilters();
144
142
  setIsApplyCurrentFiltersDialogOpen(false);
@@ -162,12 +160,10 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
162
160
  : undefined, initialFocus: dialogTitleRef, submitOnEnterKey: false, onCancel: onCancel, onSubmit: handleSaveAlert, headline: undefined, headerLeftButtonRenderer: () => (_jsx(AlertingDialogHeader, { title: editedAutomation?.title ?? "", onChange: onTitleChange, onCancel: onCancel, placeholder: intl.formatMessage({
163
161
  id: "dialogs.alert.title.placeholder",
164
162
  }), ref: dialogTitleRef, secondaryTitle: secondaryTitle, secondaryTitleIcon: secondaryTitleIcon, isSecondaryTitleVisible: isSecondaryTitleVisible ? isParentValid : undefined })), children: [
165
- _jsx("h2", { className: "sr-only", id: titleElementId, children: intl.formatMessage({ id: "dialogs.alert.accessibility.label.title" }) }), _jsxs(ScrollablePanel, { className: cx("gd-notifications-channel-dialog-content-wrapper", {
166
- "gd-notification-channel-dialog-with-automation-filters": enableAutomationFilterContext,
167
- }), children: [
168
- _jsx("div", { className: "gd-divider-with-margin" }), enableAutomationFilterContext ? (_jsxs(_Fragment, { children: [
163
+ _jsx("h2", { className: "sr-only", id: titleElementId, children: intl.formatMessage({ id: "dialogs.alert.accessibility.label.title" }) }), _jsxs(ScrollablePanel, { className: "gd-notifications-channel-dialog-content-wrapper gd-notification-channel-dialog-with-automation-filters", children: [
164
+ _jsx("div", { className: "gd-divider-with-margin" }), _jsxs(_Fragment, { children: [
169
165
  _jsx(AutomationFiltersSelect, { availableFilters: availableFilters, selectedFilters: editedAutomationFilters, onFiltersChange: onFiltersChange, storeFilters: true, onStoreFiltersChange: () => { }, isDashboardAutomation: false, overlayPositionType: OVERLAY_POSITION_TYPE, disableDateFilters: isAnomalyDetection(editedAutomation?.alert) }), _jsx(ContentDivider, { className: "gd-divider-with-margin" })
170
- ] })) : null, _jsxs(FormFieldGroup, { label: _jsx(FormattedMessage, { id: "insightAlert.config.when" }), children: [
166
+ ] }), _jsxs(FormFieldGroup, { label: _jsx(FormattedMessage, { id: "insightAlert.config.when" }), children: [
171
167
  _jsx(FormField, { label: intl.formatMessage({ id: "insightAlert.config.metric" }), htmlFor: "alert.measure", children: _jsx(AlertMeasureSelect, { selectedMeasure: selectedMeasure, onMeasureChange: onMeasureChange, measures: supportedMeasures, overlayPositionType: OVERLAY_POSITION_TYPE, id: "alert.measure", closeOnParentScroll: CLOSE_ON_PARENT_SCROLL }) }), Boolean(canManageAttributes) &&
172
168
  supportedAttributes.filter((a) => a.type === "attribute").length >
173
169
  0 && (_jsx(FormField, { label: _jsx(FormattedMessage, { id: "insightAlert.config.for" }), htmlFor: "alert.attribute", children: _jsx(AlertAttributeSelect, { id: "alert.attribute", selectedAttribute: selectedAttribute, selectedValue: selectedValue, onAttributeChange: onAttributeChange, attributes: supportedAttributes, catalogAttributes: catalogAttributes, catalogDateDatasets: catalogDateDatasets, getAttributeValues: getAttributeValues, isResultLoading: isResultLoading, showLabel: false, closeOnParentScroll: CLOSE_ON_PARENT_SCROLL }) })), _jsx(FormField, { label: _jsx(FormattedMessage, { id: "insightAlert.config.condition" }), htmlFor: "alert.condition", children: _jsx(AlertComparisonOperatorSelect, { id: "alert.condition", measure: selectedMeasure, enableAnomalyDetectionAlert: enableAnomalyDetectionAlert ? enableAiAssistant : false, selectedComparisonOperator: selectedComparisonOperator, selectedRelativeOperator: selectedRelativeOperator, selectedAiOperator: selectedAiOperator, onAnomalyDetectionChange: onAnomalyDetectionChange, onComparisonOperatorChange: onComparisonOperatorChange, onRelativeOperatorChange: onRelativeOperatorChange, overlayPositionType: OVERLAY_POSITION_TYPE, closeOnParentScroll: CLOSE_ON_PARENT_SCROLL }) }), !isAnomalyDetection(editedAutomation?.alert) && (_jsx(FormField, { label: _jsx(FormattedMessage, { id: "insightAlert.config.threshold" }), htmlFor: "alert.value", children: _jsx(AlertThresholdInput, { id: "alert.value", value: value, onChange: onChange, onBlur: onBlur, suffix: getValueSuffix(editedAutomation?.alert), errorMessage: thresholdErrorMessage }) })), isChangeOrDifferenceOperator(editedAutomation?.alert) && (_jsx(FormField, { label: _jsx(FormattedMessage, { id: "insightAlert.config.comparison" }), htmlFor: "alert.comparison", children: _jsx(AlertComparisonPeriodSelect, { id: "alert.comparison", measure: selectedMeasure, alert: editedAutomation, selectedComparison: selectedComparator?.comparator, onComparisonChange: (comparisonType) => {
@@ -195,7 +191,7 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
195
191
  /**
196
192
  * @alpha
197
193
  */
198
- export function DefaultAlertingDialogNew(props) {
194
+ export function DefaultAlertingDialog(props) {
199
195
  const { isLoading, onCancel, alertToEdit } = props;
200
196
  const locale = useDashboardSelector(selectLocale);
201
197
  if (isLoading) {
@@ -206,11 +202,9 @@ export function DefaultAlertingDialogNew(props) {
206
202
  function useDefaultAlertingDialogData() {
207
203
  const maxAutomationsRecipients = useDashboardSelector(selectMaxAutomationRecipients);
208
204
  const isExecutionTimestampMode = !!useDashboardSelector(selectExecutionTimestamp);
209
- const enableAutomationFilterContext = useEnableAlertingAutomationFilterContext();
210
205
  return {
211
206
  maxAutomationsRecipients,
212
207
  isExecutionTimestampMode,
213
- enableAutomationFilterContext,
214
208
  };
215
209
  }
216
210
  function AlertingDialogFooter({ isWhiteLabeled, helpTextId, alertToEdit, isSavingAlert, onDeleteClick, }) {
@@ -1,10 +1,10 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // (C) 2019-2026 GoodData Corporation
3
- import { useCallback, useMemo } from "react";
3
+ import { useCallback, useMemo, useState } from "react";
4
4
  import cx from "classnames";
5
5
  import { FormattedMessage, useIntl } from "react-intl";
6
6
  import { areObjRefsEqual, } from "@gooddata/sdk-model";
7
- import { Dropdown, DropdownButton, UiMenu, } from "@gooddata/sdk-ui-kit";
7
+ import { Dropdown, DropdownButton, InvertableSelectSearchBar, Item, Separator, UiMenu, } from "@gooddata/sdk-ui-kit";
8
8
  import { getSelectedCatalogAttribute, getSelectedCatalogAttributeValue } from "../utils/getters.js";
9
9
  const createInteractiveItem = (id, title, attribute, value, isSelected, subItems) => ({
10
10
  type: "interactive",
@@ -26,6 +26,34 @@ const createSeparator = (id) => ({
26
26
  function CustomStaticItem({ item: _item }) {
27
27
  return _jsx("div", { className: "gd-alert-attribute-select__dropdown-separator" });
28
28
  }
29
+ function AttributeValuesSearchContent({ attribute, values, isSelected, selectedAttributeValue, onAttributeChange, onClose, }) {
30
+ const intl = useIntl();
31
+ const [searchString, setSearchString] = useState("");
32
+ const filteredValues = useMemo(() => {
33
+ if (!searchString) {
34
+ return values;
35
+ }
36
+ const loweredSearch = searchString.toLowerCase();
37
+ return values.filter((item) => (item.title ?? item.name ?? "").toLowerCase().includes(loweredSearch));
38
+ }, [searchString, values]);
39
+ return (_jsxs("div", { className: cx("gd-alert-attribute-select__submenu-content", "s-alert-attribute-submenu-content"), children: [
40
+ _jsx("div", { children: _jsx(InvertableSelectSearchBar, { onSearch: setSearchString, searchString: searchString, searchPlaceholder: intl.formatMessage({
41
+ id: "attributesDropdown.placeholder",
42
+ }), className: "gd-alert-attribute-select__menu-item_search" }) }), _jsx(Item, { className: "gd-alert-attribute-select__menu-item_wrapper", checked: Boolean(isSelected && !selectedAttributeValue), onClick: (e) => {
43
+ onAttributeChange(attribute, undefined);
44
+ onClose();
45
+ e.preventDefault();
46
+ e.stopPropagation();
47
+ }, children: _jsxs("div", { className: "gd-alert-attribute-select__menu-item s-menu-alert-attribute-item-value", children: [intl.formatMessage({
48
+ id: "insightAlert.config.selectAttribute",
49
+ }), " ", "(", values.length, ")"] }) }), _jsx(Separator, {}), _jsx("div", { className: "gd-alert-attribute-select__menu-item__values", children: filteredValues.map((value, index) => (_jsx(Item, { checked: Boolean(isSelected && value.value === selectedAttributeValue?.value), className: "gd-alert-attribute-select__menu-item_wrapper", onClick: (e) => {
50
+ onAttributeChange(attribute, value);
51
+ onClose();
52
+ e.preventDefault();
53
+ e.stopPropagation();
54
+ }, children: _jsx("div", { className: "gd-alert-attribute-select__menu-item s-menu-alert-attribute-item-value", children: (value.title ?? value.name) || `(${intl.formatMessage({ id: "empty_value" })})` }) }, index))) })
55
+ ] }));
56
+ }
29
57
  export function AlertAttributeSelect({ id, selectedAttribute: selectedAttributeProp, getAttributeValues, isResultLoading, selectedValue, onAttributeChange, attributes, catalogAttributes, catalogDateDatasets, showLabel = true, closeOnParentScroll, }) {
30
58
  const intl = useIntl();
31
59
  const availableAttributes = useMemo(() => {
@@ -47,17 +75,22 @@ export function AlertAttributeSelect({ id, selectedAttribute: selectedAttributeP
47
75
  }
48
76
  const values = getAttributeValues(item);
49
77
  const hasDisplayForm = selectedAttribute?.displayForms.some((df) => areObjRefsEqual(df.ref, attribute.attribute.attribute.displayForm));
50
- // Create sub-items for attribute values
78
+ const isSelected = Boolean(hasDisplayForm);
79
+ if (values.length > 5) {
80
+ attributeItems.push({
81
+ type: "content",
82
+ id: `attribute-${item.id}`,
83
+ stringTitle: item.title || intl.formatMessage({ id: "empty_value" }),
84
+ data: undefined,
85
+ Component: ({ onClose }) => (_jsx(AttributeValuesSearchContent, { attribute: attribute, values: values, isSelected: isSelected, selectedAttributeValue: selectedAttributeValue, onAttributeChange: onAttributeChange, onClose: onClose })),
86
+ });
87
+ continue;
88
+ }
51
89
  const subItems = [
52
- // "All" option
53
90
  createInteractiveItem(`all-${item.id}`, `${accessibilityAriaLabel} (${values.length})`, attribute, undefined, Boolean(hasDisplayForm && !selectedAttributeValue)),
54
- // Separator after All option
55
91
  createSeparator(`separator-${item.id}`),
92
+ ...values.map((value) => createInteractiveItem(`value-${value.value}`, (value.title ?? value.name) || intl.formatMessage({ id: "empty_value" }), attribute, value, Boolean(hasDisplayForm && selectedAttributeValue?.value === value.value))),
56
93
  ];
57
- // Add individual value items
58
- for (const value of values) {
59
- subItems.push(createInteractiveItem(`value-${value.value}`, (value.title ?? value.name) || intl.formatMessage({ id: "empty_value" }), attribute, value, Boolean(hasDisplayForm && selectedAttributeValue?.value === value.value)));
60
- }
61
94
  // Check if any child is selected to determine parent selection state
62
95
  const hasSelectedChild = subItems.some((item) => item.type === "interactive" && "isSelected" in item && item.isSelected);
63
96
  // Create attribute item with submenu
@@ -81,6 +114,7 @@ export function AlertAttributeSelect({ id, selectedAttribute: selectedAttributeP
81
114
  catalogDateDatasets,
82
115
  getAttributeValues,
83
116
  intl,
117
+ onAttributeChange,
84
118
  selectedAttribute,
85
119
  selectedAttributeValue,
86
120
  ]);