@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.
- package/NOTICE +536 -2137
- package/README.md +1 -1
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +6 -4
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -2
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts +36 -3
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +138 -26
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts +15 -4
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +55 -11
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.d.ts +6 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/preloadAttributeFiltersData.js +14 -6
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/resolveDashboardConfig.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/resolveDashboardConfig.js +1 -0
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.js +21 -8
- package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.js +9 -3
- package/esm/model/commandHandlers/filterContext/filterViewHandler.d.ts +10 -0
- package/esm/model/commandHandlers/filterContext/filterViewHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/filterViewHandler.js +79 -24
- package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.d.ts +17 -0
- package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.d.ts.map +1 -0
- package/esm/model/commandHandlers/filterContext/tabSync/writtenTargets.js +79 -0
- package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.js +7 -3
- package/esm/model/commandHandlers/tabs/switchDashboardTabHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/tabs/switchDashboardTabHandler.js +3 -1
- package/esm/model/commands/filters.d.ts +16 -1
- package/esm/model/commands/filters.d.ts.map +1 -1
- package/esm/model/commands/filters.js +2 -1
- package/esm/model/commands/parameters.d.ts +10 -1
- package/esm/model/commands/parameters.d.ts.map +1 -1
- package/esm/model/commands/parameters.js +2 -1
- package/esm/model/events/base.d.ts +1 -1
- package/esm/model/events/base.d.ts.map +1 -1
- package/esm/model/events/index.d.ts +2 -1
- package/esm/model/events/index.d.ts.map +1 -1
- package/esm/model/events/insightEditor.d.ts +128 -0
- package/esm/model/events/insightEditor.d.ts.map +1 -0
- package/esm/model/events/insightEditor.js +74 -0
- package/esm/model/store/config/configSelectors.d.ts +12 -0
- package/esm/model/store/config/configSelectors.d.ts.map +1 -1
- package/esm/model/store/config/configSelectors.js +12 -0
- package/esm/model/store/filterViews/filterViewsReducers.d.ts +8 -0
- package/esm/model/store/filterViews/filterViewsReducers.d.ts.map +1 -1
- package/esm/model/store/filterViews/filterViewsReducers.js +11 -0
- package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts +6 -0
- package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts.map +1 -1
- package/esm/model/store/filterViews/filterViewsReducersSelectors.js +6 -0
- package/esm/model/store/filterViews/filterViewsState.d.ts +6 -0
- package/esm/model/store/filterViews/filterViewsState.d.ts.map +1 -1
- package/esm/model/store/filterViews/index.d.ts +2 -0
- package/esm/model/store/filterViews/index.d.ts.map +1 -1
- package/esm/model/store/meta/metaSelectors.d.ts +7 -0
- package/esm/model/store/meta/metaSelectors.d.ts.map +1 -1
- package/esm/model/store/meta/metaSelectors.js +10 -0
- package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts +24 -0
- package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/filterContext/filterContextReducers.js +75 -0
- package/esm/model/store/tabs/index.d.ts +8 -0
- package/esm/model/store/tabs/index.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts +16 -0
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersReducers.js +25 -0
- package/esm/model/store/ui/index.d.ts +2 -0
- package/esm/model/store/ui/index.d.ts.map +1 -1
- package/esm/model/store/ui/uiReducers.d.ts +6 -0
- package/esm/model/store/ui/uiReducers.d.ts.map +1 -1
- package/esm/model/store/ui/uiReducers.js +8 -0
- package/esm/model/store/ui/uiSelectors.d.ts +7 -0
- package/esm/model/store/ui/uiSelectors.d.ts.map +1 -1
- package/esm/model/store/ui/uiSelectors.js +6 -0
- package/esm/model/store/ui/uiState.d.ts +5 -0
- package/esm/model/store/ui/uiState.d.ts.map +1 -1
- package/esm/model/store/ui/uiState.js +1 -0
- package/esm/model/types/commonTypes.d.ts +18 -0
- package/esm/model/types/commonTypes.d.ts.map +1 -1
- package/esm/model/types/insightEditorTypes.d.ts +43 -0
- package/esm/model/types/insightEditorTypes.d.ts.map +1 -0
- package/esm/model/types/insightEditorTypes.js +2 -0
- package/esm/presentation/automations/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogContent.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogContent.js +1 -4
- package/esm/presentation/automations/connectors/hooks/useAutomationManagementEditRouting.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/hooks/useAutomationManagementEditRouting.js +2 -6
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/RecipientsSelect/RecipientsSelectRenderer.js +6 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContent.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContent.js +2 -5
- package/esm/presentation/automations/shared/automationFilters/utils.d.ts +4 -0
- package/esm/presentation/automations/shared/automationFilters/utils.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/utils.js +12 -5
- package/esm/presentation/automations/shared/utils/automationUtils.d.ts +1 -2
- package/esm/presentation/automations/shared/utils/automationUtils.d.ts.map +1 -1
- package/esm/presentation/automations/shared/utils/automationUtils.js +0 -1
- package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.d.ts +1 -1
- package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.d.ts.map +1 -1
- package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.js +0 -10
- package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.d.ts.map +1 -1
- package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.js +10 -1
- package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.d.ts +5 -0
- package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.d.ts.map +1 -0
- package/esm/presentation/dashboard/DefaultDashboardContent/DashboardContentLoader.js +27 -0
- package/esm/presentation/dashboard/DefaultDashboardContent/DefaultDashboardMainContent.d.ts.map +1 -1
- package/esm/presentation/dashboard/DefaultDashboardContent/DefaultDashboardMainContent.js +7 -2
- package/esm/presentation/dashboard/components/DashboardInner.d.ts.map +1 -1
- package/esm/presentation/dashboard/components/DashboardInner.js +13 -9
- package/esm/presentation/dashboard/hooks/useDashboard.d.ts.map +1 -1
- package/esm/presentation/dashboard/hooks/useDashboard.js +3 -2
- package/esm/presentation/insightEditor/InsightEditorContent.d.ts +26 -0
- package/esm/presentation/insightEditor/InsightEditorContent.d.ts.map +1 -0
- package/esm/presentation/insightEditor/InsightEditorContent.js +179 -0
- package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.d.ts +7 -0
- package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.d.ts.map +1 -0
- package/esm/presentation/insightEditor/InsightEditorCreatePanelItem.js +25 -0
- package/esm/presentation/insightEditor/InsightEditorOverlay.d.ts +6 -0
- package/esm/presentation/insightEditor/InsightEditorOverlay.d.ts.map +1 -0
- package/esm/presentation/insightEditor/InsightEditorOverlay.js +110 -0
- package/esm/presentation/insightEditor/InsightEditorPermissionsContext.d.ts +10 -0
- package/esm/presentation/insightEditor/InsightEditorPermissionsContext.d.ts.map +1 -0
- package/esm/presentation/insightEditor/InsightEditorPermissionsContext.js +18 -0
- package/esm/presentation/insightEditor/InsightEditorPlaceholder.d.ts +7 -0
- package/esm/presentation/insightEditor/InsightEditorPlaceholder.d.ts.map +1 -0
- package/esm/presentation/insightEditor/InsightEditorPlaceholder.js +15 -0
- package/esm/presentation/insightEditor/filterContext/attributeFilters.d.ts +4 -0
- package/esm/presentation/insightEditor/filterContext/attributeFilters.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/attributeFilters.js +115 -0
- package/esm/presentation/insightEditor/filterContext/dateFilters.d.ts +5 -0
- package/esm/presentation/insightEditor/filterContext/dateFilters.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/dateFilters.js +117 -0
- package/esm/presentation/insightEditor/filterContext/filterIntersection.d.ts +7 -0
- package/esm/presentation/insightEditor/filterContext/filterIntersection.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/filterIntersection.js +149 -0
- package/esm/presentation/insightEditor/filterContext/insightFilterContext.d.ts +26 -0
- package/esm/presentation/insightEditor/filterContext/insightFilterContext.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/insightFilterContext.js +72 -0
- package/esm/presentation/insightEditor/filterContext/measureValueFilters.d.ts +20 -0
- package/esm/presentation/insightEditor/filterContext/measureValueFilters.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/measureValueFilters.js +76 -0
- package/esm/presentation/insightEditor/filterContext/objQualifiers.d.ts +11 -0
- package/esm/presentation/insightEditor/filterContext/objQualifiers.d.ts.map +1 -0
- package/esm/presentation/insightEditor/filterContext/objQualifiers.js +18 -0
- package/esm/presentation/insightEditor/insightEditorEscapeGuard.d.ts +18 -0
- package/esm/presentation/insightEditor/insightEditorEscapeGuard.d.ts.map +1 -0
- package/esm/presentation/insightEditor/insightEditorEscapeGuard.js +24 -0
- package/esm/presentation/insightEditor/insightEditorRoute.d.ts +34 -0
- package/esm/presentation/insightEditor/insightEditorRoute.d.ts.map +1 -0
- package/esm/presentation/insightEditor/insightEditorRoute.js +48 -0
- package/esm/presentation/insightEditor/types.d.ts +7 -0
- package/esm/presentation/insightEditor/types.d.ts.map +1 -0
- package/esm/presentation/insightEditor/types.js +2 -0
- package/esm/presentation/insightEditor/useCanCreateInsightInEditor.d.ts +5 -0
- package/esm/presentation/insightEditor/useCanCreateInsightInEditor.d.ts.map +1 -0
- package/esm/presentation/insightEditor/useCanCreateInsightInEditor.js +14 -0
- package/esm/presentation/insightEditor/useExploreFilterTransfer.d.ts +23 -0
- package/esm/presentation/insightEditor/useExploreFilterTransfer.d.ts.map +1 -0
- package/esm/presentation/insightEditor/useExploreFilterTransfer.js +194 -0
- package/esm/presentation/insightEditor/useInsightEditPermissions.d.ts +17 -0
- package/esm/presentation/insightEditor/useInsightEditPermissions.d.ts.map +1 -0
- package/esm/presentation/insightEditor/useInsightEditPermissions.js +42 -0
- package/esm/presentation/insightEditor/useInsightEditorMenuItems.d.ts +23 -0
- package/esm/presentation/insightEditor/useInsightEditorMenuItems.d.ts.map +1 -0
- package/esm/presentation/insightEditor/useInsightEditorMenuItems.js +126 -0
- package/esm/presentation/insightEditor/useInsightEditorSession.d.ts +19 -0
- package/esm/presentation/insightEditor/useInsightEditorSession.d.ts.map +1 -0
- package/esm/presentation/insightEditor/useInsightEditorSession.js +141 -0
- package/esm/presentation/insightList/InsightList.d.ts.map +1 -1
- package/esm/presentation/insightList/InsightList.js +10 -5
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +16 -6
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +32 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +32 -0
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +50 -40
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +12 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +186 -176
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +11 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +10 -0
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +11 -1
- package/esm/presentation/shareDialog/DefaultShareDialog.d.ts.map +1 -1
- package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -5
- package/esm/presentation/topBar/title/EditableTitle.d.ts.map +1 -1
- package/esm/presentation/topBar/title/EditableTitle.js +6 -0
- package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.d.ts +1 -1
- package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.d.ts.map +1 -1
- package/esm/presentation/widget/insight/DefaultDashboardInsightComponentSetFactory.js +13 -1
- package/esm/presentation/widget/widget/InsightWidget/useEditableInsightMenu.d.ts.map +1 -1
- package/esm/presentation/widget/widget/InsightWidget/useEditableInsightMenu.js +5 -1
- package/esm/presentation/widget/widget/InsightWidget/useInsightMenu.d.ts.map +1 -1
- package/esm/presentation/widget/widget/InsightWidget/useInsightMenu.js +4 -1
- package/esm/sdk-ui-dashboard.d.ts +301 -5
- package/package.json +23 -21
- package/styles/css/dashboard.css +40 -1
- package/styles/css/dashboard.css.map +1 -1
- package/styles/css/dashboardContentLoader.css +45 -0
- package/styles/css/dashboardContentLoader.css.map +1 -0
- package/styles/css/insightEditor.css +46 -0
- package/styles/css/insightEditor.css.map +1 -0
- package/styles/css/main.css +86 -1
- package/styles/css/main.css.map +1 -1
- package/styles/scss/dashboard.scss +2 -1
- package/styles/scss/dashboardContentLoader.scss +45 -0
- package/styles/scss/insightEditor.scss +53 -0
- 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;
|
|
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
|
-
|
|
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
|