@gooddata/sdk-ui-dashboard 11.48.0-alpha.1 → 11.48.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 (163) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/_staging/automation/index.d.ts +7 -9
  4. package/esm/_staging/automation/index.d.ts.map +1 -1
  5. package/esm/_staging/automation/index.js +22 -12
  6. package/esm/kdaDialog/composition/KdaAttributesDropdown.d.ts +15 -0
  7. package/esm/kdaDialog/composition/KdaAttributesDropdown.d.ts.map +1 -0
  8. package/esm/kdaDialog/composition/KdaAttributesDropdown.js +66 -0
  9. package/esm/kdaDialog/composition/KdaAttributesSelectItem.d.ts +14 -0
  10. package/esm/kdaDialog/composition/KdaAttributesSelectItem.d.ts.map +1 -0
  11. package/esm/kdaDialog/composition/KdaAttributesSelectItem.js +33 -0
  12. package/esm/kdaDialog/composition/KeyDriversFooter.d.ts.map +1 -1
  13. package/esm/kdaDialog/composition/KeyDriversFooter.js +24 -78
  14. package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.d.ts +15 -0
  15. package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.d.ts.map +1 -0
  16. package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.js +51 -0
  17. package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.d.ts +9 -0
  18. package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.d.ts.map +1 -0
  19. package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.js +45 -0
  20. package/esm/model/commandHandlers/scheduledEmail/automationParametersRestore.d.ts +10 -3
  21. package/esm/model/commandHandlers/scheduledEmail/automationParametersRestore.d.ts.map +1 -1
  22. package/esm/model/commandHandlers/scheduledEmail/automationParametersRestore.js +5 -4
  23. package/esm/model/commandHandlers/scheduledEmail/createScheduledEmailHandler.d.ts.map +1 -1
  24. package/esm/model/commandHandlers/scheduledEmail/createScheduledEmailHandler.js +11 -2
  25. package/esm/model/commandHandlers/scheduledEmail/csvRawExecutionDefinition.d.ts +9 -1
  26. package/esm/model/commandHandlers/scheduledEmail/csvRawExecutionDefinition.d.ts.map +1 -1
  27. package/esm/model/commandHandlers/scheduledEmail/csvRawExecutionDefinition.js +4 -4
  28. package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.d.ts.map +1 -1
  29. package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.js +9 -2
  30. package/esm/model/commandHandlers/scheduledEmail/saveScheduledEmailHandler.d.ts.map +1 -1
  31. package/esm/model/commandHandlers/scheduledEmail/saveScheduledEmailHandler.js +11 -2
  32. package/esm/model/commandHandlers/widgets/exportInsightWidgetHandler.d.ts.map +1 -1
  33. package/esm/model/commandHandlers/widgets/exportInsightWidgetHandler.js +47 -13
  34. package/esm/model/react/useExportTemplates.d.ts +7 -2
  35. package/esm/model/react/useExportTemplates.d.ts.map +1 -1
  36. package/esm/model/react/useExportTemplates.js +50 -6
  37. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts +1 -1
  38. package/esm/model/store/tabs/parameters/parametersHelpers.d.ts.map +1 -1
  39. package/esm/model/store/tabs/parameters/parametersHelpers.js +10 -11
  40. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +0 -20
  41. package/esm/model/store/tabs/parameters/parametersSelectors.d.ts.map +1 -1
  42. package/esm/model/store/tabs/parameters/parametersSelectors.js +8 -34
  43. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts +20 -0
  44. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts.map +1 -0
  45. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.js +16 -0
  46. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts +1 -1
  47. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map +1 -1
  48. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.js +12 -8
  49. package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.js +2 -2
  50. package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.test.js +1 -1
  51. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.js +2 -2
  52. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.test.js +1 -1
  53. package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts +20 -17
  54. package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts.map +1 -1
  55. package/esm/presentation/automations/shared/automationFilters/automationParameters.js +57 -40
  56. package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts +3 -3
  57. package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts.map +1 -1
  58. package/esm/presentation/automations/shared/automationFilters/components/AutomationParameter.d.ts +2 -2
  59. package/esm/presentation/automations/shared/automationFilters/components/AutomationParameter.d.ts.map +1 -1
  60. package/esm/presentation/automations/shared/automationFilters/components/AutomationParameter.js +3 -3
  61. package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts.map +1 -1
  62. package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.js +9 -5
  63. package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts +2 -2
  64. package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts.map +1 -1
  65. package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.js +13 -5
  66. package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts +3 -3
  67. package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts.map +1 -1
  68. package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.js +18 -10
  69. package/esm/presentation/automations/shared/automationFilters/useParameterAnnouncements.d.ts +2 -2
  70. package/esm/presentation/automations/shared/automationFilters/useParameterAnnouncements.d.ts.map +1 -1
  71. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/selectionMode/SelectionModeItem.js +1 -1
  72. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/selectionType/SelectionTypeItem.js +1 -1
  73. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +5 -1
  74. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
  75. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +5 -1
  76. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +5 -1
  77. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
  78. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +6 -2
  79. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +5 -1
  80. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
  81. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +5 -1
  82. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +13 -1
  83. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  84. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +17 -5
  85. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +5 -1
  86. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
  87. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +5 -1
  88. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +5 -1
  89. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
  90. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +6 -2
  91. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +5 -1
  92. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
  93. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +6 -2
  94. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +5 -1
  95. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
  96. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +6 -2
  97. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +5 -1
  98. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
  99. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +6 -2
  100. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +5 -1
  101. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
  102. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +5 -1
  103. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +5 -1
  104. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
  105. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +6 -2
  106. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +5 -1
  107. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
  108. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +6 -2
  109. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +5 -1
  110. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
  111. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +5 -1
  112. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +5 -1
  113. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
  114. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +5 -1
  115. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +5 -1
  116. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
  117. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +6 -2
  118. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +5 -1
  119. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
  120. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +6 -2
  121. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +5 -1
  122. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
  123. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +6 -2
  124. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +5 -1
  125. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
  126. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +6 -2
  127. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +5 -1
  128. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
  129. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +6 -2
  130. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +5 -1
  131. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
  132. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +5 -1
  133. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +5 -1
  134. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
  135. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +5 -1
  136. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +5 -1
  137. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
  138. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +5 -1
  139. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +5 -1
  140. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
  141. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +5 -1
  142. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +5 -1
  143. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
  144. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +5 -1
  145. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +5 -1
  146. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
  147. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +5 -1
  148. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +5 -1
  149. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
  150. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +5 -1
  151. package/esm/presentation/topBar/buttonBar/button/settingButton/DefaultSettingButton.d.ts +1 -1
  152. package/esm/presentation/topBar/buttonBar/button/settingButton/DefaultSettingButton.d.ts.map +1 -1
  153. package/esm/presentation/topBar/buttonBar/button/settingButton/DefaultSettingButton.js +6 -7
  154. package/esm/sdk-ui-dashboard.d.ts +1 -1
  155. package/package.json +21 -21
  156. package/styles/css/kdaDialog.css +30 -9
  157. package/styles/css/kdaDialog.css.map +1 -1
  158. package/styles/css/main.css +33 -22
  159. package/styles/css/main.css.map +1 -1
  160. package/styles/css/topBar.css +3 -13
  161. package/styles/css/topBar.css.map +1 -1
  162. package/styles/scss/kdaDialog.scss +30 -9
  163. package/styles/scss/topBar.scss +3 -15
