@gooddata/sdk-ui-dashboard 11.65.0-alpha.9 → 11.66.0-alpha.0

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 (275) hide show
  1. package/NOTICE +536 -2137
  2. package/README.md +1 -1
  3. package/esm/__version.d.ts +1 -1
  4. package/esm/__version.js +1 -1
  5. package/esm/index.d.ts +6 -4
  6. package/esm/index.d.ts.map +1 -1
  7. package/esm/index.js +3 -2
  8. package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts +36 -3
  9. package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
  10. package/esm/model/commandHandlers/dashboard/common/filterViews.js +138 -26
  11. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts +15 -4
  12. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
  13. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +55 -11
  14. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.d.ts +6 -1
  15. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.d.ts.map +1 -1
  16. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.js +14 -6
  17. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/resolveDashboardConfig.d.ts.map +1 -1
  18. package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/resolveDashboardConfig.js +1 -0
  19. package/esm/model/commandHandlers/dashboard/resetDashboardHandler.d.ts.map +1 -1
  20. package/esm/model/commandHandlers/dashboard/resetDashboardHandler.js +21 -8
  21. package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.d.ts.map +1 -1
  22. package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.js +9 -3
  23. package/esm/model/commandHandlers/filterContext/filterViewHandler.d.ts +10 -0
  24. package/esm/model/commandHandlers/filterContext/filterViewHandler.d.ts.map +1 -1
  25. package/esm/model/commandHandlers/filterContext/filterViewHandler.js +79 -24
  26. package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.d.ts +17 -0
  27. package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.d.ts.map +1 -0
  28. package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.js +79 -0
  29. package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts.map +1 -1
  30. package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.js +7 -3
  31. package/esm/model/commandHandlers/tabs/switchDashboardTabHandler.d.ts.map +1 -1
  32. package/esm/model/commandHandlers/tabs/switchDashboardTabHandler.js +3 -1
  33. package/esm/model/commands/filters.d.ts +16 -1
  34. package/esm/model/commands/filters.d.ts.map +1 -1
  35. package/esm/model/commands/filters.js +2 -1
  36. package/esm/model/commands/parameters.d.ts +10 -1
  37. package/esm/model/commands/parameters.d.ts.map +1 -1
  38. package/esm/model/commands/parameters.js +2 -1
  39. package/esm/model/events/base.d.ts +1 -1
  40. package/esm/model/events/base.d.ts.map +1 -1
  41. package/esm/model/events/index.d.ts +2 -1
  42. package/esm/model/events/index.d.ts.map +1 -1
  43. package/esm/model/events/insightEditor.d.ts +128 -0
  44. package/esm/model/events/insightEditor.d.ts.map +1 -0
  45. package/esm/model/events/insightEditor.js +74 -0
  46. package/esm/model/store/config/configSelectors.d.ts +12 -0
  47. package/esm/model/store/config/configSelectors.d.ts.map +1 -1
  48. package/esm/model/store/config/configSelectors.js +12 -0
  49. package/esm/model/store/filterViews/filterViewsReducers.d.ts +8 -0
  50. package/esm/model/store/filterViews/filterViewsReducers.d.ts.map +1 -1
  51. package/esm/model/store/filterViews/filterViewsReducers.js +11 -0
  52. package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts +6 -0
  53. package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts.map +1 -1
  54. package/esm/model/store/filterViews/filterViewsReducersSelectors.js +6 -0
  55. package/esm/model/store/filterViews/filterViewsState.d.ts +6 -0
  56. package/esm/model/store/filterViews/filterViewsState.d.ts.map +1 -1
  57. package/esm/model/store/filterViews/index.d.ts +2 -0
  58. package/esm/model/store/filterViews/index.d.ts.map +1 -1
  59. package/esm/model/store/meta/metaSelectors.d.ts +7 -0
  60. package/esm/model/store/meta/metaSelectors.d.ts.map +1 -1
  61. package/esm/model/store/meta/metaSelectors.js +10 -0
  62. package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts +24 -0
  63. package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts.map +1 -1
  64. package/esm/model/store/tabs/filterContext/filterContextReducers.js +75 -0
  65. package/esm/model/store/tabs/index.d.ts +8 -0
  66. package/esm/model/store/tabs/index.d.ts.map +1 -1
  67. package/esm/model/store/tabs/parameters/parametersReducers.d.ts +16 -0
  68. package/esm/model/store/tabs/parameters/parametersReducers.d.ts.map +1 -1
  69. package/esm/model/store/tabs/parameters/parametersReducers.js +25 -0
  70. package/esm/model/store/ui/index.d.ts +2 -0
  71. package/esm/model/store/ui/index.d.ts.map +1 -1
  72. package/esm/model/store/ui/uiReducers.d.ts +6 -0
  73. package/esm/model/store/ui/uiReducers.d.ts.map +1 -1
  74. package/esm/model/store/ui/uiReducers.js +8 -0
  75. package/esm/model/store/ui/uiSelectors.d.ts +7 -0
  76. package/esm/model/store/ui/uiSelectors.d.ts.map +1 -1
  77. package/esm/model/store/ui/uiSelectors.js +6 -0
  78. package/esm/model/store/ui/uiState.d.ts +5 -0
  79. package/esm/model/store/ui/uiState.d.ts.map +1 -1
  80. package/esm/model/store/ui/uiState.js +1 -0
  81. package/esm/model/types/commonTypes.d.ts +18 -0
  82. package/esm/model/types/commonTypes.d.ts.map +1 -1
  83. package/esm/model/types/insightEditorTypes.d.ts +43 -0
  84. package/esm/model/types/insightEditorTypes.d.ts.map +1 -0
  85. package/esm/model/types/insightEditorTypes.js +2 -0
  86. package/esm/presentation/automations/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogContent.d.ts.map +1 -1
  87. package/esm/presentation/automations/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogContent.js +1 -4
  88. package/esm/presentation/automations/connectors/hooks/useAutomationManagementEditRouting.d.ts.map +1 -1
  89. package/esm/presentation/automations/connectors/hooks/useAutomationManagementEditRouting.js +2 -6
  90. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.d.ts.map +1 -1
  91. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.js +6 -1
  92. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContent.d.ts.map +1 -1
  93. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContent.js +2 -5
  94. package/esm/presentation/automations/shared/automationFilters/utils.d.ts +4 -0
  95. package/esm/presentation/automations/shared/automationFilters/utils.d.ts.map +1 -1
  96. package/esm/presentation/automations/shared/automationFilters/utils.js +12 -5
  97. package/esm/presentation/automations/shared/utils/automationUtils.d.ts +1 -2
  98. package/esm/presentation/automations/shared/utils/automationUtils.d.ts.map +1 -1
  99. package/esm/presentation/automations/shared/utils/automationUtils.js +0 -1
  100. package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.d.ts +1 -1
  101. package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.d.ts.map +1 -1
  102. package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.js +0 -10
  103. package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.d.ts.map +1 -1
  104. package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.js +10 -1
  105. package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.d.ts +5 -0
  106. package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.d.ts.map +1 -0
  107. package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.js +27 -0
  108. package/esm/presentation/dashboard/DefaultDashboardContent/DefaultDashboardMainContent.d.ts.map +1 -1
  109. package/esm/presentation/dashboard/DefaultDashboardContent/DefaultDashboardMainContent.js +7 -2
  110. package/esm/presentation/dashboard/components/DashboardInner.d.ts.map +1 -1
  111. package/esm/presentation/dashboard/components/DashboardInner.js +13 -9
  112. package/esm/presentation/dashboard/hooks/useDashboard.d.ts.map +1 -1
  113. package/esm/presentation/dashboard/hooks/useDashboard.js +3 -2
  114. package/esm/presentation/insightEditor/InsightEditorContent.d.ts +26 -0
  115. package/esm/presentation/insightEditor/InsightEditorContent.d.ts.map +1 -0
  116. package/esm/presentation/insightEditor/InsightEditorContent.js +179 -0
  117. package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.d.ts +7 -0
  118. package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.d.ts.map +1 -0
  119. package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.js +25 -0
  120. package/esm/presentation/insightEditor/InsightEditorOverlay.d.ts +6 -0
  121. package/esm/presentation/insightEditor/InsightEditorOverlay.d.ts.map +1 -0
  122. package/esm/presentation/insightEditor/InsightEditorOverlay.js +110 -0
  123. package/esm/presentation/insightEditor/InsightEditorPermissionsContext.d.ts +10 -0
  124. package/esm/presentation/insightEditor/InsightEditorPermissionsContext.d.ts.map +1 -0
  125. package/esm/presentation/insightEditor/InsightEditorPermissionsContext.js +18 -0
  126. package/esm/presentation/insightEditor/InsightEditorPlaceholder.d.ts +7 -0
  127. package/esm/presentation/insightEditor/InsightEditorPlaceholder.d.ts.map +1 -0
  128. package/esm/presentation/insightEditor/InsightEditorPlaceholder.js +15 -0
  129. package/esm/presentation/insightEditor/filterContext/attributeFilters.d.ts +4 -0
  130. package/esm/presentation/insightEditor/filterContext/attributeFilters.d.ts.map +1 -0
  131. package/esm/presentation/insightEditor/filterContext/attributeFilters.js +115 -0
  132. package/esm/presentation/insightEditor/filterContext/dateFilters.d.ts +5 -0
  133. package/esm/presentation/insightEditor/filterContext/dateFilters.d.ts.map +1 -0
  134. package/esm/presentation/insightEditor/filterContext/dateFilters.js +117 -0
  135. package/esm/presentation/insightEditor/filterContext/filterIntersection.d.ts +7 -0
  136. package/esm/presentation/insightEditor/filterContext/filterIntersection.d.ts.map +1 -0
  137. package/esm/presentation/insightEditor/filterContext/filterIntersection.js +149 -0
  138. package/esm/presentation/insightEditor/filterContext/insightFilterContext.d.ts +26 -0
  139. package/esm/presentation/insightEditor/filterContext/insightFilterContext.d.ts.map +1 -0
  140. package/esm/presentation/insightEditor/filterContext/insightFilterContext.js +72 -0
  141. package/esm/presentation/insightEditor/filterContext/measureValueFilters.d.ts +20 -0
  142. package/esm/presentation/insightEditor/filterContext/measureValueFilters.d.ts.map +1 -0
  143. package/esm/presentation/insightEditor/filterContext/measureValueFilters.js +76 -0
  144. package/esm/presentation/insightEditor/filterContext/objQualifiers.d.ts +11 -0
  145. package/esm/presentation/insightEditor/filterContext/objQualifiers.d.ts.map +1 -0
  146. package/esm/presentation/insightEditor/filterContext/objQualifiers.js +18 -0
  147. package/esm/presentation/insightEditor/insightEditorEscapeGuard.d.ts +18 -0
  148. package/esm/presentation/insightEditor/insightEditorEscapeGuard.d.ts.map +1 -0
  149. package/esm/presentation/insightEditor/insightEditorEscapeGuard.js +24 -0
  150. package/esm/presentation/insightEditor/insightEditorRoute.d.ts +34 -0
  151. package/esm/presentation/insightEditor/insightEditorRoute.d.ts.map +1 -0
  152. package/esm/presentation/insightEditor/insightEditorRoute.js +48 -0
  153. package/esm/presentation/insightEditor/types.d.ts +7 -0
  154. package/esm/presentation/insightEditor/types.d.ts.map +1 -0
  155. package/esm/presentation/insightEditor/types.js +2 -0
  156. package/esm/presentation/insightEditor/useCanCreateInsightInEditor.d.ts +5 -0
  157. package/esm/presentation/insightEditor/useCanCreateInsightInEditor.d.ts.map +1 -0
  158. package/esm/presentation/insightEditor/useCanCreateInsightInEditor.js +14 -0
  159. package/esm/presentation/insightEditor/useExploreFilterTransfer.d.ts +23 -0
  160. package/esm/presentation/insightEditor/useExploreFilterTransfer.d.ts.map +1 -0
  161. package/esm/presentation/insightEditor/useExploreFilterTransfer.js +194 -0
  162. package/esm/presentation/insightEditor/useInsightEditPermissions.d.ts +17 -0
  163. package/esm/presentation/insightEditor/useInsightEditPermissions.d.ts.map +1 -0
  164. package/esm/presentation/insightEditor/useInsightEditPermissions.js +42 -0
  165. package/esm/presentation/insightEditor/useInsightEditorMenuItems.d.ts +23 -0
  166. package/esm/presentation/insightEditor/useInsightEditorMenuItems.d.ts.map +1 -0
  167. package/esm/presentation/insightEditor/useInsightEditorMenuItems.js +126 -0
  168. package/esm/presentation/insightEditor/useInsightEditorSession.d.ts +19 -0
  169. package/esm/presentation/insightEditor/useInsightEditorSession.d.ts.map +1 -0
  170. package/esm/presentation/insightEditor/useInsightEditorSession.js +141 -0
  171. package/esm/presentation/insightList/InsightList.d.ts.map +1 -1
  172. package/esm/presentation/insightList/InsightList.js +10 -5
  173. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +10 -0
  174. package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
  175. package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +11 -1
  176. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +10 -0
  177. package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
  178. package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +11 -1
  179. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +10 -0
  180. package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
  181. package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +16 -6
  182. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +32 -0
  183. package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  184. package/esm/presentation/localization/bundles/en-US.localization-bundle.js +32 -0
  185. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +10 -0
  186. package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
  187. package/esm/presentation/localization/bundles/es-419.localization-bundle.js +11 -1
  188. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +10 -0
  189. package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
  190. package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +50 -40
  191. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +10 -0
  192. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
  193. package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +11 -1
  194. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +10 -0
  195. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
  196. package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +12 -2
  197. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +10 -0
  198. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
  199. package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +186 -176
  200. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +10 -0
  201. package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
  202. package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +11 -1
  203. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +10 -0
  204. package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
  205. package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +11 -1
  206. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +10 -0
  207. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
  208. package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +11 -1
  209. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +10 -0
  210. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
  211. package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +11 -1
  212. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +10 -0
  213. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
  214. package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +11 -1
  215. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +10 -0
  216. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
  217. package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +11 -1
  218. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +10 -0
  219. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
  220. package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +11 -1
  221. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +10 -0
  222. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
  223. package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +11 -1
  224. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +10 -0
  225. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
  226. package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +11 -1
  227. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +10 -0
  228. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
  229. package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +11 -1
  230. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +10 -0
  231. package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
  232. package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +11 -1
  233. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +10 -0
  234. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
  235. package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +11 -1
  236. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +10 -0
  237. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
  238. package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +11 -1
  239. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +10 -0
  240. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
  241. package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +11 -1
  242. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +10 -0
  243. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
  244. package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +11 -1
  245. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +10 -0
  246. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
  247. package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +11 -1
  248. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +10 -0
  249. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
  250. package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +11 -1
  251. package/esm/presentation/shareDialog/DefaultShareDialog.d.ts.map +1 -1
  252. package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -5
  253. package/esm/presentation/topBar/title/EditableTitle.d.ts.map +1 -1
  254. package/esm/presentation/topBar/title/EditableTitle.js +6 -0
  255. package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.d.ts +1 -1
  256. package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.d.ts.map +1 -1
  257. package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.js +13 -1
  258. package/esm/presentation/widget/widget/InsightWidget/useEditableInsightMenu.d.ts.map +1 -1
  259. package/esm/presentation/widget/widget/InsightWidget/useEditableInsightMenu.js +5 -1
  260. package/esm/presentation/widget/widget/InsightWidget/useInsightMenu.d.ts.map +1 -1
  261. package/esm/presentation/widget/widget/InsightWidget/useInsightMenu.js +4 -1
  262. package/esm/sdk-ui-dashboard.d.ts +301 -5
  263. package/package.json +23 -21
  264. package/styles/css/dashboard.css +40 -1
  265. package/styles/css/dashboard.css.map +1 -1
  266. package/styles/css/dashboardContentLoader.css +45 -0
  267. package/styles/css/dashboardContentLoader.css.map +1 -0
  268. package/styles/css/insightEditor.css +46 -0
  269. package/styles/css/insightEditor.css.map +1 -0
  270. package/styles/css/main.css +86 -1
  271. package/styles/css/main.css.map +1 -1
  272. package/styles/scss/dashboard.scss +2 -1
  273. package/styles/scss/dashboardContentLoader.scss +45 -0
  274. package/styles/scss/insightEditor.scss +53 -0
  275. package/styles/scss/main.scss +1 -0
