@gooddata/sdk-ui-gen-ai 11.57.0 → 11.58.0-alpha.1
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 +2321 -1760
- package/esm/components/GenAIChatDialogConnected.d.ts +1 -2
- package/esm/components/GenAIChatDialogConnected.d.ts.map +1 -1
- package/esm/components/GenAIChatDialogConnected.js +3 -9
- package/esm/components/Input.d.ts.map +1 -1
- package/esm/components/Input.js +8 -18
- package/esm/components/Messages.d.ts.map +1 -1
- package/esm/components/Messages.js +4 -20
- package/esm/components/customized/LandingQuestion.d.ts.map +1 -1
- package/esm/components/customized/LandingQuestion.js +1 -5
- package/esm/components/hooks/useEndpointCheck.d.ts.map +1 -1
- package/esm/components/hooks/useEndpointCheck.js +2 -2
- package/esm/components/messages/MessageScroller.d.ts +2 -2
- package/esm/components/messages/MessageScroller.d.ts.map +1 -1
- package/esm/components/messages/components/SemanticSearchTreeView.d.ts +4 -3
- package/esm/components/messages/components/SemanticSearchTreeView.d.ts.map +1 -1
- package/esm/components/messages/components/SemanticSearchTreeView.js +4 -4
- package/esm/components/messages/contents/drill/DrillSelectDropdownMenu.js +1 -1
- package/esm/components/messages/conversationContents/ConversationMultipartContent.js +1 -1
- package/esm/components/messages/conversationContents/ConversationSearchContent.d.ts.map +1 -1
- package/esm/components/messages/conversationContents/ConversationSearchContent.js +2 -8
- package/esm/components/messages/conversationContents/ConversationVisualisation.d.ts.map +1 -1
- package/esm/components/messages/conversationContents/ConversationVisualisation.js +63 -3
- package/esm/components/messages/conversationContents/ConversationVisualizationContent.js +2 -2
- package/esm/components/messages/conversationContents/SaveVisualizationDialog.js +1 -1
- package/esm/components/messages/useUserFeedback.d.ts +2 -2
- package/esm/components/messages/useUserFeedback.d.ts.map +1 -1
- package/esm/components/messages/useUserFeedback.js +17 -47
- package/esm/components/utils/modelCheckUtility.d.ts +1 -1
- package/esm/components/utils/modelCheckUtility.d.ts.map +1 -1
- package/esm/components/utils/modelCheckUtility.js +2 -2
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/internal.d.ts +1 -2
- package/esm/internal.d.ts.map +1 -1
- package/esm/internal.js +1 -2
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +0 -12
- package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +0 -12
- package/esm/model.d.ts +0 -209
- package/esm/model.d.ts.map +1 -1
- package/esm/model.js +0 -131
- package/esm/sdk-ui-gen-ai.d.ts +1 -159
- package/esm/store/localStorage.d.ts +0 -4
- package/esm/store/localStorage.d.ts.map +1 -1
- package/esm/store/localStorage.js +0 -41
- package/esm/store/messages/messagesSelectors.d.ts +1 -12
- package/esm/store/messages/messagesSelectors.d.ts.map +1 -1
- package/esm/store/messages/messagesSelectors.js +1 -6
- package/esm/store/messages/messagesSlice.d.ts +7 -34
- package/esm/store/messages/messagesSlice.d.ts.map +1 -1
- package/esm/store/messages/messagesSlice.js +159 -408
- package/esm/store/queues/queue.newMessage.js +2 -4
- package/esm/store/sideEffects/conversationSession.js +1 -1
- package/esm/store/sideEffects/onChatOpenSync.d.ts +0 -1
- package/esm/store/sideEffects/onChatOpenSync.d.ts.map +1 -1
- package/esm/store/sideEffects/onChatOpenSync.js +0 -6
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts +2 -2
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts.map +1 -1
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.js +2 -8
- package/esm/store/sideEffects/onEvent.d.ts.map +1 -1
- package/esm/store/sideEffects/onEvent.js +26 -71
- package/esm/store/sideEffects/onThreadClear.d.ts +1 -7
- package/esm/store/sideEffects/onThreadClear.d.ts.map +1 -1
- package/esm/store/sideEffects/onThreadClear.js +4 -26
- package/esm/store/sideEffects/onThreadLoad.d.ts +3 -26
- package/esm/store/sideEffects/onThreadLoad.d.ts.map +1 -1
- package/esm/store/sideEffects/onThreadLoad.js +3 -86
- package/esm/store/sideEffects/onUserFeedback.d.ts +4 -4
- package/esm/store/sideEffects/onUserFeedback.d.ts.map +1 -1
- package/esm/store/sideEffects/onUserFeedback.js +21 -44
- package/esm/store/sideEffects/onUserMessage.d.ts +3 -25
- package/esm/store/sideEffects/onUserMessage.d.ts.map +1 -1
- package/esm/store/sideEffects/onUserMessage.js +7 -161
- package/esm/store/sideEffects/onVisualisationRender.d.ts +2 -8
- package/esm/store/sideEffects/onVisualisationRender.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualisationRender.js +1 -28
- package/esm/store/sideEffects/onVisualizationSave.d.ts +5 -6
- package/esm/store/sideEffects/onVisualizationSave.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualizationSave.js +32 -240
- package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts +3 -4
- package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualizationSuccessSave.js +16 -49
- package/esm/store/sideEffects/utils.d.ts +0 -2
- package/esm/store/sideEffects/utils.d.ts.map +1 -1
- package/esm/store/sideEffects/utils.js +0 -14
- package/package.json +20 -19
- package/styles/css/main.css +12 -496
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +12 -496
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/messages.scss +14 -375
- package/esm/components/messages/AssistantMessage.d.ts +0 -8
- package/esm/components/messages/AssistantMessage.d.ts.map +0 -1
- package/esm/components/messages/AssistantMessage.js +0 -35
- package/esm/components/messages/MessageContents.d.ts +0 -12
- package/esm/components/messages/MessageContents.d.ts.map +0 -1
- package/esm/components/messages/MessageContents.js +0 -49
- package/esm/components/messages/ReasoningDropdown.d.ts +0 -14
- package/esm/components/messages/ReasoningDropdown.d.ts.map +0 -1
- package/esm/components/messages/ReasoningDropdown.js +0 -42
- package/esm/components/messages/ReasoningMessage.d.ts +0 -9
- package/esm/components/messages/ReasoningMessage.d.ts.map +0 -1
- package/esm/components/messages/ReasoningMessage.js +0 -45
- package/esm/components/messages/UserMessage.d.ts +0 -8
- package/esm/components/messages/UserMessage.d.ts.map +0 -1
- package/esm/components/messages/UserMessage.js +0 -10
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts +0 -12
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts.map +0 -1
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.js +0 -36
- package/esm/components/messages/contents/ErrorContents.d.ts +0 -7
- package/esm/components/messages/contents/ErrorContents.d.ts.map +0 -1
- package/esm/components/messages/contents/ErrorContents.js +0 -8
- package/esm/components/messages/contents/ReasoningContents.d.ts +0 -6
- package/esm/components/messages/contents/ReasoningContents.d.ts.map +0 -1
- package/esm/components/messages/contents/ReasoningContents.js +0 -43
- package/esm/components/messages/contents/RoutingContents.d.ts +0 -8
- package/esm/components/messages/contents/RoutingContents.d.ts.map +0 -1
- package/esm/components/messages/contents/RoutingContents.js +0 -8
- package/esm/components/messages/contents/SearchContents.d.ts +0 -7
- package/esm/components/messages/contents/SearchContents.d.ts.map +0 -1
- package/esm/components/messages/contents/SearchContents.js +0 -15
- package/esm/components/messages/contents/SemanticSearchContents.d.ts +0 -8
- package/esm/components/messages/contents/SemanticSearchContents.d.ts.map +0 -1
- package/esm/components/messages/contents/SemanticSearchContents.js +0 -27
- package/esm/components/messages/contents/TextContents.d.ts +0 -7
- package/esm/components/messages/contents/TextContents.d.ts.map +0 -1
- package/esm/components/messages/contents/TextContents.js +0 -8
- package/esm/components/messages/contents/VisualizationContents.d.ts +0 -24
- package/esm/components/messages/contents/VisualizationContents.d.ts.map +0 -1
- package/esm/components/messages/contents/VisualizationContents.js +0 -532
- package/esm/components/messages/contents/VisualizationSaveDialog.d.ts +0 -13
- package/esm/components/messages/contents/VisualizationSaveDialog.d.ts.map +0 -1
- package/esm/components/messages/contents/VisualizationSaveDialog.js +0 -33
- package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts +0 -6
- package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts.map +0 -1
- package/esm/components/messages/contents/hooks/useVisualisationSaving.js +0 -17
- package/esm/components/messages/contents/useExecution.d.ts +0 -14
- package/esm/components/messages/contents/useExecution.d.ts.map +0 -1
- package/esm/components/messages/contents/useExecution.js +0 -131
- package/esm/components/messages/contents/useKdaDefinition.d.ts +0 -13
- package/esm/components/messages/contents/useKdaDefinition.d.ts.map +0 -1
- package/esm/components/messages/contents/useKdaDefinition.js +0 -140
- package/esm/components/messages/messageState.d.ts +0 -12
- package/esm/components/messages/messageState.d.ts.map +0 -1
- package/esm/components/messages/messageState.js +0 -21
- package/esm/store/sideEffects/converters/interactionsToMessages.d.ts +0 -19
- package/esm/store/sideEffects/converters/interactionsToMessages.d.ts.map +0 -1
- package/esm/store/sideEffects/converters/interactionsToMessages.js +0 -82
|
@@ -1,532 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// (C) 2024-2026 GoodData Corporation
|
|
3
|
-
import { useCallback, useMemo, useRef, useState, } from "react";
|
|
4
|
-
import cx from "classnames";
|
|
5
|
-
import copy from "copy-to-clipboard";
|
|
6
|
-
import { useIntl } from "react-intl";
|
|
7
|
-
import { useDispatch, useSelector } from "react-redux";
|
|
8
|
-
import { assertNever, isMeasureDescriptor, } from "@gooddata/sdk-model";
|
|
9
|
-
import { isNoDataSdkError, useWorkspaceStrict, } from "@gooddata/sdk-ui";
|
|
10
|
-
import { BarChart, ColumnChart, Headline, LineChart, PieChart, ScatterPlot } from "@gooddata/sdk-ui-charts";
|
|
11
|
-
import { getKdaKeyDriverCombinations, } from "@gooddata/sdk-ui-dashboard";
|
|
12
|
-
import { Dropdown, IconCopy, IconExternalLink, IconSave, Overlay, UiButton, UiFocusManager, UiIconButton, UiMenu, UiTooltip, useId, } from "@gooddata/sdk-ui-kit";
|
|
13
|
-
import { PivotTable } from "@gooddata/sdk-ui-pivot";
|
|
14
|
-
import { PivotTableNext, useAgGridToken } from "@gooddata/sdk-ui-pivot/next";
|
|
15
|
-
import { ScopedThemeProvider, useTheme } from "@gooddata/sdk-ui-theme-provider";
|
|
16
|
-
import { mapVisualizationAnomalyDetectionToBackendConfig, mapVisualizationAnomalyDetectionToChartConfig, } from "../../../anomalyDetection/anomalyDetectionMapping.js";
|
|
17
|
-
import { mapVisualizationClusteringToBackendConfig, mapVisualizationClusteringToChartConfig, } from "../../../clustering/clusteringMapping.js";
|
|
18
|
-
import { mapVisualizationForecastToBackendConfig, mapVisualizationForecastToChartConfig, } from "../../../forecast/forecastMapping.js";
|
|
19
|
-
import { makeTextContents, makeUserMessage } from "../../../model.js";
|
|
20
|
-
import { agentSwitchingActiveSelector, colorPaletteSelector, settingsSelector, } from "../../../store/chatWindow/chatWindowSelectors.js";
|
|
21
|
-
import { copyToClipboardAction, setKeyDriverAnalysisAction, } from "../../../store/chatWindow/chatWindowSlice.js";
|
|
22
|
-
import { agentsAvailableSelector } from "../../../store/messages/messagesSelectors.js";
|
|
23
|
-
import { newMessageAction, saveVisualisationRenderStatusAction, visualizationErrorAction, } from "../../../store/messages/messagesSlice.js";
|
|
24
|
-
import { getAbsoluteVisualizationHref, getHeadlineComparison, getVisualizationHref } from "../../../utils.js";
|
|
25
|
-
import { storeKdaReturnFocusFromDrillContext } from "../../../utils/kdaReturnFocus.js";
|
|
26
|
-
import { mapVisualizationWhatIfToScenarios } from "../../../whatIf/whatIfMapping.js";
|
|
27
|
-
import { useConfig } from "../../ConfigContext.js";
|
|
28
|
-
import { convertIntersectionToAttributeFilters, mergeFilters } from "../../utils/intersectionUtils.js";
|
|
29
|
-
import { VisualizationErrorBoundary } from "../components/VisualizationErrorBoundary.js";
|
|
30
|
-
import { DrillSelectDropdownMenu } from "./drill/DrillSelectDropdownMenu.js";
|
|
31
|
-
import { MarkdownComponent } from "./Markdown.js";
|
|
32
|
-
import { useExecution } from "./useExecution.js";
|
|
33
|
-
import { createKdaDefinitionFromDrill, getDashboardAttributeFilter } from "./useKdaDefinition.js";
|
|
34
|
-
import { VisualizationSaveDialog } from "./VisualizationSaveDialog.js";
|
|
35
|
-
const VIS_HEIGHT = 250;
|
|
36
|
-
const MORE_MENU_BUTTON_ID = "gd-gen-ai-chat__visualization__save__more-menu-button";
|
|
37
|
-
const overlayAlignPoints = [{ align: "br tr" }];
|
|
38
|
-
function VisualizationContentsComponentCore({ content, messageId, useMarkdown, colorPalette, enableNewPivotTable = true, enableAccessibleChartTooltip = false, enableChangeAnalysis = false, agentSwitchingActive = false, agGridToken, agentsAvailable, showSuggestions = false, onCopyToClipboard, setKeyDriverAnalysis, }) {
|
|
39
|
-
const dispatch = useDispatch();
|
|
40
|
-
// Resolve agGridToken from context if provided via AgGridTokenProvider, otherwise use prop from Redux
|
|
41
|
-
const resolvedAgGridToken = useAgGridToken(agGridToken);
|
|
42
|
-
const className = cx("gd-gen-ai-chat__messages__content", "gd-gen-ai-chat__messages__content--visualization");
|
|
43
|
-
const visualization = content.createdVisualizations?.[0];
|
|
44
|
-
const { metrics, dimensions, filters, sorts } = useExecution(visualization);
|
|
45
|
-
const config = useConfig();
|
|
46
|
-
const settings = useSelector(settingsSelector);
|
|
47
|
-
const useHostedAnalyticalDesigner = Boolean(settings?.enableShellApplication_analyticalDesigner);
|
|
48
|
-
const enableSecondGranularities = Boolean(settings?.enableSecondGranularities);
|
|
49
|
-
const separators = settings?.separators;
|
|
50
|
-
const [saveDialogOpen, setSaveDialogOpen] = useState(null);
|
|
51
|
-
const [hasVisError, setHasVisError] = useState(false);
|
|
52
|
-
const [visLoading, setVisLoading] = useState(true);
|
|
53
|
-
const workspaceId = useWorkspaceStrict();
|
|
54
|
-
const [isMenuButtonOpen, setMenuButtonOpen] = useState(false);
|
|
55
|
-
const [isTable, setIsTable] = useState(false);
|
|
56
|
-
const arePromptActionsDisabled = agentSwitchingActive && agentsAvailable !== true;
|
|
57
|
-
const intl = useIntl();
|
|
58
|
-
const theme = useTheme();
|
|
59
|
-
const kpiTheme = useMemo(() => ({
|
|
60
|
-
...theme,
|
|
61
|
-
kpi: {
|
|
62
|
-
...theme?.kpi,
|
|
63
|
-
primaryMeasureColor: theme?.dashboards?.content?.widget?.title?.color ?? theme?.palette?.complementary?.c8,
|
|
64
|
-
secondaryInfoColor: theme?.dashboards?.content?.widget?.title?.color ?? theme?.palette?.complementary?.c8,
|
|
65
|
-
},
|
|
66
|
-
}), [theme]);
|
|
67
|
-
const moreButtonTooltipText = intl.formatMessage({ id: "gd.gen-ai.visualisation.menu" });
|
|
68
|
-
const toggleButtonTableTooltipText = intl.formatMessage({ id: "gd.gen-ai.visualisation.toggle.table" });
|
|
69
|
-
const toggleButtonOriginalTooltipText = intl.formatMessage({
|
|
70
|
-
id: "gd.gen-ai.visualisation.toggle.original",
|
|
71
|
-
});
|
|
72
|
-
// generate unique IDs for accessibility and dropdown positioning
|
|
73
|
-
const id = useId();
|
|
74
|
-
const menuId = `menu-${id}`;
|
|
75
|
-
const dropdownAnchorClassName = `${MORE_MENU_BUTTON_ID}-${id}`;
|
|
76
|
-
const menuItems = useMemo(() => visualization?.savedVisualizationId
|
|
77
|
-
? [
|
|
78
|
-
{
|
|
79
|
-
id: "button-save",
|
|
80
|
-
title: intl.formatMessage({
|
|
81
|
-
id: "gd.gen-ai.visualisation.menu.button.save_as_new_visualisation",
|
|
82
|
-
}),
|
|
83
|
-
icon: _jsx(IconSave, { width: 16, height: 16, ariaHidden: true, color: "currentColor" }),
|
|
84
|
-
ariaAttributes: {
|
|
85
|
-
"aria-haspopup": "dialog",
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
id: "button-open",
|
|
90
|
-
title: intl.formatMessage({
|
|
91
|
-
id: "gd.gen-ai.visualisation.menu.button.open_in_analyze",
|
|
92
|
-
}),
|
|
93
|
-
icon: _jsx(IconExternalLink, { width: 16, height: 16, ariaHidden: true, color: "currentColor" }),
|
|
94
|
-
ariaAttributes: {
|
|
95
|
-
"aria-description": intl.formatMessage({
|
|
96
|
-
id: "gd.gen-ai.visualisation.menu.button.open_in_analyze.description",
|
|
97
|
-
}),
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
id: "button-copy",
|
|
102
|
-
title: intl.formatMessage({
|
|
103
|
-
id: "gd.gen-ai.visualisation.menu.button.copy_visualisation_link",
|
|
104
|
-
}),
|
|
105
|
-
icon: _jsx(IconCopy, { width: 16, height: 16, ariaHidden: true, color: "currentColor" }),
|
|
106
|
-
},
|
|
107
|
-
]
|
|
108
|
-
: [
|
|
109
|
-
{
|
|
110
|
-
id: "button-save",
|
|
111
|
-
title: intl.formatMessage({
|
|
112
|
-
id: "gd.gen-ai.visualisation.menu.button.save_as_visualisation",
|
|
113
|
-
}),
|
|
114
|
-
icon: _jsx(IconSave, { width: 16, height: 16, ariaHidden: true, color: "currentColor" }),
|
|
115
|
-
ariaAttributes: {
|
|
116
|
-
"aria-haspopup": "dialog",
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
id: "button-open",
|
|
121
|
-
title: intl.formatMessage({
|
|
122
|
-
id: "gd.gen-ai.visualisation.menu.button.open_in_analyze",
|
|
123
|
-
}),
|
|
124
|
-
icon: _jsx(IconExternalLink, { width: 16, height: 16, ariaHidden: true, color: "currentColor" }),
|
|
125
|
-
ariaAttributes: {
|
|
126
|
-
"aria-description": intl.formatMessage({
|
|
127
|
-
id: "gd.gen-ai.visualisation.menu.button.open_in_analyze.description",
|
|
128
|
-
}),
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
], [intl, visualization?.savedVisualizationId]);
|
|
132
|
-
const handleOpen = (e, vis) => {
|
|
133
|
-
if (!vis?.savedVisualizationId) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const visualizationStatus = "saved";
|
|
137
|
-
config.linkHandler?.({
|
|
138
|
-
id: vis.id,
|
|
139
|
-
type: "visualization",
|
|
140
|
-
workspaceId,
|
|
141
|
-
newTab: e.metaKey,
|
|
142
|
-
preventDefault: e.preventDefault.bind(e),
|
|
143
|
-
itemUrl: getVisualizationHref(workspaceId, vis.savedVisualizationId, visualizationStatus, useHostedAnalyticalDesigner),
|
|
144
|
-
visualizationStatus,
|
|
145
|
-
action: "open",
|
|
146
|
-
});
|
|
147
|
-
e.stopPropagation();
|
|
148
|
-
};
|
|
149
|
-
const handleButtonClick = (e, item) => {
|
|
150
|
-
switch (item.id) {
|
|
151
|
-
case "button-save":
|
|
152
|
-
setSaveDialogOpen("save");
|
|
153
|
-
setMenuButtonOpen(false);
|
|
154
|
-
break;
|
|
155
|
-
case "button-open":
|
|
156
|
-
if (visualization?.savedVisualizationId) {
|
|
157
|
-
if (config.allowNativeLinks) {
|
|
158
|
-
window.location.href = getVisualizationHref(workspaceId, visualization.savedVisualizationId, "saved", useHostedAnalyticalDesigner);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
handleOpen(e, visualization);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
setSaveDialogOpen("explore");
|
|
166
|
-
}
|
|
167
|
-
setMenuButtonOpen(false);
|
|
168
|
-
break;
|
|
169
|
-
case "button-copy":
|
|
170
|
-
if (visualization?.savedVisualizationId) {
|
|
171
|
-
const visualizationStatus = "saved";
|
|
172
|
-
let link = undefined;
|
|
173
|
-
if (config.allowNativeLinks) {
|
|
174
|
-
link = getAbsoluteVisualizationHref(workspaceId, visualization.savedVisualizationId, visualizationStatus, useHostedAnalyticalDesigner);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
link = config.linkHandler?.({
|
|
178
|
-
id: visualization.savedVisualizationId,
|
|
179
|
-
type: "visualization",
|
|
180
|
-
workspaceId,
|
|
181
|
-
newTab: e.metaKey,
|
|
182
|
-
preventDefault: e.preventDefault.bind(e),
|
|
183
|
-
itemUrl: getAbsoluteVisualizationHref(workspaceId, visualization.savedVisualizationId, visualizationStatus, useHostedAnalyticalDesigner),
|
|
184
|
-
visualizationStatus,
|
|
185
|
-
action: "copy",
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
if (link) {
|
|
189
|
-
copy(link);
|
|
190
|
-
onCopyToClipboard?.({ content: link });
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
setMenuButtonOpen(false);
|
|
194
|
-
break;
|
|
195
|
-
default:
|
|
196
|
-
// No action needed for other items
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
const handleSuccess = useCallback(() => {
|
|
201
|
-
dispatch(saveVisualisationRenderStatusAction({
|
|
202
|
-
visualizationId: visualization.id,
|
|
203
|
-
assistantMessageId: messageId,
|
|
204
|
-
status: "SUCCESSFUL",
|
|
205
|
-
}));
|
|
206
|
-
}, [dispatch, visualization?.id, messageId]);
|
|
207
|
-
const visualizationContainerRef = useRef(null);
|
|
208
|
-
const [drillState, setDrillState] = useState(null);
|
|
209
|
-
const handlerDrill = useCallback((event) => {
|
|
210
|
-
storeKdaReturnFocusFromDrillContext(event.drillContext);
|
|
211
|
-
const keyDriverData = getKdaKeyDriverCombinations({
|
|
212
|
-
type: "keyDriveAnalysis",
|
|
213
|
-
transition: "in-place",
|
|
214
|
-
origin: {},
|
|
215
|
-
}, event, enableSecondGranularities);
|
|
216
|
-
if (keyDriverData.length === 0) {
|
|
217
|
-
setDrillState(null);
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
setDrillState({ keyDriverData, event });
|
|
221
|
-
}
|
|
222
|
-
}, [enableSecondGranularities]);
|
|
223
|
-
const handleSdkError = useCallback((error) => {
|
|
224
|
-
// Ignore NO_DATA error, we still want an option to save the visualization
|
|
225
|
-
if (!isNoDataSdkError(error)) {
|
|
226
|
-
setHasVisError(true);
|
|
227
|
-
}
|
|
228
|
-
dispatch(visualizationErrorAction({
|
|
229
|
-
errorType: error.seType,
|
|
230
|
-
errorMessage: error.getMessage(),
|
|
231
|
-
}));
|
|
232
|
-
switch (error.seType) {
|
|
233
|
-
case "NO_DATA":
|
|
234
|
-
dispatch(saveVisualisationRenderStatusAction({
|
|
235
|
-
visualizationId: visualization.id,
|
|
236
|
-
assistantMessageId: messageId,
|
|
237
|
-
status: "NO_DATA",
|
|
238
|
-
}));
|
|
239
|
-
break;
|
|
240
|
-
case "DATA_TOO_LARGE_TO_COMPUTE":
|
|
241
|
-
case "DATA_TOO_LARGE_TO_DISPLAY":
|
|
242
|
-
dispatch(saveVisualisationRenderStatusAction({
|
|
243
|
-
visualizationId: visualization.id,
|
|
244
|
-
assistantMessageId: messageId,
|
|
245
|
-
status: "TOO_MANY_DATA_POINTS",
|
|
246
|
-
}));
|
|
247
|
-
break;
|
|
248
|
-
default:
|
|
249
|
-
dispatch(saveVisualisationRenderStatusAction({
|
|
250
|
-
visualizationId: visualization.id,
|
|
251
|
-
assistantMessageId: messageId,
|
|
252
|
-
status: "UNEXPECTED_ERROR",
|
|
253
|
-
}));
|
|
254
|
-
break;
|
|
255
|
-
}
|
|
256
|
-
}, [dispatch, visualization?.id, messageId]);
|
|
257
|
-
const handleLoadingChanged = useCallback(({ isLoading }) => {
|
|
258
|
-
setVisLoading(isLoading);
|
|
259
|
-
}, []);
|
|
260
|
-
const renderMenuItems = () => {
|
|
261
|
-
return (_jsx(Overlay, { alignTo: `.${dropdownAnchorClassName}`, alignPoints: overlayAlignPoints, className: "gd-gen-ai-chat__visualization__menu_overlay", closeOnMouseDrag: true, closeOnOutsideClick: true, onClose: () => setMenuButtonOpen(false), children: _jsx(UiFocusManager, { enableAutofocus: true, enableReturnFocusOnUnmount: true, enableFocusTrap: true, children: _jsx(UiMenu, { dataTestId: "gen-ai-visualization-menu-list", items: menuItems.map((item) => ({
|
|
262
|
-
type: "interactive",
|
|
263
|
-
stringTitle: item.title,
|
|
264
|
-
data: item,
|
|
265
|
-
iconLeft: item.icon,
|
|
266
|
-
id: item.id,
|
|
267
|
-
isDisabled: false,
|
|
268
|
-
ariaAttributes: item.ariaAttributes,
|
|
269
|
-
})), ariaAttributes: {
|
|
270
|
-
id: menuId,
|
|
271
|
-
}, onSelect: (item, e) => {
|
|
272
|
-
handleButtonClick(e, item.data);
|
|
273
|
-
}, onClose: () => setMenuButtonOpen(false) }) }) }, "saveVisualisationMenuButton"));
|
|
274
|
-
};
|
|
275
|
-
const moreButtonDescId = useId();
|
|
276
|
-
const drillableItems = useMemo(() => {
|
|
277
|
-
if (visualization && enableChangeAnalysis) {
|
|
278
|
-
if (visualization.visualizationType === "TABLE") {
|
|
279
|
-
return metrics.filter(Boolean).map(headerPredicate);
|
|
280
|
-
}
|
|
281
|
-
return [dimensions[0], dimensions[1]].filter(Boolean).map((x) => x.attribute.displayForm);
|
|
282
|
-
}
|
|
283
|
-
return undefined;
|
|
284
|
-
}, [dimensions, enableChangeAnalysis, metrics, visualization]);
|
|
285
|
-
const whatIfScenarios = useMemo(() => mapVisualizationWhatIfToScenarios(visualization), [visualization]);
|
|
286
|
-
const renderCurrentChart = (execConfig) => {
|
|
287
|
-
if (!visualization) {
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
if (isTable) {
|
|
291
|
-
return renderTable(intl.locale, metrics, dimensions, filters, sorts, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
292
|
-
drillableItems,
|
|
293
|
-
enableChangeAnalysis,
|
|
294
|
-
enableNewPivotTable,
|
|
295
|
-
enableAccessibleChartTooltip,
|
|
296
|
-
agGridToken: resolvedAgGridToken,
|
|
297
|
-
execConfig,
|
|
298
|
-
separators,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
switch (visualization.visualizationType) {
|
|
302
|
-
case "BAR":
|
|
303
|
-
return renderBarChart(intl.locale, metrics, dimensions, filters, sorts, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
304
|
-
enableChangeAnalysis,
|
|
305
|
-
enableAccessibleChartTooltip,
|
|
306
|
-
execConfig,
|
|
307
|
-
separators,
|
|
308
|
-
});
|
|
309
|
-
case "COLUMN":
|
|
310
|
-
return renderColumnChart(intl.locale, metrics, dimensions, filters, sorts, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
311
|
-
drillableItems,
|
|
312
|
-
enableChangeAnalysis,
|
|
313
|
-
enableAccessibleChartTooltip,
|
|
314
|
-
execConfig,
|
|
315
|
-
separators,
|
|
316
|
-
});
|
|
317
|
-
case "LINE":
|
|
318
|
-
return renderLineChart(intl.locale, visualization, metrics, dimensions, filters, sorts, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
319
|
-
drillableItems,
|
|
320
|
-
enableChangeAnalysis,
|
|
321
|
-
enableAccessibleChartTooltip,
|
|
322
|
-
execConfig,
|
|
323
|
-
separators,
|
|
324
|
-
});
|
|
325
|
-
case "PIE":
|
|
326
|
-
return renderPieChart(intl.locale, metrics, dimensions, filters, sorts, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
327
|
-
drillableItems,
|
|
328
|
-
enableChangeAnalysis,
|
|
329
|
-
enableAccessibleChartTooltip,
|
|
330
|
-
execConfig,
|
|
331
|
-
separators,
|
|
332
|
-
});
|
|
333
|
-
case "SCATTER":
|
|
334
|
-
return renderScatterPlot(intl.locale, visualization, metrics, dimensions, filters, sorts, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
335
|
-
drillableItems,
|
|
336
|
-
enableAccessibleChartTooltip,
|
|
337
|
-
execConfig,
|
|
338
|
-
separators,
|
|
339
|
-
});
|
|
340
|
-
case "TABLE":
|
|
341
|
-
return renderTable(intl.locale, metrics, dimensions, filters, sorts, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
342
|
-
drillableItems,
|
|
343
|
-
enableChangeAnalysis,
|
|
344
|
-
enableNewPivotTable,
|
|
345
|
-
enableAccessibleChartTooltip,
|
|
346
|
-
agGridToken: resolvedAgGridToken,
|
|
347
|
-
execConfig,
|
|
348
|
-
separators,
|
|
349
|
-
});
|
|
350
|
-
case "HEADLINE":
|
|
351
|
-
return renderHeadline(intl.locale, kpiTheme, metrics, dimensions, filters, colorPalette, handleSdkError, handleLoadingChanged, handleSuccess, handlerDrill, {
|
|
352
|
-
drillableItems,
|
|
353
|
-
enableChangeAnalysis,
|
|
354
|
-
execConfig,
|
|
355
|
-
separators,
|
|
356
|
-
});
|
|
357
|
-
default:
|
|
358
|
-
assertNever(visualization.visualizationType);
|
|
359
|
-
return null;
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
return (_jsxs("div", { className: className, children: [_jsx(MarkdownComponent, { allowMarkdown: useMarkdown, children: content.text }), visualization && whatIfScenarios ? (_jsx("div", { className: "gd-gen-ai-chat__visualization__what-if-group", children: whatIfScenarios.map((scenario, index) => (_jsxs("div", { className: cx("gd-gen-ai-chat__visualization", `gd-gen-ai-chat__visualization--${visualization.visualizationType.toLowerCase()}`), children: [_jsx("div", { className: "gd-gen-ai-chat__visualization__title", children: scenario.label }), _jsx("div", { className: cx("gd-gen-ai-chat__visualization__wrapper", `gd-gen-ai-chat__visualization__wrapper--${visualization.visualizationType.toLowerCase()}`), children: _jsx(VisualizationErrorBoundary, { children: renderCurrentChart(scenario.execConfig) }) })] }, index))) })) : visualization ? (_jsx(Dropdown, { enableAutoToggle: false, isOpen: Boolean(drillState), onToggle: (state) => {
|
|
363
|
-
if (!state) {
|
|
364
|
-
setDrillState(null);
|
|
365
|
-
}
|
|
366
|
-
}, closeOnEscape: true, closeOnParentScroll: true, alignPoints: [
|
|
367
|
-
{
|
|
368
|
-
align: "tl tl",
|
|
369
|
-
offset: calculateOffset(visualizationContainerRef.current, drillState?.event),
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
align: "tl tr",
|
|
373
|
-
offset: calculateOffset(visualizationContainerRef.current, drillState?.event),
|
|
374
|
-
},
|
|
375
|
-
], renderBody: () => {
|
|
376
|
-
return (_jsx(DrillSelectDropdownMenu, { drillState: drillState, onSelect: (item) => {
|
|
377
|
-
const data = item.data.context;
|
|
378
|
-
const event = drillState?.event;
|
|
379
|
-
if (!event) {
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
const allFilters = mergeFilters(convertIntersectionToAttributeFilters(event.drillContext.intersection ?? []), filters
|
|
383
|
-
.map(getDashboardAttributeFilter)
|
|
384
|
-
.filter(Boolean));
|
|
385
|
-
const definition = createKdaDefinitionFromDrill(intl.locale, data, event, allFilters);
|
|
386
|
-
setKeyDriverAnalysis?.({ keyDriverAnalysis: definition });
|
|
387
|
-
}, onClose: () => {
|
|
388
|
-
setDrillState(null);
|
|
389
|
-
} }));
|
|
390
|
-
}, renderButton: () => {
|
|
391
|
-
return (_jsxs("div", { ref: visualizationContainerRef, className: cx("gd-gen-ai-chat__visualization", `gd-gen-ai-chat__visualization--${visualization.visualizationType.toLowerCase()}`, {
|
|
392
|
-
active: isMenuButtonOpen,
|
|
393
|
-
}), children: [config.canAnalyze && !hasVisError
|
|
394
|
-
? (() => {
|
|
395
|
-
return (_jsxs("div", { className: cx("gd-gen-ai-chat__visualization__buttons"), children: [visualization.visualizationType === "TABLE" ? null : (_jsx("div", { className: cx("gd-gen-ai-chat__visualization__table"), children: _jsx(UiTooltip, { triggerBy: ["focus", "hover"], arrowPlacement: "bottom", anchor: _jsx(UiIconButton, { dataTestId: "gen-ai-visualization-toggle-button", onClick: () => {
|
|
396
|
-
setIsTable(!isTable);
|
|
397
|
-
}, icon: isTable ? "visualization" : "table", accessibilityConfig: {
|
|
398
|
-
role: "button",
|
|
399
|
-
ariaLabel: isTable
|
|
400
|
-
? toggleButtonOriginalTooltipText
|
|
401
|
-
: toggleButtonTableTooltipText,
|
|
402
|
-
} }), content: isTable
|
|
403
|
-
? toggleButtonOriginalTooltipText
|
|
404
|
-
: toggleButtonTableTooltipText }) })), _jsxs("div", { id: MORE_MENU_BUTTON_ID, className: cx("gd-gen-ai-chat__visualization__save", dropdownAnchorClassName), children: [_jsx(UiTooltip, { disabled: !moreButtonTooltipText, triggerBy: ["focus", "hover"], arrowPlacement: "bottom", anchor: _jsx(UiIconButton, { dataTestId: "gen-ai-visualization-menu-button", onClick: () => setMenuButtonOpen(!isMenuButtonOpen), icon: "ellipsis", isDisabled: visLoading, accessibilityConfig: {
|
|
405
|
-
role: "button",
|
|
406
|
-
ariaLabel: moreButtonTooltipText,
|
|
407
|
-
ariaDescribedBy: moreButtonDescId,
|
|
408
|
-
isExpanded: isMenuButtonOpen,
|
|
409
|
-
popupId: menuId,
|
|
410
|
-
ariaHaspopup: "menu",
|
|
411
|
-
}, isActive: isMenuButtonOpen }), content: moreButtonTooltipText }), isMenuButtonOpen ? renderMenuItems() : null] })] }));
|
|
412
|
-
})()
|
|
413
|
-
: null, _jsx("div", { className: "gd-gen-ai-chat__visualization__title", id: moreButtonDescId, children: _jsx(MarkdownComponent, { allowMarkdown: useMarkdown, children: visualization.title }) }), _jsx("div", { className: cx("gd-gen-ai-chat__visualization__wrapper", `gd-gen-ai-chat__visualization__wrapper--${isTable ? "table" : visualization.visualizationType.toLowerCase()}`), children: _jsx(VisualizationErrorBoundary, { children: renderCurrentChart() }) }), saveDialogOpen ? (_jsx(VisualizationSaveDialog, { onClose: () => setSaveDialogOpen(null), visualization: visualization, type: saveDialogOpen, messageId: messageId })) : null, drillState ? (_jsx("div", { className: "gd-gen-ai-chat__visualization__drill_overlay" })) : null] }));
|
|
414
|
-
} })) : null, showSuggestions && !whatIfScenarios && visualization?.suggestions?.length ? (_jsx("div", { className: "gd-gen-ai-chat__visualization__suggestions", children: visualization.suggestions.map((suggestion) => (_jsx(UiButton, { label: suggestion.label, variant: "secondary", size: "small", isDisabled: arePromptActionsDisabled, onClick: () => {
|
|
415
|
-
dispatch(newMessageAction(makeUserMessage([makeTextContents(suggestion.query, [])])));
|
|
416
|
-
}, tooltip: suggestion.query }, suggestion.label))) })) : null] }));
|
|
417
|
-
}
|
|
418
|
-
const visualizationTooltipOptions = {
|
|
419
|
-
tooltip: {
|
|
420
|
-
className: "gd-gen-ai-chat__vis_tooltip",
|
|
421
|
-
},
|
|
422
|
-
};
|
|
423
|
-
const legendTooltipOptions = {
|
|
424
|
-
legend: {
|
|
425
|
-
responsive: "autoPositionWithPopup",
|
|
426
|
-
},
|
|
427
|
-
};
|
|
428
|
-
const renderBarChart = (locale, metrics, dimensions, filters, sortBy, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => (_jsx(BarChart, { locale: locale, height: VIS_HEIGHT, measures: metrics, viewBy: [dimensions[0], dimensions[1]].filter(Boolean), stackBy: metrics.length <= 1 ? dimensions[2] : undefined, sortBy: sortBy, config: {
|
|
429
|
-
...visualizationTooltipOptions,
|
|
430
|
-
...legendTooltipOptions,
|
|
431
|
-
colorPalette,
|
|
432
|
-
separators: props.separators,
|
|
433
|
-
// Better visibility with stacked bars if there are multiple metrics and dimensions
|
|
434
|
-
stackMeasures: metrics.length > 1 && dimensions.length === 2,
|
|
435
|
-
enableAccessibleTooltip: props.enableAccessibleChartTooltip,
|
|
436
|
-
}, drillableItems: props.drillableItems, onDrill: onDrill, filters: filters, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
437
|
-
const renderColumnChart = (locale, metrics, dimensions, filters, sortBy, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => (_jsx(ColumnChart, { locale: locale, height: VIS_HEIGHT, measures: metrics, viewBy: [dimensions[0], dimensions[1]].filter(Boolean), stackBy: metrics.length <= 1 ? dimensions[2] : undefined, sortBy: sortBy, config: {
|
|
438
|
-
...visualizationTooltipOptions,
|
|
439
|
-
...legendTooltipOptions,
|
|
440
|
-
colorPalette,
|
|
441
|
-
separators: props.separators,
|
|
442
|
-
// Better visibility with stacked bars if there are multiple metrics and dimensions
|
|
443
|
-
stackMeasures: metrics.length > 1 && dimensions.length === 2,
|
|
444
|
-
enableAccessibleTooltip: props.enableAccessibleChartTooltip,
|
|
445
|
-
}, drillableItems: props.drillableItems, onDrill: onDrill, filters: filters, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
446
|
-
const renderLineChart = (locale, visualization, metrics, dimensions, filters, sortBy, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => {
|
|
447
|
-
const forecast = mapVisualizationForecastToChartConfig(visualization);
|
|
448
|
-
const forecastConfig = mapVisualizationForecastToBackendConfig(visualization);
|
|
449
|
-
const anomalies = mapVisualizationAnomalyDetectionToChartConfig(visualization.config);
|
|
450
|
-
const outliersConfig = mapVisualizationAnomalyDetectionToBackendConfig(visualization.config);
|
|
451
|
-
return (_jsx(LineChart, { locale: locale, height: VIS_HEIGHT, measures: metrics, trendBy: dimensions[0], segmentBy: metrics.length <= 1 ? dimensions[1] : undefined, filters: filters, sortBy: sortBy, config: {
|
|
452
|
-
...visualizationTooltipOptions,
|
|
453
|
-
...legendTooltipOptions,
|
|
454
|
-
colorPalette,
|
|
455
|
-
separators: props.separators,
|
|
456
|
-
enableAccessibleTooltip: props.enableAccessibleChartTooltip,
|
|
457
|
-
...(forecastConfig && forecast ? { forecast } : {}),
|
|
458
|
-
...(outliersConfig && anomalies ? { anomalies } : {}),
|
|
459
|
-
}, forecastConfig: forecastConfig, outliersConfig: outliersConfig, drillableItems: props.drillableItems, onDrill: onDrill, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
460
|
-
};
|
|
461
|
-
const renderPieChart = (locale, metrics, dimensions, filters, sortBy, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => (_jsx(PieChart, { locale: locale, height: VIS_HEIGHT, measures: metrics, viewBy: metrics.length <= 1 ? dimensions[0] : undefined, filters: filters, sortBy: sortBy, config: {
|
|
462
|
-
...visualizationTooltipOptions,
|
|
463
|
-
colorPalette,
|
|
464
|
-
separators: props.separators,
|
|
465
|
-
enableAccessibleTooltip: props.enableAccessibleChartTooltip,
|
|
466
|
-
}, drillableItems: props.drillableItems, onDrill: onDrill, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
467
|
-
const renderScatterPlot = (locale, visualization, metrics, dimensions, filters, sortBy, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => {
|
|
468
|
-
const clustering = mapVisualizationClusteringToChartConfig(visualization.config);
|
|
469
|
-
const clusteringConfig = mapVisualizationClusteringToBackendConfig(visualization.config);
|
|
470
|
-
return (_jsx(ScatterPlot, { locale: locale, height: VIS_HEIGHT, xAxisMeasure: metrics[0], yAxisMeasure: metrics[1], attribute: dimensions[0], segmentBy: dimensions[1], filters: filters, sortBy: sortBy, config: {
|
|
471
|
-
...visualizationTooltipOptions,
|
|
472
|
-
...legendTooltipOptions,
|
|
473
|
-
colorPalette,
|
|
474
|
-
separators: props.separators,
|
|
475
|
-
enableAccessibleTooltip: props.enableAccessibleChartTooltip,
|
|
476
|
-
...(clusteringConfig && clustering ? { clustering } : {}),
|
|
477
|
-
}, drillableItems: props.drillableItems, onDrill: onDrill, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
478
|
-
};
|
|
479
|
-
const renderTable = (locale, metrics, dimensions, filters, sortBy, onError, onLoadingChanged, onSuccess, onDrill, props) => {
|
|
480
|
-
const TableComponent = props.enableNewPivotTable ? PivotTableNext : PivotTable;
|
|
481
|
-
return (_jsx(TableComponent, { locale: locale, measures: metrics, rows: dimensions, filters: filters, sortBy: sortBy, config: props.enableNewPivotTable
|
|
482
|
-
? { agGridToken: props.agGridToken, separators: props.separators }
|
|
483
|
-
: { separators: props.separators }, drillableItems: props.drillableItems, onDrill: onDrill, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }));
|
|
484
|
-
};
|
|
485
|
-
const renderHeadline = (locale, theme, metrics, _dimensions, filters, colorPalette, onError, onLoadingChanged, onSuccess, onDrill, props) => {
|
|
486
|
-
return (_jsx(ScopedThemeProvider, { theme: theme, children: _jsx(Headline, { locale: locale, primaryMeasure: metrics[0], secondaryMeasures: [metrics[1], metrics[2]].filter(Boolean), filters: filters, config: {
|
|
487
|
-
...visualizationTooltipOptions,
|
|
488
|
-
...getHeadlineComparison(metrics),
|
|
489
|
-
colorPalette,
|
|
490
|
-
separators: props.separators,
|
|
491
|
-
}, drillableItems: props.drillableItems, onDrill: onDrill, onError: onError, onLoadingChanged: onLoadingChanged, onExportReady: onSuccess, execConfig: props.execConfig }) }));
|
|
492
|
-
};
|
|
493
|
-
function calculateOffset(container, drillEvent) {
|
|
494
|
-
const offest = getRelativeOffset(drillEvent?.target, container);
|
|
495
|
-
return {
|
|
496
|
-
y: offest.y + (drillEvent?.chartY ?? 0),
|
|
497
|
-
x: offest.x + (drillEvent?.chartX ?? 0),
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
function getRelativeOffset(child, ancestor) {
|
|
501
|
-
if (!child || !ancestor) {
|
|
502
|
-
return { x: 0, y: 0 };
|
|
503
|
-
}
|
|
504
|
-
const c = child.getBoundingClientRect();
|
|
505
|
-
const a = ancestor.getBoundingClientRect();
|
|
506
|
-
return {
|
|
507
|
-
x: c.left - a.left,
|
|
508
|
-
y: c.top - a.top,
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
function headerPredicate(m) {
|
|
512
|
-
return (header) => {
|
|
513
|
-
if (isMeasureDescriptor(header)) {
|
|
514
|
-
return header.measureHeaderItem.localIdentifier === m.measure.localIdentifier;
|
|
515
|
-
}
|
|
516
|
-
return false;
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
export function VisualizationContentsComponent(props) {
|
|
520
|
-
const dispatch = useDispatch();
|
|
521
|
-
const settings = useSelector(settingsSelector);
|
|
522
|
-
const colorPalette = useSelector(colorPaletteSelector);
|
|
523
|
-
const agentSwitchingActive = useSelector(agentSwitchingActiveSelector);
|
|
524
|
-
const agentsAvailable = useSelector(agentsAvailableSelector);
|
|
525
|
-
const onCopyToClipboard = useCallback((...args) => {
|
|
526
|
-
dispatch(copyToClipboardAction(...args));
|
|
527
|
-
}, [dispatch]);
|
|
528
|
-
const setKeyDriverAnalysis = useCallback((...args) => {
|
|
529
|
-
dispatch(setKeyDriverAnalysisAction(...args));
|
|
530
|
-
}, [dispatch]);
|
|
531
|
-
return (_jsx(VisualizationContentsComponentCore, { ...props, colorPalette: colorPalette, enableNewPivotTable: settings?.enableNewPivotTable, enableAccessibleChartTooltip: settings?.enableAccessibleChartTooltip, enableChangeAnalysis: settings?.enableChangeAnalysis, agentSwitchingActive: agentSwitchingActive, agGridToken: settings?.agGridToken, agentsAvailable: agentsAvailable, onCopyToClipboard: onCopyToClipboard, setKeyDriverAnalysis: setKeyDriverAnalysis }));
|
|
532
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type IGenAIVisualization } from "@gooddata/sdk-model";
|
|
2
|
-
import { saveVisualizationAction as saveVisualizationActionCreator } from "../../../store/messages/messagesSlice.js";
|
|
3
|
-
export type VisualizationSaveDialogProps = {
|
|
4
|
-
onClose: () => void;
|
|
5
|
-
visualization: IGenAIVisualization;
|
|
6
|
-
messageId: string;
|
|
7
|
-
type: "save" | "explore";
|
|
8
|
-
};
|
|
9
|
-
export type VisualizationSaveDialogDispatchProps = {
|
|
10
|
-
saveVisualizationAction: (...args: Parameters<typeof saveVisualizationActionCreator>) => void;
|
|
11
|
-
};
|
|
12
|
-
export declare function VisualizationSaveDialog(props: VisualizationSaveDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
//# sourceMappingURL=VisualizationSaveDialog.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VisualizationSaveDialog.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/contents/VisualizationSaveDialog.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG/D,OAAO,EAAE,uBAAuB,IAAI,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAIrH,MAAM,MAAM,4BAA4B,GAAG;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,mBAAmB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IAC/C,uBAAuB,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,8BAA8B,CAAC,KAAK,IAAI,CAAC;CACjG,CAAC;AA4DF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,2CAW1E"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// (C) 2024-2026 GoodData Corporation
|
|
3
|
-
import { useCallback, useState } from "react";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
|
-
import { useDispatch } from "react-redux";
|
|
6
|
-
import { ConfirmDialog, Input, Typography } from "@gooddata/sdk-ui-kit";
|
|
7
|
-
import { saveVisualizationAction as saveVisualizationActionCreator } from "../../../store/messages/messagesSlice.js";
|
|
8
|
-
import { useVisualisationSaving } from "./hooks/useVisualisationSaving.js";
|
|
9
|
-
function VisualizationSaveDialogCore({ onClose, visualization, messageId, saveVisualizationAction, type, }) {
|
|
10
|
-
const intl = useIntl();
|
|
11
|
-
const [value, setValue] = useState(visualization.title);
|
|
12
|
-
const { setSavingStarted } = useVisualisationSaving(visualization, onClose);
|
|
13
|
-
return (_jsxs(ConfirmDialog, { onClose: onClose, onCancel: onClose, onSubmit: () => {
|
|
14
|
-
setSavingStarted(true);
|
|
15
|
-
saveVisualizationAction({
|
|
16
|
-
visualizationId: visualization.id,
|
|
17
|
-
visualizationTitle: value || visualization.title,
|
|
18
|
-
assistantMessageId: messageId,
|
|
19
|
-
explore: type === "explore",
|
|
20
|
-
});
|
|
21
|
-
}, isPositive: true, autofocusOnOpen: false, submitOnEnterKey: true, headline: intl.formatMessage({ id: "gd.gen-ai.save-dialog.title" }), cancelButtonText: intl.formatMessage({ id: "gd.gen-ai.button.cancel" }), submitButtonText: type === "save"
|
|
22
|
-
? intl.formatMessage({ id: "gd.gen-ai.button.save" })
|
|
23
|
-
: intl.formatMessage({ id: "gd.gen-ai.button.save_and_explore" }), showProgressIndicator: visualization.saving, isSubmitDisabled: visualization.saving, isCancelDisabled: visualization.saving, className: "gd-gen-ai-chat__visualization__save-dialog", children: [_jsx(Typography, { tagName: "p", children: type === "save"
|
|
24
|
-
? intl.formatMessage({ id: "gd.gen-ai.save-dialog.description" })
|
|
25
|
-
: intl.formatMessage({ id: "gd.gen-ai.save-dialog.description.explore" }) }), _jsx(Input, { autofocus: true, label: intl.formatMessage({ id: "gd.gen-ai.save-dialog.label" }), labelPositionTop: true, placeholder: visualization.title, value: value, disabled: visualization.saving, onChange: (newValue) => setValue(String(newValue)) })] }));
|
|
26
|
-
}
|
|
27
|
-
export function VisualizationSaveDialog(props) {
|
|
28
|
-
const dispatch = useDispatch();
|
|
29
|
-
const saveVisualization = useCallback((...args) => {
|
|
30
|
-
dispatch(saveVisualizationActionCreator(...args));
|
|
31
|
-
}, [dispatch]);
|
|
32
|
-
return _jsx(VisualizationSaveDialogCore, { ...props, saveVisualizationAction: saveVisualization });
|
|
33
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type IGenAIVisualization } from "@gooddata/sdk-model";
|
|
2
|
-
export declare function useVisualisationSaving(visualization: IGenAIVisualization, onClose: () => void): {
|
|
3
|
-
setSavingStarted: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
4
|
-
savingStarted: boolean;
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=useVisualisationSaving.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useVisualisationSaving.d.ts","sourceRoot":"","sources":["../../../../../src/components/messages/contents/hooks/useVisualisationSaving.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,IAAI;;;EAgB7F"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// (C) 2025 GoodData Corporation
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
export function useVisualisationSaving(visualization, onClose) {
|
|
4
|
-
const [savingStarted, setSavingStarted] = useState(false);
|
|
5
|
-
// Close the dialog automatically once the item is saved
|
|
6
|
-
const isSaving = visualization.saving;
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
if (savingStarted && !isSaving) {
|
|
9
|
-
setSavingStarted(false);
|
|
10
|
-
onClose();
|
|
11
|
-
}
|
|
12
|
-
}, [savingStarted, isSaving, onClose]);
|
|
13
|
-
return {
|
|
14
|
-
setSavingStarted,
|
|
15
|
-
savingStarted,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { type IAttribute, type IFilter, type IGenAIVisualization, type IMeasure, type IMeasureDefinition, type ISortItem } from "@gooddata/sdk-model";
|
|
2
|
-
export declare const useExecution: (vis?: IGenAIVisualization) => {
|
|
3
|
-
metrics: IMeasure<IMeasureDefinition>[];
|
|
4
|
-
dimensions: IAttribute[];
|
|
5
|
-
filters: IFilter[];
|
|
6
|
-
sorts: ISortItem[];
|
|
7
|
-
};
|
|
8
|
-
export declare const prepareExecution: (vis: IGenAIVisualization) => {
|
|
9
|
-
metrics: IMeasure<IMeasureDefinition>[];
|
|
10
|
-
dimensions: IAttribute[];
|
|
11
|
-
filters: IFilter[];
|
|
12
|
-
sorts: ISortItem[];
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=useExecution.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useExecution.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/contents/useExecution.tsx"],"names":[],"mappings":"AAIA,OAAO,EAUH,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,mBAAmB,EAExB,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,SAAS,EAgBjB,MAAM,qBAAqB,CAAC;AAwB7B,eAAO,MAAM,YAAY,SAAU,mBAAmB;;;;;CAarD,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAS,mBAAmB;;;;;CAgBxD,CAAC"}
|