@@ -1,4 +1,4 @@
1
- export declare const LIB_VERSION = "11.48.0-alpha.1";
1
+ export declare const LIB_VERSION = "11.48.0-alpha.3";
2
2
  export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
3
3
  export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
4
4
  //# sourceMappingURL=__version.d.ts.map
package/esm/__version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // (C) 2021 GoodData Corporation
2
2
  // DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
3
- export const LIB_VERSION = "11.48.0-alpha.1";
3
+ export const LIB_VERSION = "11.48.0-alpha.3";
4
4
  export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
5
5
  export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
@@ -1,4 +1,4 @@
1
- import { type FilterContextItem, type IAutomationMetadataObject, type IAutomationMetadataObjectDefinition, type IAutomationRecipient, type IDashboardExportParameter, type IExportDefinitionMetadataObject, type IExportDefinitionMetadataObjectDefinition, type IFilter, type IInsightParameterValue, type IUser, type IWorkspaceUser, type ParameterValue } from "@gooddata/sdk-model";
1
+ import { type FilterContextItem, type IAutomationMetadataObject, type IAutomationMetadataObjectDefinition, type IAutomationRecipient, type IDashboardExportParameter, type IExportDefinitionMetadataObject, type IExportDefinitionMetadataObjectDefinition, type IFilter, type IInsightParameterValue, type IUser, type IWorkspaceUser } from "@gooddata/sdk-model";
2
2
  export declare const isDashboardAutomation: (automation: IAutomationMetadataObject | IAutomationMetadataObjectDefinition | undefined) => boolean | undefined;
3
3
  export declare const isVisualisationAutomation: (automation: IAutomationMetadataObject | IAutomationMetadataObjectDefinition | undefined) => boolean | undefined;
4
4
  export declare const isCsvVisualizationAutomation: (automation: IAutomationMetadataObject | IAutomationMetadataObjectDefinition | undefined) => boolean | undefined;