@@ -0,0 +1,194 @@
1
+ // (C) 2020-2026 GoodData Corporation
2
+ import { useCallback, useEffect, useMemo, useRef } from "react";
3
+ import { defineMessages } from "react-intl";
4
+ import { GdcAdCommandType, GdcErrorType, GdcProductName, } from "@gooddata/sdk-embedding";
5
+ import { isInsightWidget } from "@gooddata/sdk-model";
6
+ import { useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
7
+ import { useToastMessage } from "@gooddata/sdk-ui-kit";
8
+ import { queryWidgetFilters } from "../../model/queries/widgets.js";
9
+ import { useDashboardDispatch, useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
10
+ import { queryAndWaitFor } from "../../model/store/_infra/queryAndWaitFor.js";
11
+ import { selectBackendCapabilities } from "../../model/store/backendCapabilities/backendCapabilitiesSelectors.js";
12
+ import { selectEnableComputedAttributes, selectEnableMeasureValueFilterKD, selectEnableTimezoneChange, } from "../../model/store/config/configSelectors.js";
13
+ import { selectInsightByWidgetRef } from "../../model/store/insights/insightsSelectors.js";
14
+ import { selectEffectiveDashboardTimezone } from "../../model/store/meta/metaSelectors.js";
15
+ import { selectAttributeFilterConfigsDisplayAsLabelMap } from "../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
16
+ import { selectFilterContextDateFilter, selectFilterContextMeasureValueFilters, } from "../../model/store/tabs/filterContext/filterContextSelectors.js";
17
+ import { selectAnalyticalWidgetByRef } from "../../model/store/tabs/layout/layoutSelectors.js";
18
+ import { buildInsightEditorFilterContext, loadInsightAvailableAttributes, } from "./filterContext/insightFilterContext.js";
19
+ const KEEP_FILTER_CONTEXT_ID = "keepFilterContext";
20
+ const RETRY_DELAY_MS = 300;
21
+ const MAX_KEEPING_DURATION_MS = 5000;
22
+ const TOAST_DURATION_MS = 5000;
23
+ const messages = defineMessages({
24
+ dateFilterInapplicable: { id: "insightEditor.filterContext.dateFilterInapplicable" },
25
+ invalidFilterItemsCount: { id: "insightEditor.filterContext.invalidFilterItemsCount" },
26
+ tookTooLong: { id: "insightEditor.filterContext.tookTooLong" },
27
+ failed: { id: "insightEditor.filterContext.failed" },
28
+ });
29
+ /**
30
+ * Passes the dashboard filters and timezone of the explored widget to Analytical Designer, so the
31
+ * explored insight shows the same data as the widget.
32
+ *
33
+ * @remarks
34
+ * The transfer starts when the opened insight first renders. Analytical Designer replaces its filters
35
+ * with each answer of the visualization to a reference point change. An answer that the opened
36
+ * insight requested can arrive after the filters were set, and then removes them without an error.
37
+ * When Analytical Designer is not ready yet (its date datasets still load), the command fails and the
38
+ * transfer retries until it succeeds or takes too long. A later render starts the transfer again if
39
+ * the retries stopped too early.
40
+ */
41
+ export function useExploreFilterTransfer(target, isExplore, apiRef) {
42
+ const dispatch = useDashboardDispatch();
43
+ const backend = useBackendStrict();
44
+ const workspace = useWorkspaceStrict();
45
+ const { addWarning } = useToastMessage();
46
+ const widgetRef = target.type === "widget" ? target.ref : undefined;
47
+ const state = {
48
+ widget: useDashboardSelector(selectAnalyticalWidgetByRef(widgetRef)),
49
+ insight: useDashboardSelector(selectInsightByWidgetRef(widgetRef)),
50
+ capabilities: useDashboardSelector(selectBackendCapabilities),
51
+ displayAsLabelMap: useDashboardSelector(selectAttributeFilterConfigsDisplayAsLabelMap),
52
+ dateFilter: useDashboardSelector(selectFilterContextDateFilter),
53
+ isMeasureValueFilterEnabled: useDashboardSelector(selectEnableMeasureValueFilterKD),
54
+ measureValueFilters: useDashboardSelector(selectFilterContextMeasureValueFilters),
55
+ enableComputedAttributes: useDashboardSelector(selectEnableComputedAttributes),
56
+ isTimezoneEnabled: useDashboardSelector(selectEnableTimezoneChange),
57
+ timezone: useDashboardSelector(selectEffectiveDashboardTimezone),
58
+ };
59
+ const stateRef = useRef(state);
60
+ useEffect(() => {
61
+ stateRef.current = state;
62
+ });
63
+ const progress = useRef({
64
+ isInsightOpened: false,
65
+ isFilterContextKept: false,
66
+ isFailureReported: false,
67
+ startTime: 0,
68
+ });
69
+ const availableAttributes = useRef(null);
70
+ const retryTimeout = useRef(undefined);
71
+ const latestRun = useRef(0);
72
+ // The attributes load while Analytical Designer starts, so the transfer does not wait for them.
73
+ const getAvailableAttributes = useCallback(() => {
74
+ const { insight, enableComputedAttributes } = stateRef.current;
75
+ if (!availableAttributes.current) {
76
+ const load = insight
77
+ ? loadInsightAvailableAttributes(backend, workspace, insight, enableComputedAttributes)
78
+ : Promise.resolve([]);
79
+ // A failed load is not cached, so the next transfer loads the attributes again.
80
+ availableAttributes.current = load.catch((error) => {
81
+ availableAttributes.current = null;
82
+ throw error;
83
+ });
84
+ }
85
+ return availableAttributes.current;
86
+ }, [backend, workspace]);
87
+ useEffect(() => {
88
+ if (isExplore && widgetRef) {
89
+ // The transfer reports a failure of this preload.
90
+ getAvailableAttributes().catch(() => undefined);
91
+ }
92
+ return () => clearTimeout(retryTimeout.current);
93
+ }, [isExplore, widgetRef, getAvailableAttributes]);
94
+ const transferFilters = useCallback(async (run) => {
95
+ const attributes = await getAvailableAttributes();
96
+ const { widget, insight, ...rest } = stateRef.current;
97
+ if (!isInsightWidget(widget) || !insight) {
98
+ return;
99
+ }
100
+ const appliedFilters = (await queryAndWaitFor(dispatch, queryWidgetFilters(widget.ref)));
101
+ if (run !== latestRun.current) {
102
+ return;
103
+ }
104
+ const filters = buildInsightEditorFilterContext({
105
+ widget,
106
+ insight,
107
+ appliedFilters,
108
+ availableAttributes: attributes,
109
+ attributeFilterConfigsDisplayAsLabelMap: rest.displayAsLabelMap,
110
+ capabilities: rest.capabilities,
111
+ dateFilter: rest.dateFilter,
112
+ isMeasureValueFilterEnabled: rest.isMeasureValueFilterEnabled,
113
+ measureValueFilters: rest.measureValueFilters,
114
+ });
115
+ if (filters.length) {
116
+ if (!apiRef.current) {
117
+ return;
118
+ }
119
+ apiRef.current.setFilterContext({ filters }, KEEP_FILTER_CONTEXT_ID);
120
+ }
121
+ progress.current.isFilterContextKept = true;
122
+ }, [getAvailableAttributes, dispatch, apiRef]);
123
+ const keepFilterContext = useCallback(async () => {
124
+ const current = progress.current;
125
+ if (!current.isInsightOpened || current.isFilterContextKept) {
126
+ return;
127
+ }
128
+ if (!current.startTime) {
129
+ current.startTime = Date.now();
130
+ }
131
+ if (!widgetRef) {
132
+ // An insight that is not on the dashboard has no dashboard filters.
133
+ return;
134
+ }
135
+ // Only the latest transfer sends its filters, as an earlier one may still wait for data.
136
+ const run = ++latestRun.current;
137
+ try {
138
+ await transferFilters(run);
139
+ }
140
+ catch (error) {
141
+ // The filters stay not kept, so the next render of the insight tries again.
142
+ console.error("The dashboard filters cannot pass to Analytical Designer.", error);
143
+ if (run === latestRun.current && !current.isFailureReported) {
144
+ current.isFailureReported = true;
145
+ addWarning(messages.failed, { duration: TOAST_DURATION_MS });
146
+ }
147
+ }
148
+ }, [widgetRef, transferFilters, addWarning]);
149
+ const onInsightOpened = useCallback(() => {
150
+ if (!isExplore) {
151
+ return;
152
+ }
153
+ progress.current.isInsightOpened = true;
154
+ const { isTimezoneEnabled, timezone } = stateRef.current;
155
+ if (isTimezoneEnabled) {
156
+ // The explored insight executes in the same timezone as the widget.
157
+ const command = {
158
+ gdc: {
159
+ product: GdcProductName.ANALYTICAL_DESIGNER,
160
+ event: {
161
+ name: GdcAdCommandType.SetTimezone,
162
+ data: timezone === undefined ? {} : { timezoneId: timezone },
163
+ },
164
+ },
165
+ };
166
+ apiRef.current?.sendCommand(command);
167
+ }
168
+ }, [isExplore, apiRef]);
169
+ const onInsightRendered = useCallback(() => {
170
+ if (isExplore) {
171
+ void keepFilterContext();
172
+ }
173
+ }, [isExplore, keepFilterContext]);
174
+ const onCommandFailed = useCallback((data, contextId) => {
175
+ if (!isExplore || contextId !== KEEP_FILTER_CONTEXT_ID) {
176
+ return;
177
+ }
178
+ progress.current.isFilterContextKept = false;
179
+ if (data.errorCode === GdcErrorType.InvalidArgument) {
180
+ const isInvalidFilterItemsCount = (data.errorMessage?.indexOf("more than 30 attribute") ?? -1) > 0;
181
+ addWarning(isInvalidFilterItemsCount
182
+ ? messages.invalidFilterItemsCount
183
+ : messages.dateFilterInapplicable, { duration: TOAST_DURATION_MS });
184
+ return;
185
+ }
186
+ if (Date.now() - progress.current.startTime > MAX_KEEPING_DURATION_MS) {
187
+ addWarning(messages.tookTooLong, { duration: TOAST_DURATION_MS });
188
+ return;
189
+ }
190
+ clearTimeout(retryTimeout.current);
191
+ retryTimeout.current = setTimeout(() => void keepFilterContext(), RETRY_DELAY_MS);
192
+ }, [isExplore, addWarning, keepFilterContext]);
193
+ return useMemo(() => ({ onInsightOpened, onInsightRendered, onCommandFailed }), [onInsightOpened, onInsightRendered, onCommandFailed]);
194
+ }
@@ -0,0 +1,17 @@
1
+ import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
2
+ import { type AccessGranularPermission, type IInsight } from "@gooddata/sdk-model";
3
+ /**
4
+ * The current user's own permissions on each visualization of the dashboard, keyed by visualization id.
5
+ */
6
+ export type InsightPermissionsById = Record<string, AccessGranularPermission[]>;
7
+ export declare function indexInsightPermissions(insights: IInsight[]): InsightPermissionsById;
8
+ export declare function loadInsightPermissions(backend: IAnalyticalBackend, workspace: string, ids: string[]): Promise<InsightPermissionsById>;
9
+ /**
10
+ * The user's own permissions on the dashboard's visualizations, read in one query once the dashboard
11
+ * is in (its own load brings the visualizations without permissions). Only users without the MANAGE
12
+ * role while visualization permissions are on need them; for everyone else no request is made.
13
+ * `undefined` until the map is in, so a visualization counts as not editable while loading or after a
14
+ * failed read.
15
+ */
16
+ export declare function useInsightEditPermissions(isActive?: boolean): InsightPermissionsById | undefined;
17
+ //# sourceMappingURL=useInsightEditPermissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInsightEditPermissions.d.ts","sourceRoot":"","sources":["../../../src/presentation/insightEditor/useInsightEditPermissions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,QAAQ,EAAa,MAAM,qBAAqB,CAAC;AAQ9F;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;AAEhF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,sBAAsB,CAIpF;AAED,wBAAsB,sBAAsB,CACxC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,sBAAsB,CAAC,CAWjC;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,UAAO,GAAG,sBAAsB,GAAG,SAAS,CAe7F"}
@@ -0,0 +1,42 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useMemo } from "react";
3
+ import { insightId } from "@gooddata/sdk-model";
4
+ import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
5
+ import { useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
6
+ import { selectEnableVisualizationPermissions } from "../../model/store/config/configSelectors.js";
7
+ import { selectInsights } from "../../model/store/insights/insightsSelectors.js";
8
+ import { selectCanManageWorkspace } from "../../model/store/permissions/permissionsSelectors.js";
9
+ export function indexInsightPermissions(insights) {
10
+ return Object.fromEntries(insights.map((insight) => [insightId(insight), insight.insight.permissions ?? []]));
11
+ }
12
+ export async function loadInsightPermissions(backend, workspace, ids) {
13
+ const page = await backend
14
+ .workspace(workspace)
15
+ .insights()
16
+ .getInsightsQuery()
17
+ // the id list travels in the body, a dashboard with many widgets would not fit a URL
18
+ .withMethod("POST")
19
+ .withFilter({ id: ids })
20
+ .withMetaInclude(["permissions"])
21
+ .query();
22
+ return indexInsightPermissions(await page.all());
23
+ }
24
+ /**
25
+ * The user's own permissions on the dashboard's visualizations, read in one query once the dashboard
26
+ * is in (its own load brings the visualizations without permissions). Only users without the MANAGE
27
+ * role while visualization permissions are on need them; for everyone else no request is made.
28
+ * `undefined` until the map is in, so a visualization counts as not editable while loading or after a
29
+ * failed read.
30
+ */
31
+ export function useInsightEditPermissions(isActive = true) {
32
+ const backend = useBackendStrict();
33
+ const workspace = useWorkspaceStrict();
34
+ const enabled = useDashboardSelector(selectEnableVisualizationPermissions);
35
+ const canManageProject = useDashboardSelector(selectCanManageWorkspace);
36
+ const insights = useDashboardSelector(selectInsights);
37
+ const ids = useMemo(() => (insights ?? []).map(insightId).sort(), [insights]);
38
+ const key = ids.join(",");
39
+ const needed = isActive && enabled && !canManageProject && ids.length > 0;
40
+ const { result } = useCancelablePromise({ promise: needed ? () => loadInsightPermissions(backend, workspace, ids) : null }, [backend, workspace, needed, key]);
41
+ return result;
42
+ }
@@ -0,0 +1,23 @@
1
+ import { type IInsight, type IInsightWidget } from "@gooddata/sdk-model";
2
+ import { type IInsightMenuItem, type IInsightMenuItemButton } from "../widget/insightMenu/types.js";
3
+ export declare const EXPLORE_INSIGHT_MENU_ITEM_ID = "explore";
4
+ export declare const EXPLORE_INSIGHT_SEPARATOR_ID = "explore-separator";
5
+ export declare const EDIT_INSIGHT_MENU_ITEM_ID = "options-menu-edit-insight";
6
+ export declare const EDIT_INSIGHT_SEPARATOR_ID = "edit-insight-separator";
7
+ /**
8
+ * The "Explore from here" item of the widget menu in view mode.
9
+ */
10
+ export declare function useExploreInsightMenuItem(insight: IInsight | undefined, widget: IInsightWidget, closeMenu: () => void): IInsightMenuItemButton | undefined;
11
+ /**
12
+ * The "Edit" item of the widget menu in edit mode.
13
+ */
14
+ export declare function useEditInsightMenuItem(insight: IInsight | undefined, widget: IInsightWidget): IInsightMenuItemButton | undefined;
15
+ /**
16
+ * Puts the explore item first, separated from the other items.
17
+ */
18
+ export declare function addExploreMenuItem(items: IInsightMenuItem[], exploreItem: IInsightMenuItemButton | undefined): IInsightMenuItem[];
19
+ /**
20
+ * Puts the edit item last, but before the remove item, which stays the last one.
21
+ */
22
+ export declare function addEditMenuItem(items: IInsightMenuItem[], editItem: IInsightMenuItemButton | undefined): IInsightMenuItem[];
23
+ //# sourceMappingURL=useInsightEditorMenuItems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInsightEditorMenuItems.d.ts","sourceRoot":"","sources":["../../../src/presentation/insightEditor/useInsightEditorMenuItems.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAmC,MAAM,qBAAqB,CAAC;AAc1G,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAIpG,eAAO,MAAM,4BAA4B,YAAY,CAAC;AACtD,eAAO,MAAM,4BAA4B,sBAAsB,CAAC;AAChE,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAGlE;;GAEG;AACH,wBAAgB,yBAAyB,CACrC,OAAO,EAAE,QAAQ,GAAG,SAAS,EAC7B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,IAAI,GACtB,sBAAsB,GAAG,SAAS,CAsCpC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,QAAQ,GAAG,SAAS,EAC7B,MAAM,EAAE,cAAc,GACvB,sBAAsB,GAAG,SAAS,CA0CpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,gBAAgB,EAAE,EACzB,WAAW,EAAE,sBAAsB,GAAG,SAAS,GAChD,gBAAgB,EAAE,CAUpB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,gBAAgB,EAAE,EACzB,QAAQ,EAAE,sBAAsB,GAAG,SAAS,GAC7C,gBAAgB,EAAE,CAYpB"}
@@ -0,0 +1,126 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2021-2026 GoodData Corporation
3
+ import { useMemo } from "react";
4
+ import { useIntl } from "react-intl";
5
+ import { canEditVisualization, insightId } from "@gooddata/sdk-model";
6
+ import { IconExplore, useMediaQuery } from "@gooddata/sdk-ui-kit";
7
+ import { useTheme } from "@gooddata/sdk-ui-theme-provider";
8
+ import { useDashboardDispatch, useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
9
+ import { selectEnableInsightEditing, selectEnableVisualizationPermissions, } from "../../model/store/config/configSelectors.js";
10
+ import { selectCanCreateVisualization, selectPermissions, } from "../../model/store/permissions/permissionsSelectors.js";
11
+ import { uiActions } from "../../model/store/ui/index.js";
12
+ import { useInsightEditorPermissions } from "./InsightEditorPermissionsContext.js";
13
+ export const EXPLORE_INSIGHT_MENU_ITEM_ID = "explore";
14
+ export const EXPLORE_INSIGHT_SEPARATOR_ID = "explore-separator";
15
+ export const EDIT_INSIGHT_MENU_ITEM_ID = "options-menu-edit-insight";
16
+ export const EDIT_INSIGHT_SEPARATOR_ID = "edit-insight-separator";
17
+ const REMOVE_MENU_ITEM_ID = "InteractionPanelRemove";
18
+ /**
19
+ * The "Explore from here" item of the widget menu in view mode.
20
+ */
21
+ export function useExploreInsightMenuItem(insight, widget, closeMenu) {
22
+ const intl = useIntl();
23
+ const theme = useTheme();
24
+ const dispatch = useDashboardDispatch();
25
+ const isEnabled = useDashboardSelector(selectEnableInsightEditing);
26
+ const canCreateVisualization = useDashboardSelector(selectCanCreateVisualization);
27
+ const isMobile = useMediaQuery("mobileDevice");
28
+ const iconColor = theme?.palette?.complementary?.c5;
29
+ return useMemo(() => {
30
+ // Explore opens a draft the user may save as a new visualization, so it is a create path.
31
+ if (!isEnabled || !insight || !canCreateVisualization || isMobile) {
32
+ return undefined;
33
+ }
34
+ return {
35
+ type: "button",
36
+ itemId: EXPLORE_INSIGHT_MENU_ITEM_ID,
37
+ className: "s-options-menu-explore-insight",
38
+ itemName: intl.formatMessage({ id: "insightEditor.menu.explore" }),
39
+ icon: (_jsx(IconExplore, { className: "gd-icon-explore gd-icon-explore-sdk", color: iconColor, ariaHidden: true })),
40
+ onClick: () => {
41
+ dispatch(uiActions.openInsightEditor({ type: "widget", ref: widget.ref }));
42
+ closeMenu();
43
+ },
44
+ };
45
+ }, [
46
+ isEnabled,
47
+ insight,
48
+ canCreateVisualization,
49
+ isMobile,
50
+ intl,
51
+ iconColor,
52
+ dispatch,
53
+ widget.ref,
54
+ closeMenu,
55
+ ]);
56
+ }
57
+ /**
58
+ * The "Edit" item of the widget menu in edit mode.
59
+ */
60
+ export function useEditInsightMenuItem(insight, widget) {
61
+ const intl = useIntl();
62
+ const dispatch = useDashboardDispatch();
63
+ const isEnabled = useDashboardSelector(selectEnableInsightEditing);
64
+ const workspacePermissions = useDashboardSelector(selectPermissions);
65
+ const visualizationPermissionsEnabled = useDashboardSelector(selectEnableVisualizationPermissions);
66
+ const insightPermissions = useInsightEditorPermissions();
67
+ return useMemo(() => {
68
+ // Editing a visualization follows the right to save it in place, not the right to create one.
69
+ const canEditInsight = isEnabled &&
70
+ !!insight &&
71
+ !!workspacePermissions &&
72
+ canEditVisualization(insightPermissions?.[insightId(insight)], workspacePermissions, visualizationPermissionsEnabled);
73
+ if (!canEditInsight) {
74
+ return undefined;
75
+ }
76
+ return {
77
+ type: "button",
78
+ itemId: EDIT_INSIGHT_MENU_ITEM_ID,
79
+ className: "s-options-menu-edit-insight",
80
+ itemName: intl.formatMessage({ id: "controlButtons.edit.value" }),
81
+ icon: "gd-icon-pencil",
82
+ onClick: () => {
83
+ dispatch(uiActions.openInsightEditor({ type: "widget", ref: widget.ref }));
84
+ },
85
+ };
86
+ }, [
87
+ isEnabled,
88
+ insight,
89
+ workspacePermissions,
90
+ insightPermissions,
91
+ visualizationPermissionsEnabled,
92
+ intl,
93
+ dispatch,
94
+ widget.ref,
95
+ ]);
96
+ }
97
+ /**
98
+ * Puts the explore item first, separated from the other items.
99
+ */
100
+ export function addExploreMenuItem(items, exploreItem) {
101
+ if (!exploreItem) {
102
+ return items;
103
+ }
104
+ const needsSeparator = items.length > 0 && items[0].type !== "separator";
105
+ return [
106
+ exploreItem,
107
+ ...(needsSeparator ? [{ type: "separator", itemId: EXPLORE_INSIGHT_SEPARATOR_ID }] : []),
108
+ ...items,
109
+ ];
110
+ }
111
+ /**
112
+ * Puts the edit item last, but before the remove item, which stays the last one.
113
+ */
114
+ export function addEditMenuItem(items, editItem) {
115
+ if (!editItem) {
116
+ return items;
117
+ }
118
+ const removeItem = items.find((item) => item.itemId === REMOVE_MENU_ITEM_ID);
119
+ const otherItems = items.filter((item) => item !== removeItem);
120
+ return [
121
+ ...otherItems,
122
+ editItem,
123
+ ...(items.length > 0 ? [{ type: "separator", itemId: EDIT_INSIGHT_SEPARATOR_ID }] : []),
124
+ ...(removeItem ? [removeItem] : []),
125
+ ];
126
+ }
@@ -0,0 +1,19 @@
1
+ import { type InsightEditorTarget } from "../../model/types/insightEditorTypes.js";
2
+ export interface IInsightEditorSession {
3
+ /**
4
+ * Closes the editor without saving. It removes the placeholder of a new insight. It does nothing
5
+ * after the session ended or while a save runs.
6
+ */
7
+ cancel: () => void;
8
+ /**
9
+ * Puts the insight that the user saved in Analytical Designer on the dashboard and closes the
10
+ * editor.
11
+ */
12
+ save: (insightIdentifier: string) => Promise<void>;
13
+ }
14
+ /**
15
+ * The actions that finish the editing session of the target. They need no Analytical Designer code,
16
+ * so the editor can close while its chunk still loads.
17
+ */
18
+ export declare function useInsightEditorSession(target: InsightEditorTarget): IInsightEditorSession;
19
+ //# sourceMappingURL=useInsightEditorSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInsightEditorSession.d.ts","sourceRoot":"","sources":["../../../src/presentation/insightEditor/useInsightEditorSession.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAenF,MAAM,WAAW,qBAAqB;IAClC;;;OAGG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB;;;OAGG;IACH,IAAI,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,qBAAqB,CAmF1F"}
@@ -0,0 +1,141 @@
1
+ // (C) 2020-2026 GoodData Corporation
2
+ import { useCallback, useEffect, useMemo, useRef } from "react";
3
+ import { defineMessages } from "react-intl";
4
+ import { idRef, insightRef, insightTitle, insightVisualizationType, isInsightWidget, } from "@gooddata/sdk-model";
5
+ import { useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
6
+ import { INSIGHT_WIDGET_SIZE_INFO_DEFAULT } from "@gooddata/sdk-ui-ext";
7
+ import { useToastMessage } from "@gooddata/sdk-ui-kit";
8
+ import { getSizeInfo } from "../../_staging/layout/sizing.js";
9
+ import { changeInsightWidgetInsight } from "../../model/commands/insight.js";
10
+ import { eagerRemoveNestedLayoutSectionItem, replaceNestedLayoutSectionItem, } from "../../model/commands/layout.js";
11
+ import { insightEditorCancelled, insightEditorInsightSaved } from "../../model/events/insightEditor.js";
12
+ import { useDashboardDispatch, useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
13
+ import { useDashboardEventDispatch } from "../../model/react/useDashboardEventDispatch.js";
14
+ import { dispatchAndWaitFor } from "../../model/store/_infra/dispatchAndWaitFor.js";
15
+ import { selectSettings } from "../../model/store/config/configSelectors.js";
16
+ import { selectInsightByWidgetRef } from "../../model/store/insights/insightsSelectors.js";
17
+ import { selectIsInEditMode } from "../../model/store/renderMode/renderModeSelectors.js";
18
+ import { selectInsightWidgetPlaceholderPath, selectWidgetByRef, } from "../../model/store/tabs/layout/layoutSelectors.js";
19
+ import { uiActions } from "../../model/store/ui/index.js";
20
+ const messages = defineMessages({
21
+ placementFailed: { id: "insightEditor.save.placementFailed" },
22
+ });
23
+ /**
24
+ * The actions that finish the editing session of the target. They need no Analytical Designer code,
25
+ * so the editor can close while its chunk still loads.
26
+ */
27
+ export function useInsightEditorSession(target) {
28
+ const dispatch = useDashboardDispatch();
29
+ const eventDispatch = useDashboardEventDispatch();
30
+ const backend = useBackendStrict();
31
+ const workspace = useWorkspaceStrict();
32
+ const { addError } = useToastMessage();
33
+ const widgetRef = target.type === "widget" ? target.ref : undefined;
34
+ const state = {
35
+ isEditMode: useDashboardSelector(selectIsInEditMode),
36
+ placeholderPath: useDashboardSelector(selectInsightWidgetPlaceholderPath),
37
+ settings: useDashboardSelector(selectSettings),
38
+ widget: useDashboardSelector(selectWidgetByRef(widgetRef)),
39
+ widgetInsight: useDashboardSelector(selectInsightByWidgetRef(widgetRef)),
40
+ };
41
+ // The handlers run after AD events, so they read the state of that moment.
42
+ const stateRef = useRef(state);
43
+ useEffect(() => {
44
+ stateRef.current = state;
45
+ });
46
+ // AD confirms a cancellation at once after a save. The first save or cancel ends the session, so a
47
+ // cancellation during a running save cannot remove the placeholder that the save fills.
48
+ const isSettledRef = useRef(false);
49
+ const close = useCallback(() => {
50
+ dispatch(uiActions.closeInsightEditor());
51
+ }, [dispatch]);
52
+ const removePlaceholder = useCallback(() => {
53
+ const { placeholderPath } = stateRef.current;
54
+ if (target.type === "placeholder" && placeholderPath) {
55
+ dispatch(eagerRemoveNestedLayoutSectionItem(placeholderPath));
56
+ }
57
+ }, [target, dispatch]);
58
+ const cancel = useCallback(() => {
59
+ if (isSettledRef.current) {
60
+ return;
61
+ }
62
+ isSettledRef.current = true;
63
+ close();
64
+ eventDispatch(insightEditorCancelled(target));
65
+ removePlaceholder();
66
+ }, [close, eventDispatch, target, removePlaceholder]);
67
+ const save = useCallback(async (insightIdentifier) => {
68
+ if (isSettledRef.current) {
69
+ return;
70
+ }
71
+ isSettledRef.current = true;
72
+ let insight;
73
+ try {
74
+ insight = await backend
75
+ .workspace(workspace)
76
+ .insights()
77
+ .getInsight(idRef(insightIdentifier, "insight"));
78
+ if (stateRef.current.isEditMode) {
79
+ await placeInsight(dispatch, target, insight, stateRef.current);
80
+ }
81
+ close();
82
+ eventDispatch(insightEditorInsightSaved(target, insight));
83
+ }
84
+ catch (error) {
85
+ console.error("The insight saved in Analytical Designer cannot be put on the dashboard.", error);
86
+ close();
87
+ removePlaceholder();
88
+ addError(messages.placementFailed);
89
+ // The insight exists in the backend, so listeners must learn about it when it loaded.
90
+ eventDispatch(insight ? insightEditorInsightSaved(target, insight) : insightEditorCancelled(target));
91
+ }
92
+ }, [backend, workspace, target, dispatch, close, removePlaceholder, addError, eventDispatch]);
93
+ return useMemo(() => ({ cancel, save }), [cancel, save]);
94
+ }
95
+ async function placeInsight(dispatch, target, insight, { placeholderPath, settings, widget, widgetInsight }) {
96
+ if (target.type === "placeholder") {
97
+ if (placeholderPath) {
98
+ await addInsightToPlaceholder(dispatch, insight, placeholderPath, getSizeInfo(settings, "insight", insight));
99
+ }
100
+ }
101
+ else if (target.type === "widget") {
102
+ if (isInsightWidget(widget)) {
103
+ const originalType = widgetInsight && insightVisualizationType(widgetInsight);
104
+ const newType = insightVisualizationType(insight);
105
+ // Table sizes reset always, as the buckets may have changed.
106
+ const sizes = originalType === newType && newType !== "table" ? undefined : {};
107
+ dispatch(changeInsightWidgetInsight(widget.ref, insightRef(insight), sizes));
108
+ }
109
+ }
110
+ else {
111
+ // The new insight is not on the dashboard yet, so the list of insights must show it.
112
+ dispatch(uiActions.requestInsightListUpdate());
113
+ }
114
+ }
115
+ async function addInsightToPlaceholder(dispatch, insight, placeholderPath, sizeInfo) {
116
+ const itemReplaced = await dispatchAndWaitFor(dispatch, replaceNestedLayoutSectionItem(placeholderPath, {
117
+ type: "IDashboardLayoutItem",
118
+ size: {
119
+ xl: {
120
+ gridHeight: sizeInfo.height.default || INSIGHT_WIDGET_SIZE_INFO_DEFAULT.height.default,
121
+ gridWidth: sizeInfo.width.default || INSIGHT_WIDGET_SIZE_INFO_DEFAULT.width.default,
122
+ },
123
+ },
124
+ widget: {
125
+ type: "insight",
126
+ insight: insightRef(insight),
127
+ ignoreDashboardFilters: [],
128
+ drills: [],
129
+ title: insightTitle(insight),
130
+ description: "",
131
+ configuration: { hideTitle: false },
132
+ properties: {},
133
+ },
134
+ }, undefined, true));
135
+ const addedWidgetRef = itemReplaced.payload.items[0]?.widget?.ref;
136
+ if (addedWidgetRef) {
137
+ dispatch(uiActions.selectWidget(addedWidgetRef));
138
+ dispatch(uiActions.setConfigurationPanelOpened(true));
139
+ }
140
+ dispatch(uiActions.requestInsightListUpdate());
141
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"InsightList.d.ts","sourceRoot":"","sources":["../../../src/presentation/insightList/InsightList.tsx"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,QAAQ,EAUhB,MAAM,qBAAqB,CAAC;AAiC7B,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,YAAY,CAAC;AAKzE,UAAU,gBAAgB;IACtB,OAAO,EAAE,QAAQ,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAO5E;AAsCD;;GAEG;AACH,wBAAgB,WAAW,CAAC,EACxB,MAAM,EACN,KAAkB,EAClB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,WAAW,GACd,EAAE,iBAAiB,2CA8OnB"}
1
+ {"version":3,"file":"InsightList.d.ts","sourceRoot":"","sources":["../../../src/presentation/insightList/InsightList.tsx"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,QAAQ,EAUhB,MAAM,qBAAqB,CAAC;AAmC7B,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,YAAY,CAAC;AAKzE,UAAU,gBAAgB;IACtB,OAAO,EAAE,QAAQ,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAO5E;AAsCD;;GAEG;AACH,wBAAgB,WAAW,CAAC,EACxB,MAAM,EACN,KAAkB,EAClB,eAAe,EACf,UAAU,EACV,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,WAAW,GACd,EAAE,iBAAiB,2CAsPnB"}
@@ -9,12 +9,13 @@ import { DropdownList, InsightListItem, UiSkeleton } from "@gooddata/sdk-ui-kit"
9
9
  import { customMatcher, useHybridSearch, } from "@gooddata/sdk-ui-semantic-search";
10
10
  import { messages } from "../../locales.js";
11
11
  import { createInsightRequested } from "../../model/events/lab.js";
12
- import { useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
12
+ import { useDashboardDispatch, useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
13
13
  import { useDashboardEventDispatch } from "../../model/react/useDashboardEventDispatch.js";
14
14
  import { useDashboardExecConfig } from "../../model/react/useWidgetExecConfig.js";
15
15
  import { selectBackendCapabilities } from "../../model/store/backendCapabilities/backendCapabilitiesSelectors.js";
16
- import { selectAllowCreateInsightRequest, selectEnableCatalogSmartSearchResults, selectEnableVisualizationFilteringByTags, selectObjectAvailabilityConfig, selectSettings, } from "../../model/store/config/configSelectors.js";
16
+ import { selectAllowCreateInsightRequest, selectEnableCatalogSmartSearchResults, selectEnableInsightEditing, selectEnableVisualizationFilteringByTags, selectObjectAvailabilityConfig, selectSettings, } from "../../model/store/config/configSelectors.js";
17
17
  import { selectCanCreateVisualization } from "../../model/store/permissions/permissionsSelectors.js";
18
+ import { uiActions } from "../../model/store/ui/index.js";
18
19
  import { selectInsightListLastUpdateRequested } from "../../model/store/ui/uiSelectors.js";
19
20
  import { selectRestrictedRichTextReferences } from "../../model/store/unavailableObjects/unavailableObjectsSelectors.js";
20
21
  import { selectCurrentUser } from "../../model/store/user/userSelectors.js";
@@ -136,12 +137,16 @@ export function InsightList({ height, width = LIST_WIDTH, searchAutofocus, rende
136
137
  return isFirstOrLast ? ITEM_HEIGHT + firstLastItemMargin : ITEM_HEIGHT;
137
138
  };
138
139
  const eventDispatch = useDashboardEventDispatch();
140
+ const dispatch = useDashboardDispatch();
141
+ const isInsightEditingEnabled = useDashboardSelector(selectEnableInsightEditing);
139
142
  const createInsightRequestedEvent = useCallback((e) => {
140
143
  e.preventDefault();
141
144
  e.stopPropagation();
142
145
  eventDispatch(createInsightRequested());
143
- // oxlint-disable-next-line react-hooks/exhaustive-deps
144
- }, []);
146
+ if (isInsightEditingEnabled) {
147
+ dispatch(uiActions.openInsightEditor({ type: "new" }));
148
+ }
149
+ }, [eventDispatch, dispatch, isInsightEditingEnabled]);
145
150
  const TABS_AND_SEARCHFIELD_HEIGHT = 70;
146
151
  const SEARCHFIELD_HEIGHT = 47;
147
152
  // need to subtract height of controls from the overall size which was measured
@@ -149,7 +154,7 @@ export function InsightList({ height, width = LIST_WIDTH, searchAutofocus, rende
149
154
  const dropdownListHeight = height && height - controlsHeight;
150
155
  const dropdownListLoading = isLoading && pagedInsights.length === 0;
151
156
  const showDropdownListTabs = initialLoadCompleted && !search;
152
- const showNoDataCreateButton = allowCreateInsightRequest && canCreateVisualization;
157
+ const showNoDataCreateButton = (allowCreateInsightRequest || isInsightEditingEnabled) && canCreateVisualization;
153
158
  return (_jsx(DropdownList, { width: width, height: dropdownListHeight, isMobile: false, isLoading: dropdownListLoading, showSearch: initialLoadCompleted, searchString: search, searchFieldSize: "small", searchPlaceholder: intl.formatMessage({ id: "search_insights" }), onSearch: onSearch, disableAutofocus: !searchAutofocus, showTabs: showDropdownListTabs, tabs: backend.capabilities.supportsOwners && author ? dropdownTabsTranslationIds : undefined, selectedTabId: selectedTabId, onTabSelect: onTabSelect, itemHeight: ITEM_HEIGHT, itemHeightGetter: itemHeightGetter, items: insights, itemsCount: totalItems, body: () => {
154
159
  if (!isLoading && pagedInsights.length === 0 && searchRelatedItems.length > 0) {
155
160
  return (_jsx(InsightListNoData, { isUserInsights: selectedTabId === messages.tabsMy.id, hasNoMatchingData: true, showNoDataCreateButton: showNoDataCreateButton, onCreateButtonClick: createInsightRequestedEvent }));
@@ -1,4 +1,6 @@
1
1
  export declare const de_DE: {
2
+ "dashboard.ai.composing.replyNow": string;
3
+ "dashboard.ai.composing.waiting": string;
2
4
  "dashboard.contractExpired.trial.title": string;
3
5
  "dashboard.contractExpired.trial.description": string;
4
6
  "dashboard.contractExpired.nonTrial.title": string;
@@ -941,5 +943,13 @@ export declare const de_DE: {
941
943
  "dashboard_add_filter.button.aria_label": string;
942
944
  "dashboard_add_filter.menu.title": string;
943
945
  "dashboard_add_filter.menu.parameter": string;
946
+ "insightEditor.menu.explore": string;
947
+ "addPanel.insight": string;
948
+ "insightEditor.filterContext.dateFilterInapplicable": string;
949
+ "insightEditor.filterContext.invalidFilterItemsCount": string;
950
+ "insightEditor.filterContext.tookTooLong": string;
951
+ "insightEditor.filterContext.failed": string;
952
+ "insightEditor.dialog.label": string;
953
+ "insightEditor.save.placementFailed": string;
944
954
  };
945
955
  //# sourceMappingURL=de-DE.localization-bundle.d.ts.map