@@ -26,15 +26,13 @@ export declare const getAutomationExportParametersByTab: (automation: IAutomatio
26
26
  export declare function setExportParametersByTab(automation: IAutomationMetadataObjectDefinition, parametersByTab: Record<string, IDashboardExportParameter[]> | undefined): IAutomationMetadataObjectDefinition;
27
27
  /**
28
28
  * Converts stored export parameter overrides ({@link IDashboardExportParameter}, value carried as a
29
- * string) to {@link IInsightParameterValue} runtime values. Non-finite values are dropped.
29
+ * string) to {@link IInsightParameterValue} runtime values. Each row carries its own type tag:
30
+ * NUMBER values are parsed (non-finite ones dropped), STRING values stay strings. STRING rows are
31
+ * dropped while `enableStringParameters` is off (a row persisted before the flag was turned off).
32
+ * Untagged rows predate the tag and are decoded as NUMBER; rows tagged with a type this version
33
+ * does not know (persisted by a newer one) are dropped.
30
34
  */
31
- export declare function exportParametersToValues(stored: IDashboardExportParameter[]): IInsightParameterValue[];
32
- /**
33
- * The parameter values the automation dialogs can carry: NUMBER only, until the interactions
34
- * slice (F1-2636…F1-2641) widens the automation model. The single home of that policy — delete
35
- * together with the automation seeding gates when the slice lands.
36
- */
37
- export declare function isAutomationSupportedParameterValue(value: ParameterValue): value is number;
35
+ export declare function exportParametersToValues(stored: IDashboardExportParameter[], isStringParametersEnabled: boolean): IInsightParameterValue[];
38
36
  export declare const getAutomationVisualizationFilters: (automation: IAutomationMetadataObject | IAutomationMetadataObjectDefinition | undefined) => {
39
37
  executionFilters: IFilter[] | undefined;
40
38
  filterContextItems: FilterContextItem[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_staging/automation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAE9B,KAAK,+BAA+B,EACpC,KAAK,yCAAyC,EAE9C,KAAK,OAAO,EACZ,KAAK,sBAAsB,EAC3B,KAAK,KAAK,EACV,KAAK,cAAc,EACnB,KAAK,cAAc,EAMtB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,qBAAqB,kHAUjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,kHAUrC,CAAC;AAEF,eAAO,MAAM,4BAA4B,kHAQxC,CAAC;AAEF,eAAO,MAAM,kCAAkC,wHAW9C,CAAC;AAEF,eAAO,MAAM,6BAA6B,kHAQzC,CAAC;AAEF,eAAO,MAAM,mCAAmC,wHAW/C,CAAC;AAEF,eAAO,MAAM,6BAA6B,8HAYzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kCAAkC,8IAY9C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,sJAW9C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,mCAAmC,EAC/C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,GACzE,mCAAmC,CA+BrC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,yBAAyB,EAAE,GAAG,sBAAsB,EAAE,CAQtG;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,MAAM,CAE1F;AAED,eAAO,MAAM,iCAAiC;;;CAuB7C,CAAC;AAEF,eAAO,MAAM,yBAAyB,oHAQrC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,mIAIxC,CAAC;AAOF,eAAO,MAAM,mBAAmB,8HAqB/B,CAAC;AAEF,eAAO,MAAM,uCAAuC,gEAOnD,CAAC;AAEF,eAAO,MAAM,iCAAiC,0DAe7C,CAAC;AAEF,eAAO,MAAM,gCAAgC,uCAO5C,CAAC;AAEF,eAAO,MAAM,6CAA6C,qDASzD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_staging/automation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAE9B,KAAK,+BAA+B,EACpC,KAAK,yCAAyC,EAE9C,KAAK,OAAO,EACZ,KAAK,sBAAsB,EAC3B,KAAK,KAAK,EACV,KAAK,cAAc,EAStB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,qBAAqB,kHAUjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,kHAUrC,CAAC;AAEF,eAAO,MAAM,4BAA4B,kHAQxC,CAAC;AAEF,eAAO,MAAM,kCAAkC,wHAW9C,CAAC;AAEF,eAAO,MAAM,6BAA6B,kHAQzC,CAAC;AAEF,eAAO,MAAM,mCAAmC,wHAW/C,CAAC;AAEF,eAAO,MAAM,6BAA6B,8HAYzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kCAAkC,8IAY9C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,sJAW9C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,mCAAmC,EAC/C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,GACzE,mCAAmC,CA+BrC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,yBAAyB,EAAE,EACnC,yBAAyB,EAAE,OAAO,GACnC,sBAAsB,EAAE,CAQ1B;AAqBD,eAAO,MAAM,iCAAiC;;;CAuB7C,CAAC;AAEF,eAAO,MAAM,yBAAyB,oHAQrC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,mIAIxC,CAAC;AAOF,eAAO,MAAM,mBAAmB,8HAqB/B,CAAC;AAEF,eAAO,MAAM,uCAAuC,gEAOnD,CAAC;AAEF,eAAO,MAAM,iCAAiC,0DAe7C,CAAC;AAEF,eAAO,MAAM,gCAAgC,uCAO5C,CAAC;AAEF,eAAO,MAAM,6CAA6C,qDASzD,CAAC"}
@@ -1,6 +1,6 @@
1
1
  // (C) 2024-2026 GoodData Corporation
2
2
  import { isEqual, omit, pick } from "lodash-es";
3
- import { idRef, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isFilter, isFilterContextItem, } from "@gooddata/sdk-model";
3
+ import { assertNever, idRef, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isFilter, isFilterContextItem, } from "@gooddata/sdk-model";
4
4
  export const isDashboardAutomation = (automation) => {
5
5
  if (!automation) {
6
6
  return false;
@@ -115,24 +115,34 @@ export function setExportParametersByTab(automation, parametersByTab) {
115
115
  }
116
116
  /**
117
117
  * Converts stored export parameter overrides ({@link IDashboardExportParameter}, value carried as a
118
- * string) to {@link IInsightParameterValue} runtime values. Non-finite values are dropped.
118
+ * string) to {@link IInsightParameterValue} runtime values. Each row carries its own type tag:
119
+ * NUMBER values are parsed (non-finite ones dropped), STRING values stay strings. STRING rows are
120
+ * dropped while `enableStringParameters` is off (a row persisted before the flag was turned off).
121
+ * Untagged rows predate the tag and are decoded as NUMBER; rows tagged with a type this version
122
+ * does not know (persisted by a newer one) are dropped.
119
123
  */
120
- export function exportParametersToValues(stored) {
124
+ export function exportParametersToValues(stored, isStringParametersEnabled) {
121
125
  return stored.reduce((acc, row) => {
122
- const value = Number(row.value);
123
- if (Number.isFinite(value)) {
126
+ const value = decodeExportParameterValue(row.parameterType, row.value, isStringParametersEnabled);
127
+ if (value !== undefined) {
124
128
  acc.push({ ref: idRef(row.id, "parameter"), value });
125
129
  }
126
130
  return acc;
127
131
  }, []);
128
132
  }
129
- /**
130
- * The parameter values the automation dialogs can carry: NUMBER only, until the interactions
131
- * slice (F1-2636…F1-2641) widens the automation model. The single home of that policy — delete
132
- * together with the automation seeding gates when the slice lands.
133
- */
134
- export function isAutomationSupportedParameterValue(value) {
135
- return typeof value === "number";
133
+ function decodeExportParameterValue(parameterType, wireValue, isStringParametersEnabled) {
134
+ const tag = parameterType ?? "NUMBER";
135
+ switch (tag) {
136
+ case "NUMBER": {
137
+ const parsed = Number(wireValue);
138
+ return Number.isFinite(parsed) ? parsed : undefined;
139
+ }
140
+ case "STRING":
141
+ return isStringParametersEnabled ? wireValue : undefined;
142
+ default:
143
+ assertNever(tag);
144
+ return undefined;
145
+ }
136
146
  }
137
147
  export const getAutomationVisualizationFilters = (automation) => {
138
148
  if (!automation) {
@@ -0,0 +1,15 @@
1
+ import { type ICatalogAttribute } from "@gooddata/sdk-model";
2
+ import { type IKdaItemGroup } from "../internalTypes.js";
3
+ export interface IKdaAttributesDropdownProps {
4
+ buttonLabel: string;
5
+ attributesCount: number;
6
+ validAttributes: ICatalogAttribute[];
7
+ initialAttributes: ICatalogAttribute[];
8
+ mapAttributes: Map<string, IKdaItemGroup | undefined>;
9
+ isSearchBarVisible: boolean;
10
+ onApply: (selected: ICatalogAttribute[]) => void;
11
+ onOpen: () => void;
12
+ onClose: () => void;
13
+ }
14
+ export declare function KdaAttributesDropdown({ buttonLabel, attributesCount, validAttributes, initialAttributes, mapAttributes, isSearchBarVisible, onApply, onOpen, onClose }: IKdaAttributesDropdownProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=KdaAttributesDropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KdaAttributesDropdown.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KdaAttributesDropdown.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAW7D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYzD,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;IACtD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EAClC,WAAW,EACX,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,MAAM,EACN,OAAO,EACV,EAAE,2BAA2B,2CA0K7B"}
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2025-2026 GoodData Corporation
3
+ import { useId } from "react";
4
+ import { FormattedMessage, useIntl } from "react-intl";
5
+ import { Dropdown, InvertableSelectSearchBar, InvertableSelectVirtualised, SeparatorLine, UiButton, useIdPrefixed, } from "@gooddata/sdk-ui-kit";
6
+ import { getAttributeKey, getAttributeTitle, useKdaAttributesSelection, } from "./hooks/useKdaAttributesSelection.js";
7
+ import { KdaAttributesSelectItem } from "./KdaAttributesSelectItem.js";
8
+ const ITEM_HEIGHT = 28;
9
+ const ALIGN_POINTS = [{ align: "tl bl" }];
10
+ export function KdaAttributesDropdown({ buttonLabel, attributesCount, validAttributes, initialAttributes, mapAttributes, isSearchBarVisible, onApply, onOpen, onClose, }) {
11
+ const intl = useIntl();
12
+ const labelKeyDriversId = useId();
13
+ const dropdownButtonId = useIdPrefixed("kda-attributes-dropdown-button");
14
+ const { searchString, setSearchString, selection, isInverted, filteredOptions, resolvedSelection, isApplyDisabled, onSelect, resetSelection, } = useKdaAttributesSelection(validAttributes, initialAttributes);
15
+ const popupLabel = intl.formatMessage({
16
+ id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel",
17
+ });
18
+ return (_jsx(Dropdown, { className: "gd-kda-attributes-dropdown", closeOnEscape: true, autofocusOnOpen: true, overlayPositionType: "sameAsTarget", alignPoints: ALIGN_POINTS, returnFocusTo: dropdownButtonId, onOpenStateChanged: (isOpen) => {
19
+ if (isOpen) {
20
+ resetSelection();
21
+ onOpen();
22
+ }
23
+ else {
24
+ onClose();
25
+ }
26
+ }, renderButton: ({ toggleDropdown, isOpen, buttonRef, dropdownId }) => (_jsx(UiButton, { id: dropdownButtonId, dataTestId: `${attributesCount}_attributes`, ref: buttonRef, variant: "tertiary", iconAfter: "settings", isSelected: isOpen, label: buttonLabel, onClick: toggleDropdown, accessibilityConfig: {
27
+ ariaHaspopup: "dialog",
28
+ ariaExpanded: isOpen,
29
+ ariaControls: isOpen ? dropdownId : undefined,
30
+ } })), renderBody: ({ closeDropdown, ariaAttributes }) => {
31
+ const handleApply = () => {
32
+ onApply(resolvedSelection);
33
+ closeDropdown();
34
+ };
35
+ return (_jsxs("div", { ...ariaAttributes, "aria-labelledby": undefined, "aria-label": popupLabel, className: "gd-kda-attributes-dropdown__body", children: [
36
+ _jsx("div", { className: "gd-kda-attributes-dropdown__header", children: popupLabel }), _jsx(InvertableSelectVirtualised, { className: "gd-kda-attributes-select", adaptiveWidth: true, items: filteredOptions, totalItemsCount: filteredOptions.length, itemHeight: ITEM_HEIGHT, getItemKey: getAttributeKey, getItemTitle: getAttributeTitle, isItemQuestionMarkEnabled: () => false, isInverted: isInverted, selectedItems: selection, canSubmitOnKeyDown: !isApplyDisabled, onApplyButtonClick: handleApply, onSelect: onSelect, searchString: searchString, onSearch: setSearchString, renderItem: (itemProps) => {
37
+ const group = mapAttributes.get(itemProps.item.attribute.id);
38
+ const driverCount = group?.significantDrivers.length ?? 0;
39
+ const count = driverCount > 0 ? `(${driverCount})` : "-";
40
+ const countAriaLabel = driverCount > 0
41
+ ? intl.formatMessage({
42
+ id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.countLabel",
43
+ }, { count: driverCount })
44
+ : intl.formatMessage({
45
+ id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.noDrivers",
46
+ });
47
+ return (_jsx(KdaAttributesSelectItem, { ...itemProps, right: _jsx("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-label": countAriaLabel, children: count }) }));
48
+ }, renderSearchBar: isSearchBarVisible
49
+ ? ({ onSearch, searchString: search, searchPlaceholder }) => (_jsx(InvertableSelectSearchBar, { onSearch: onSearch, searchString: search, searchPlaceholder: searchPlaceholder, isSmall: true, onEscKeyPress: (e) => {
50
+ if (search) {
51
+ e.stopPropagation();
52
+ }
53
+ else {
54
+ closeDropdown();
55
+ }
56
+ } }))
57
+ : () => _jsx("div", { className: "gd-kda-attributes-dropdown__no-search" }), renderActions: () => (_jsxs("div", { className: "gd-kda-attributes-dropdown__subheader", children: [
58
+ _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__attribute", children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.attribute" }) }), _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__key_drivers", id: labelKeyDriversId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.drivers" }) })
59
+ ] })) }), _jsxs("div", { className: "gd-kda-attributes-dropdown__actions", children: [
60
+ _jsx(SeparatorLine, {}), _jsxs("div", { className: "gd-kda-attributes-dropdown__actions-buttons", children: [
61
+ _jsx(UiButton, { variant: "secondary", size: "small", onClick: closeDropdown, label: intl.formatMessage({ id: "gs.list.cancel" }) }), _jsx(UiButton, { variant: "primary", size: "small", isDisabled: isApplyDisabled, onClick: handleApply, label: intl.formatMessage({ id: "gs.list.apply" }) })
62
+ ] })
63
+ ] })
64
+ ] }));
65
+ } }));
66
+ }
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from "react";
2
+ export interface IKdaAttributesSelectItemProps<T> {
3
+ item: T;
4
+ title: string;
5
+ isSelected: boolean;
6
+ focusedAction?: string;
7
+ index?: number;
8
+ onSelect: () => void;
9
+ onDeselect: () => void;
10
+ onSelectOnly: () => void;
11
+ right?: ReactNode;
12
+ }
13
+ export declare function KdaAttributesSelectItem<T>({ item, title, isSelected, focusedAction, index, onSelect, onDeselect, onSelectOnly, right }: IKdaAttributesSelectItemProps<T>): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=KdaAttributesSelectItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KdaAttributesSelectItem.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KdaAttributesSelectItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AASrE,MAAM,WAAW,6BAA6B,CAAC,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,EACvC,IAAI,EACJ,KAAK,EACL,UAAU,EACV,aAAa,EACb,KAAK,EACL,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,EACR,EAAE,6BAA6B,CAAC,CAAC,CAAC,2CAkFlC"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2025-2026 GoodData Corporation
3
+ import { useCallback } from "react";
4
+ import cx from "classnames";
5
+ import { FormattedMessage, useIntl } from "react-intl";
6
+ import { SELECT_ITEM_ACTION, ScopedIdStore, UiLink } from "@gooddata/sdk-ui-kit";
7
+ const ONLY_ACTION = "only";
8
+ export function KdaAttributesSelectItem({ item, title, isSelected, focusedAction, index, onSelect, onDeselect, onSelectOnly, right, }) {
9
+ const intl = useIntl();
10
+ const makeId = ScopedIdStore.useContextStoreOptional((ctx) => ctx.makeId);
11
+ const onItemClick = useCallback(() => {
12
+ if (isSelected) {
13
+ onDeselect();
14
+ }
15
+ else {
16
+ onSelect();
17
+ }
18
+ }, [isSelected, onSelect, onDeselect]);
19
+ const onOnlyClick = useCallback((event) => {
20
+ event.stopPropagation();
21
+ onSelectOnly();
22
+ }, [onSelectOnly]);
23
+ const classes = cx("gd-kda-attributes-select-item", "gd-attribute-filter-elements-select-item__next", "gd-list-item", "has-only-visible", { "is-selected": isSelected }, {
24
+ "gd-attribute-filter-list-item--isFocused": !!focusedAction,
25
+ "gd-attribute-filter-list-item--isFocusedSelectItem": focusedAction === SELECT_ITEM_ACTION,
26
+ });
27
+ return (_jsxs("div", { className: classes, onClick: onItemClick, role: "row", tabIndex: -1, "aria-rowindex": index, "aria-label": title, children: [
28
+ _jsx("div", { role: "gridcell", className: "gd-attribute-filter-list-item-label", children: _jsxs("label", { className: "input-checkbox-label", children: [
29
+ _jsx("input", { tabIndex: focusedAction === SELECT_ITEM_ACTION ? 0 : -1, id: makeId?.({ item, specifier: SELECT_ITEM_ACTION }), type: "checkbox", className: "input-checkbox", readOnly: true, checked: isSelected }), _jsx("span", { className: "input-label-text", children: title })
30
+ ] }) }), _jsx("div", { className: cx("gd-list-item-only", {
31
+ "gd-list-item-only--isFocusedSelectItem": focusedAction === ONLY_ACTION,
32
+ }), role: "gridcell", children: _jsx(UiLink, { onClick: onOnlyClick, id: makeId?.({ item, specifier: ONLY_ACTION }), variant: "primary", flipUnderline: true, role: "button", "aria-label": intl.formatMessage({ id: "attributesDropdown.onlyLabel" }, { itemTitle: title }), tabIndex: focusedAction === ONLY_ACTION ? 0 : -1, children: _jsx(FormattedMessage, { id: "gs.list.only" }) }) }), right ? (_jsx("div", { role: "gridcell", className: "gd-kda-attributes-select-item__right", children: right })) : null] }));
33
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"KeyDriversFooter.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KeyDriversFooter.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,gBAAgB,mDAyM/B"}
1
+ {"version":3,"file":"KeyDriversFooter.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KeyDriversFooter.tsx"],"names":[],"mappings":"AAgBA,wBAAgB,gBAAgB,mDA2E/B"}
@@ -1,19 +1,16 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // (C) 2025-2026 GoodData Corporation
3
- import { useId, useMemo } from "react";
4
- import { FormattedMessage, useIntl } from "react-intl";
3
+ import { useCallback } from "react";
4
+ import { FormattedMessage } from "react-intl";
5
5
  import { areObjRefsEqual } from "@gooddata/sdk-model";
6
- import { DropdownInvertableSelect, InvertableSelectItem, UiButton, UiSkeleton } from "@gooddata/sdk-ui-kit";
6
+ import { UiSkeleton } from "@gooddata/sdk-ui-kit";
7
7
  import { useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
8
- import { selectCatalogAttributes, selectCatalogIsLoaded, } from "../../model/store/catalog/catalogSelectors.js";
9
- import { useSummaryDrivers } from "../hooks/useSummaryDrivers.js";
8
+ import { selectCatalogIsLoaded } from "../../model/store/catalog/catalogSelectors.js";
10
9
  import { useKdaState } from "../providers/KdaState.js";
10
+ import { useKdaValidAttributes } from "./hooks/useKdaValidAttributes.js";
11
+ import { KdaAttributesDropdown } from "./KdaAttributesDropdown.js";
11
12
  export function KeyDriversFooter() {
12
13
  const { state, setState } = useKdaState();
13
- const list = useSummaryDrivers();
14
- const intl = useIntl();
15
- const labelAttributeId = useId();
16
- const labelKeyDriversId = useId();
17
14
  const isCatalogLoaded = useDashboardSelector(selectCatalogIsLoaded);
18
15
  const isLoading = !isCatalogLoaded ||
19
16
  state.itemsStatus === "pending" ||
@@ -21,34 +18,22 @@ export function KeyDriversFooter() {
21
18
  state.relevantStatus === "pending" ||
22
19
  state.relevantStatus === "loading";
23
20
  const isError = state.itemsStatus === "error";
24
- const allAttributes = useDashboardSelector(selectCatalogAttributes);
25
- const { validAttributes, mapAttributes } = useMemo(() => {
26
- const mapAttributes = new Map();
27
- const validAttributes = allAttributes
28
- .filter((a) => {
29
- return state.relevantAttributes.some((attr) => areObjRefsEqual(attr, a.attribute.ref));
30
- })
31
- .map((a) => {
32
- const group = list.find((item) => a.displayForms.some((df) => areObjRefsEqual(df.ref, item.displayForm)));
33
- mapAttributes.set(a.attribute.ref, group);
34
- return [a, group];
35
- })
36
- .sort(([, a], [, b]) => {
37
- const aIndex = a ? list.indexOf(a) : Number.MAX_VALUE;
38
- const bIndex = b ? list.indexOf(b) : Number.MAX_VALUE;
39
- return aIndex - bIndex;
40
- })
41
- .map(([a]) => a);
42
- return { validAttributes, mapAttributes };
43
- }, [allAttributes, list, state.relevantAttributes]);
44
- const initialAttributes = useMemo(() => {
45
- return state.selectedAttributes
46
- .map((attr) => {
47
- return validAttributes.find((a) => a.displayForms.some((df) => areObjRefsEqual(df.ref, attr)));
48
- })
49
- .filter(Boolean);
50
- }, [state.selectedAttributes, validAttributes]);
51
- const isSearchBarVisible = validAttributes.length > 7;
21
+ const { validAttributes, mapAttributes, initialAttributes, isSearchBarVisible } = useKdaValidAttributes();
22
+ const onApply = useCallback((selected) => {
23
+ setState({
24
+ selectedAttributes: selected.map((item) => {
25
+ const existingRef = state.selectedAttributes.find((ref) => item.displayForms.some((df) => areObjRefsEqual(df.ref, ref)));
26
+ return existingRef ?? item.defaultDisplayForm.ref;
27
+ }),
28
+ selectedUpdated: Date.now(),
29
+ });
30
+ }, [setState, state.selectedAttributes]);
31
+ const onOpen = useCallback(() => {
32
+ setState({ attributesDropdownOpen: true });
33
+ }, [setState]);
34
+ const onClose = useCallback(() => {
35
+ setState({ attributesDropdownOpen: false });
36
+ }, [setState]);
52
37
  //Do not show footer when kda is not loaded at all
53
38
  if (isError) {
54
39
  return null;
@@ -60,46 +45,7 @@ export function KeyDriversFooter() {
60
45
  const buttonLabel = chunks
61
46
  .filter((chunk) => typeof chunk === "string")
62
47
  .join("");
63
- return (_jsx(DropdownInvertableSelect, { closeOnEscape: true, accessibilityConfig: {
64
- triggerRole: "button",
65
- popupRole: "dialog",
66
- popupLabel: intl.formatMessage({
67
- id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel",
68
- }),
69
- }, className: "gd-kda-attributes-dropdown", initialValue: initialAttributes, overlayPositionType: "sameAsTarget", initialIsInverted: false, options: validAttributes, onOpen: () => {
70
- setState({
71
- attributesDropdownOpen: true,
72
- });
73
- }, onClose: () => {
74
- setState({
75
- attributesDropdownOpen: false,
76
- });
77
- }, alignPoints: [{ align: "tl bl" }], getItemTitle: (item) => item.attribute.title, getItemKey: (item) => item.attribute.id, onChange: (selectedItems, isInverted) => {
78
- const selected = isInverted
79
- ? validAttributes.filter((a) => !selectedItems.includes(a))
80
- : selectedItems;
81
- setState({
82
- selectedAttributes: selected.map((item) => item.defaultDisplayForm.ref),
83
- selectedUpdated: Date.now(),
84
- });
85
- }, header: _jsx("div", { className: "gd-kda-attributes-dropdown__header", children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.attributes" }) }), renderSearchBar: isSearchBarVisible
86
- ? undefined
87
- : () => _jsx("div", { className: "gd-kda-attributes-dropdown__no-search" }), renderItem: (props) => (_jsx(InvertableSelectItem, { title: props.title, isSelected: props.isSelected, onClick: props.isSelected ? props.onDeselect : props.onSelect, onOnly: props.onSelectOnly, accessibilityConfig: {
88
- ariaLabelledBy: labelAttributeId,
89
- }, renderRight: () => {
90
- const group = mapAttributes.get(props.item.attribute.ref);
91
- if (!group || group.significantDrivers.length === 0) {
92
- return (_jsx("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-labelledby": labelKeyDriversId, children: "-" }));
93
- }
94
- return (_jsxs("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-labelledby": labelKeyDriversId, children: ["(", group.significantDrivers.length, ")"] }));
95
- } })), renderButton: ({ buttonRef, isOpen, toggleDropdown, accessibilityConfig, }) => (_jsx(UiButton, { ref: buttonRef, variant: "tertiary", iconAfter: "settings", isSelected: isOpen, label: buttonLabel, onClick: toggleDropdown, accessibilityConfig: {
96
- ...accessibilityConfig,
97
- ariaHaspopup: "dialog",
98
- } })), renderListActions: () => {
99
- return (_jsx(_Fragment, { children: _jsxs("div", { className: "gd-kda-attributes-dropdown__subheader", children: [
100
- _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__attribute", id: labelAttributeId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.attribute" }) }), _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__key_drivers", id: labelKeyDriversId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.drivers" }) })
101
- ] }) }));
102
- } }));
48
+ return (_jsx(KdaAttributesDropdown, { buttonLabel: buttonLabel, attributesCount: state.selectedAttributes.length, validAttributes: validAttributes, initialAttributes: initialAttributes, mapAttributes: mapAttributes, isSearchBarVisible: isSearchBarVisible, onApply: onApply, onOpen: onOpen, onClose: onClose }));
103
49
  },
104
50
  } })) }));
105
51
  }
@@ -0,0 +1,15 @@
1
+ import { type ICatalogAttribute } from "@gooddata/sdk-model";
2
+ export declare const getAttributeKey: (item: ICatalogAttribute) => string;
3
+ export declare const getAttributeTitle: (item: ICatalogAttribute) => string;
4
+ export declare function useKdaAttributesSelection(validAttributes: ICatalogAttribute[], initialAttributes: ICatalogAttribute[]): {
5
+ searchString: string;
6
+ setSearchString: import("react").Dispatch<import("react").SetStateAction<string>>;
7
+ selection: ICatalogAttribute[];
8
+ isInverted: boolean;
9
+ filteredOptions: ICatalogAttribute[];
10
+ resolvedSelection: ICatalogAttribute[];
11
+ isApplyDisabled: boolean;
12
+ onSelect: (selectedItems: ICatalogAttribute[], inverted: boolean) => void;
13
+ resetSelection: () => void;
14
+ };
15
+ //# sourceMappingURL=useKdaAttributesSelection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKdaAttributesSelection.d.ts","sourceRoot":"","sources":["../../../../src/kdaDialog/composition/hooks/useKdaAttributesSelection.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,eAAO,MAAM,eAAe,qCAAiD,CAAC;AAC9E,eAAO,MAAM,iBAAiB,qCAAoD,CAAC;AAEnF,wBAAgB,yBAAyB,CACrC,eAAe,EAAE,iBAAiB,EAAE,EACpC,iBAAiB,EAAE,iBAAiB,EAAE;;;;;;;;;;EAuDzC"}
@@ -0,0 +1,51 @@
1
+ // (C) 2025-2026 GoodData Corporation
2
+ import { useCallback, useMemo, useState } from "react";
3
+ export const getAttributeKey = (item) => item.attribute.id;
4
+ export const getAttributeTitle = (item) => item.attribute.title;
5
+ export function useKdaAttributesSelection(validAttributes, initialAttributes) {
6
+ const [searchString, setSearchString] = useState("");
7
+ const [selection, setSelection] = useState(initialAttributes);
8
+ const [isInverted, setIsInverted] = useState(false);
9
+ const resetSelection = useCallback(() => {
10
+ setSelection(initialAttributes);
11
+ setIsInverted(false);
12
+ setSearchString("");
13
+ }, [initialAttributes]);
14
+ const filteredOptions = useMemo(() => {
15
+ if (!searchString) {
16
+ return validAttributes;
17
+ }
18
+ const lowerSearch = searchString.toLowerCase();
19
+ return validAttributes.filter((option) => getAttributeTitle(option).toLowerCase().includes(lowerSearch));
20
+ }, [validAttributes, searchString]);
21
+ const resolvedSelection = useMemo(() => {
22
+ if (!isInverted) {
23
+ return selection;
24
+ }
25
+ const selectedIds = new Set(selection.map(getAttributeKey));
26
+ return validAttributes.filter((a) => !selectedIds.has(getAttributeKey(a)));
27
+ }, [isInverted, selection, validAttributes]);
28
+ const isApplyDisabled = useMemo(() => {
29
+ if (resolvedSelection.length === 0) {
30
+ return true;
31
+ }
32
+ const currentIds = new Set(resolvedSelection.map(getAttributeKey));
33
+ const committedIds = new Set(initialAttributes.map(getAttributeKey));
34
+ return currentIds.size === committedIds.size && [...currentIds].every((id) => committedIds.has(id));
35
+ }, [resolvedSelection, initialAttributes]);
36
+ const onSelect = useCallback((selectedItems, inverted) => {
37
+ setSelection(selectedItems);
38
+ setIsInverted(inverted);
39
+ }, []);
40
+ return {
41
+ searchString,
42
+ setSearchString,
43
+ selection,
44
+ isInverted,
45
+ filteredOptions,
46
+ resolvedSelection,
47
+ isApplyDisabled,
48
+ onSelect,
49
+ resetSelection,
50
+ };
51
+ }
@@ -0,0 +1,9 @@
1
+ import { type ICatalogAttribute } from "@gooddata/sdk-model";
2
+ import { type IKdaItemGroup } from "../../internalTypes.js";
3
+ export declare function useKdaValidAttributes(): {
4
+ validAttributes: ICatalogAttribute[];
5
+ mapAttributes: Map<string, IKdaItemGroup | undefined>;
6
+ initialAttributes: ICatalogAttribute[];
7
+ isSearchBarVisible: boolean;
8
+ };
9
+ //# sourceMappingURL=useKdaValidAttributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKdaValidAttributes.d.ts","sourceRoot":"","sources":["../../../../src/kdaDialog/composition/hooks/useKdaValidAttributes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;AAK9E,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D,wBAAgB,qBAAqB;;;;;EA4CpC"}
@@ -0,0 +1,45 @@
1
+ // (C) 2025-2026 GoodData Corporation
2
+ import { useMemo } from "react";
3
+ import { areObjRefsEqual } from "@gooddata/sdk-model";
4
+ import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
5
+ import { selectCatalogAttributes } from "../../../model/store/catalog/catalogSelectors.js";
6
+ import { useSummaryDrivers } from "../../hooks/useSummaryDrivers.js";
7
+ import { useKdaState } from "../../providers/KdaState.js";
8
+ const SEARCH_BAR_THRESHOLD = 7;
9
+ export function useKdaValidAttributes() {
10
+ const { state } = useKdaState();
11
+ const list = useSummaryDrivers();
12
+ const allAttributes = useDashboardSelector(selectCatalogAttributes);
13
+ const { validAttributes, mapAttributes } = useMemo(() => {
14
+ const mapAttributes = new Map();
15
+ const validAttributes = allAttributes
16
+ .filter((a) => {
17
+ return state.relevantAttributes.some((attr) => areObjRefsEqual(attr, a.attribute.ref));
18
+ })
19
+ .map((a) => {
20
+ const group = list.find((item) => a.displayForms.some((df) => areObjRefsEqual(df.ref, item.displayForm)));
21
+ mapAttributes.set(a.attribute.id, group);
22
+ return [a, group];
23
+ })
24
+ .sort(([, a], [, b]) => {
25
+ const aIndex = a ? list.indexOf(a) : Number.MAX_VALUE;
26
+ const bIndex = b ? list.indexOf(b) : Number.MAX_VALUE;
27
+ return aIndex - bIndex;
28
+ })
29
+ .map(([a]) => a);
30
+ return { validAttributes, mapAttributes };
31
+ }, [allAttributes, list, state.relevantAttributes]);
32
+ const initialAttributes = useMemo(() => {
33
+ return state.selectedAttributes
34
+ .map((attr) => {
35
+ return validAttributes.find((a) => a.displayForms.some((df) => areObjRefsEqual(df.ref, attr)));
36
+ })
37
+ .filter((a) => a !== undefined);
38
+ }, [state.selectedAttributes, validAttributes]);
39
+ return {
40
+ validAttributes,
41
+ mapAttributes,
42
+ initialAttributes,
43
+ isSearchBarVisible: validAttributes.length > SEARCH_BAR_THRESHOLD,
44
+ };
45
+ }
@@ -3,10 +3,17 @@ import { type ChangeParameterValuesParams } from "../../commands/parameters.js";
3
3
  /**
4
4
  * Pure decision logic for restoring an automation's stored parameter overrides on dashboard load.
5
5
  * Returns the {@link changeParameterValues} command params to dispatch: alert params target the
6
- * active tab, export params target their own tab. Mirrors the filter-side `extractRelevantFilters`
7
- * the saga reads the raw pieces off the automation and dispatches each result.
6
+ * active tab, export params target their own tab. Each export wire row carries its own type tag.
7
+ * Mirrors the filter-side `extractRelevantFilters` — the saga reads the raw pieces off the
8
+ * automation and dispatches each result.
8
9
  *
9
10
  * @internal
10
11
  */
11
- export declare function extractAutomationParameterChanges(enableParameters: boolean, alertParameters: IInsightParameterValue[] | undefined, exportParametersByTab: Record<string, IDashboardExportParameter[]> | undefined, correlationId: string): ChangeParameterValuesParams[];
12
+ export declare function extractAutomationParameterChanges({ enableParameters, enableStringParameters, alertParameters, exportParametersByTab, correlationId }: {
13
+ enableParameters: boolean;
14
+ enableStringParameters: boolean;
15
+ alertParameters: IInsightParameterValue[] | undefined;
16
+ exportParametersByTab: Record<string, IDashboardExportParameter[]> | undefined;
17
+ correlationId: string;
18
+ }): ChangeParameterValuesParams[];
12
19
  //# sourceMappingURL=automationParametersRestore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"automationParametersRestore.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/scheduledEmail/automationParametersRestore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGlG,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAEhF;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAC7C,gBAAgB,EAAE,OAAO,EACzB,eAAe,EAAE,sBAAsB,EAAE,GAAG,SAAS,EACrD,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,EAC9E,aAAa,EAAE,MAAM,GACtB,2BAA2B,EAAE,CAe/B"}
1
+ {"version":3,"file":"automationParametersRestore.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/scheduledEmail/automationParametersRestore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGlG,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAEhF;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,EAC9C,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,aAAa,EAChB,EAAE;IACC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,sBAAsB,EAAE,OAAO,CAAC;IAChC,eAAe,EAAE,sBAAsB,EAAE,GAAG,SAAS,CAAC;IACtD,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,CAAC;IAC/E,aAAa,EAAE,MAAM,CAAC;CACzB,GAAG,2BAA2B,EAAE,CAehC"}
@@ -3,12 +3,13 @@ import { exportParametersToValues } from "../../../_staging/automation/index.js"
3
3
  /**
4
4
  * Pure decision logic for restoring an automation's stored parameter overrides on dashboard load.
5
5
  * Returns the {@link changeParameterValues} command params to dispatch: alert params target the
6
- * active tab, export params target their own tab. Mirrors the filter-side `extractRelevantFilters`
7
- * the saga reads the raw pieces off the automation and dispatches each result.
6
+ * active tab, export params target their own tab. Each export wire row carries its own type tag.
7
+ * Mirrors the filter-side `extractRelevantFilters` — the saga reads the raw pieces off the
8
+ * automation and dispatches each result.
8
9
  *
9
10
  * @internal
10
11
  */
11
- export function extractAutomationParameterChanges(enableParameters, alertParameters, exportParametersByTab, correlationId) {
12
+ export function extractAutomationParameterChanges({ enableParameters, enableStringParameters, alertParameters, exportParametersByTab, correlationId, }) {
12
13
  if (!enableParameters) {
13
14
  return [];
14
15
  }
@@ -17,7 +18,7 @@ export function extractAutomationParameterChanges(enableParameters, alertParamet
17
18
  changes.push({ parameters: alertParameters, correlationId });
18
19
  }
19
20
  for (const [tabLocalIdentifier, exportParameters] of Object.entries(exportParametersByTab ?? {})) {
20
- const parameters = exportParametersToValues(exportParameters);
21
+ const parameters = exportParametersToValues(exportParameters, enableStringParameters);
21
22
  if (parameters.length) {
22
23
  changes.push({ parameters, tabLocalIdentifier, correlationId });
23
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createScheduledEmailHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/scheduledEmail/createScheduledEmailHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAwB/C,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,KAAK,+BAA+B,EAAyB,MAAM,gCAAgC,CAAC;AAc7G,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAoBnE,wBAAiB,2BAA2B,CACxC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,qBAAqB,GAC3B,YAAY,CAAC,+BAA+B,CAAC,CA6F/C"}
1
+ {"version":3,"file":"createScheduledEmailHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/scheduledEmail/createScheduledEmailHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAwB/C,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,KAAK,+BAA+B,EAAyB,MAAM,gCAAgC,CAAC;AAkB7G,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAoBnE,wBAAiB,2BAA2B,CACxC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,qBAAqB,GAC3B,YAAY,CAAC,+BAA+B,CAAC,CAiG/C"}
@@ -5,7 +5,7 @@ import { fillMissingTitles, resolveDefaultDisplayFormRefForDisplayForm, resolveM
5
5
  import { scheduledEmailCreated } from "../../events/scheduledEmail.js";
6
6
  import { queryWithInsight } from "../../queryServices/queryWidgetFilters.js";
7
7
  import { selectCatalogAttributes } from "../../store/catalog/catalogSelectors.js";
8
- import { selectLocale, selectSettings } from "../../store/config/configSelectors.js";
8
+ import { selectEnableStringParameters, selectLocale, selectSettings, } from "../../store/config/configSelectors.js";
9
9
  import { selectExecutionResultByRef } from "../../store/executionResults/executionResultsSelectors.js";
10
10
  import { selectAutomationCommonDateFilterId } from "../../store/filtering/dashboardFilterSelectors.js";
11
11
  import { selectInsightByRef, selectInsightByWidgetRef, selectRawExportOverridesForInsight, } from "../../store/insights/insightsSelectors.js";
@@ -31,6 +31,7 @@ export function* createScheduledEmailHandler(ctx, cmd) {
31
31
  const commonDateFilterId = yield select(selectAutomationCommonDateFilterId);
32
32
  const insight = yield select(selectInsightByWidgetRef(ref));
33
33
  const insightParameterValues = yield select(selectReferencedInsightParameterValuesForWidget(ref));
34
+ const enableStringParameters = yield select(selectEnableStringParameters);
34
35
  const locale = yield select(selectLocale);
35
36
  const messages = yield call(resolveMessages, locale);
36
37
  const lookupInsight = insight ? yield select(selectInsightByRef(insightRef(insight))) : undefined;
@@ -52,7 +53,15 @@ export function* createScheduledEmailHandler(ctx, cmd) {
52
53
  throw new Error("CSV raw widget attachment requires an available widget.");
53
54
  }
54
55
  }
55
- const preparedExecutionDefinitionWithFilters = prepareCsvRawExecutionDefinition(preparedExecutionDefinition, csvRawRequest, insight, insightParameterValues, widget, commonDateFilterId);
56
+ const preparedExecutionDefinitionWithFilters = prepareCsvRawExecutionDefinition({
57
+ executionDefinition: preparedExecutionDefinition,
58
+ csvRawRequest,
59
+ insight,
60
+ insightParameterValues,
61
+ enableStringParameters,
62
+ widget,
63
+ commonDateFilterId,
64
+ });
56
65
  const settings = yield select(selectSettings);
57
66
  const catalogAttributes = yield select(selectCatalogAttributes);
58
67
  const preloadedAttributesWithReferences = yield select(selectPreloadedAttributesWithReferences);