@gooddata/sdk-ui-gen-ai 11.49.0-alpha.0 → 11.49.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/esm/components/GenAIChatContextIndicator.d.ts.map +1 -1
- package/esm/components/GenAIChatContextIndicator.js +5 -2
- package/esm/components/GenAIChatDialogConnected.d.ts +5 -1
- package/esm/components/GenAIChatDialogConnected.d.ts.map +1 -1
- package/esm/components/GenAIChatDialogConnected.js +7 -2
- package/esm/components/GenAIStandaloneInput.d.ts +39 -0
- package/esm/components/GenAIStandaloneInput.d.ts.map +1 -0
- package/esm/components/GenAIStandaloneInput.js +74 -0
- package/esm/components/GenAiChatAgentSwitching.d.ts +3 -2
- package/esm/components/GenAiChatAgentSwitching.d.ts.map +1 -1
- package/esm/components/GenAiChatAgentSwitching.js +2 -2
- package/esm/components/GenAiChatContextChooser.js +1 -1
- package/esm/components/Input.d.ts.map +1 -1
- package/esm/components/Input.js +8 -35
- package/esm/components/completion/plugins/rehype-references.d.ts.map +1 -1
- package/esm/components/completion/plugins/rehype-references.js +1 -0
- package/esm/components/completion/utils.d.ts +1 -1
- package/esm/components/completion/utils.d.ts.map +1 -1
- package/esm/components/completion/utils.js +9 -1
- package/esm/components/hooks/useContextItems.d.ts.map +1 -1
- package/esm/components/hooks/useContextItems.js +7 -4
- package/esm/components/hooks/useInputAutofocus.d.ts +5 -0
- package/esm/components/hooks/useInputAutofocus.d.ts.map +1 -0
- package/esm/components/hooks/useInputAutofocus.js +27 -0
- package/esm/components/messages/ConversationItemContents.d.ts.map +1 -1
- package/esm/components/messages/ConversationItemContents.js +4 -0
- package/esm/components/messages/conversationContents/ConversationAlertProposalContent.js +1 -1
- package/esm/components/messages/conversationContents/ConversationDashboardContent.d.ts +10 -0
- package/esm/components/messages/conversationContents/ConversationDashboardContent.d.ts.map +1 -0
- package/esm/components/messages/conversationContents/ConversationDashboardContent.js +26 -0
- package/esm/components/utils/agentSelection.d.ts +2 -2
- package/esm/components/utils/agentSelection.d.ts.map +1 -1
- package/esm/components/utils/agentSelection.js +2 -2
- package/esm/components/utils/icons.d.ts.map +1 -1
- package/esm/components/utils/icons.js +1 -0
- package/esm/context/collectContextReferences.d.ts +2 -2
- package/esm/context/collectContextReferences.d.ts.map +1 -1
- package/esm/context/collectContextReferences.js +8 -8
- package/esm/context/dashboard.d.ts +1 -1
- package/esm/context/dashboard.d.ts.map +1 -1
- package/esm/context/dashboard.js +3 -0
- package/esm/hooks/useGenAIStandaloneInputData.d.ts +11 -0
- package/esm/hooks/useGenAIStandaloneInputData.d.ts.map +1 -0
- package/esm/hooks/useGenAIStandaloneInputData.js +26 -0
- package/esm/internal.d.ts +3 -2
- package/esm/internal.d.ts.map +1 -1
- package/esm/internal.js +3 -2
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +20 -0
- package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +20 -0
- package/esm/model.d.ts +1 -1
- package/esm/model.d.ts.map +1 -1
- package/esm/sdk-ui-gen-ai.d.ts +1 -1
- package/esm/store/messages/messagesSlice.d.ts +9 -5
- package/esm/store/messages/messagesSlice.d.ts.map +1 -1
- package/esm/store/messages/messagesSlice.js +5 -1
- package/esm/store/sideEffects/onThreadLoad.d.ts.map +1 -1
- package/esm/store/sideEffects/onThreadLoad.js +30 -1
- package/package.json +20 -20
- package/styles/css/animation.css +1 -0
- package/styles/css/animation.css.map +1 -1
- package/styles/css/input.css +3 -0
- package/styles/css/input.css.map +1 -1
- package/styles/css/main.css +129 -15
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +125 -15
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/animation.scss +1 -0
- package/styles/scss/input.scss +3 -0
- package/styles/scss/messages.scss +36 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAIChatContextIndicator.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatContextIndicator.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAe,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"GenAIChatContextIndicator.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatContextIndicator.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAe,MAAM,OAAO,CAAC;AAc7C,KAAK,iCAAiC,GAAG;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AA2DF,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,iCAAiC,CAG5C,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
3
|
import { useCallback } from "react";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
4
5
|
import { connect, useSelector } from "react-redux";
|
|
5
6
|
import { UiChip } from "@gooddata/sdk-ui-kit";
|
|
6
7
|
import { collectContextReferences } from "../context/collectContextReferences.js";
|
|
@@ -16,8 +17,10 @@ import { getIconByType } from "./utils/icons.js";
|
|
|
16
17
|
* @internal
|
|
17
18
|
*/
|
|
18
19
|
function GenAIChatContextIndicatorCore({ removeContextReference, onDelete, }) {
|
|
20
|
+
const intl = useIntl();
|
|
21
|
+
const emptyReferenceLabel = intl.formatMessage({ id: "gd.gen-ai.context.untitled" });
|
|
19
22
|
const context = useSelector(userContextSelector);
|
|
20
|
-
const references = collectContextReferences(context);
|
|
23
|
+
const references = collectContextReferences(context, emptyReferenceLabel);
|
|
21
24
|
const onDeleteHandler = useCallback((reference) => {
|
|
22
25
|
return () => {
|
|
23
26
|
removeContextReference({ object: reference });
|
|
@@ -27,7 +30,7 @@ function GenAIChatContextIndicatorCore({ removeContextReference, onDelete, }) {
|
|
|
27
30
|
if (references.length === 0) {
|
|
28
31
|
return null;
|
|
29
32
|
}
|
|
30
|
-
return (_jsx("div", { className: "gd-gen-ai-chat__context-indicator", "aria-live": "polite", children: references.map((reference, index) => (_jsx(UiChip, { ...getIconByType(reference.type), label: reference.title, isExpandable: false,
|
|
33
|
+
return (_jsx("div", { className: "gd-gen-ai-chat__context-indicator", "aria-live": "polite", children: references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...getIconByType(reference.type), label: reference.title, isExpandable: false, onDelete: onDeleteHandler(reference) }, index))) }));
|
|
31
34
|
}
|
|
32
35
|
const mapDispatchToProps = {
|
|
33
36
|
removeContextReference: removeContextReferenceAction,
|
|
@@ -79,6 +79,10 @@ export interface IGenAIChatDialogConnectedProps {
|
|
|
79
79
|
* Pass `undefined` to clear it (e.g. when the user leaves the dashboard).
|
|
80
80
|
*/
|
|
81
81
|
ambientUserContext?: IGenAIUserContext;
|
|
82
|
+
/**
|
|
83
|
+
* Agent ID to use for the seeded question. If not provided, the default agent will be used.
|
|
84
|
+
*/
|
|
85
|
+
agentId?: string;
|
|
82
86
|
/** When true, the seeded question is appended to the existing thread instead of clearing it first. */
|
|
83
87
|
appendToChat?: boolean;
|
|
84
88
|
/** When true, the user context is replaced instead of merged with the existing one. */
|
|
@@ -113,5 +117,5 @@ export interface IGenAIChatDialogConnectedProps {
|
|
|
113
117
|
*
|
|
114
118
|
* @internal
|
|
115
119
|
*/
|
|
116
|
-
export declare function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, ambientUserContext, appendToChat, replaceUserContext, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks, onLinkClick, returnFocusTo }: IGenAIChatDialogConnectedProps): import("react/jsx-runtime").JSX.Element;
|
|
120
|
+
export declare function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, agentId, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, ambientUserContext, appendToChat, replaceUserContext, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks, onLinkClick, returnFocusTo }: IGenAIChatDialogConnectedProps): import("react/jsx-runtime").JSX.Element;
|
|
117
121
|
//# sourceMappingURL=GenAIChatDialogConnected.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAIChatDialogConnected.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialogConnected.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAqD,MAAM,OAAO,CAAC;AAE1F,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI7F,OAAO,EACH,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EACd,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,+BAA+B,EACpC,KAAK,iCAAiC,EACtC,KAAK,oBAAoB,EAW5B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"GenAIChatDialogConnected.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialogConnected.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { makeTextContents, makeUserItem, makeUserMessage } from "../model.js";
|
|
5
5
|
import { setAmbientUserContextAction, setUserContextAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
6
6
|
import { isChatAssistantMessageEvent, isChatClosedEvent, isChatCopyToClipboardEvent, isChatFeedbackErrorEvent, isChatFeedbackEvent, isChatOpenedEvent, isChatResetEvent, isChatSaveVisualizationErrorEvent, isChatSaveVisualizationSuccessEvent, isChatUserMessageEvent, } from "../store/events.js";
|
|
7
|
-
import { clearThreadAction, newMessageAction } from "../store/messages/messagesSlice.js";
|
|
7
|
+
import { clearThreadAction, newMessageAction, setSelectedAgentAction, } from "../store/messages/messagesSlice.js";
|
|
8
8
|
import { GenAIChatDialog } from "./GenAIChatDialog.js";
|
|
9
9
|
/**
|
|
10
10
|
* A "connected" wrapper over {@link GenAIChatDialog} that centralizes the wiring every consumer otherwise
|
|
@@ -17,7 +17,7 @@ import { GenAIChatDialog } from "./GenAIChatDialog.js";
|
|
|
17
17
|
*
|
|
18
18
|
* @internal
|
|
19
19
|
*/
|
|
20
|
-
export function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, ambientUserContext, appendToChat, replaceUserContext, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks = true, onLinkClick, returnFocusTo, }) {
|
|
20
|
+
export function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, agentId, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, ambientUserContext, appendToChat, replaceUserContext, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks = true, onLinkClick, returnFocusTo, }) {
|
|
21
21
|
const defaultLinkClick = useCallback(({ itemUrl, newTab, preventDefault }) => {
|
|
22
22
|
if (itemUrl) {
|
|
23
23
|
preventDefault();
|
|
@@ -113,6 +113,10 @@ export function GenAIChatDialogConnected({ backend, workspace, locale, canManage
|
|
|
113
113
|
if (clear) {
|
|
114
114
|
chatDispatcher(clearThreadAction());
|
|
115
115
|
}
|
|
116
|
+
// Agent id override
|
|
117
|
+
if (userContext || askedQuestion) {
|
|
118
|
+
chatDispatcher(setSelectedAgentAction({ agentId }));
|
|
119
|
+
}
|
|
116
120
|
// Always set (and thereby clear when undefined) so a follow-up ask without context does not
|
|
117
121
|
// inherit the previous ask's user context (LX-2544).
|
|
118
122
|
chatDispatcher(setUserContextAction({ userContext, replaceUserContext }));
|
|
@@ -127,6 +131,7 @@ export function GenAIChatDialogConnected({ backend, workspace, locale, canManage
|
|
|
127
131
|
}
|
|
128
132
|
}, [
|
|
129
133
|
isOpen,
|
|
134
|
+
agentId,
|
|
130
135
|
chatDispatcher,
|
|
131
136
|
askedQuestion,
|
|
132
137
|
askSeq,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type GenAiStoreProps } from "./GenAiStore.js";
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export type GenAIStandaloneInputProps = Omit<GenAiStoreProps, "children"> & {
|
|
6
|
+
/**
|
|
7
|
+
* Callback called when the user submits a message.
|
|
8
|
+
*/
|
|
9
|
+
onStart?: (prompt: string, agentId?: string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Callback called when the user sets an agent.
|
|
12
|
+
*/
|
|
13
|
+
onAgentSet?: (agentId: string) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Additional class name for the input container.
|
|
16
|
+
*/
|
|
17
|
+
className?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the user has manage permissions.
|
|
20
|
+
*/
|
|
21
|
+
canManage?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the user has analyze permissions.
|
|
24
|
+
*/
|
|
25
|
+
canAnalyze?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Locale for the component.
|
|
28
|
+
*/
|
|
29
|
+
locale?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the input should autofocus.
|
|
32
|
+
*/
|
|
33
|
+
autofocus?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare function GenAIStandaloneInput(props: GenAIStandaloneInputProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=GenAIStandaloneInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenAIStandaloneInput.d.ts","sourceRoot":"","sources":["../../src/components/GenAIStandaloneInput.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAWnE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACxE;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AA0FF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,2CAYpE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import cx from "classnames";
|
|
5
|
+
import { defineMessages, useIntl } from "react-intl";
|
|
6
|
+
import { useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
7
|
+
import { SyntaxHighlightingInput } from "@gooddata/sdk-ui-kit";
|
|
8
|
+
import { useGenAIStandaloneInputData } from "../hooks/useGenAIStandaloneInputData.js";
|
|
9
|
+
import { IntlWrapper } from "../localization/IntlWrapper.js";
|
|
10
|
+
import { useCompletion } from "./completion/useCompletion.js";
|
|
11
|
+
import { GenAiChatAgentSwitching } from "./GenAiChatAgentSwitching.js";
|
|
12
|
+
import { GenAiStore } from "./GenAiStore.js";
|
|
13
|
+
import { useHighlight } from "./highlight/useHighlight.js";
|
|
14
|
+
import { useFullscreenCheck } from "./hooks/useFullscreenCheck.js";
|
|
15
|
+
import { useInputAutofocus } from "./hooks/useInputAutofocus.js";
|
|
16
|
+
const msgs = defineMessages({
|
|
17
|
+
placeholder: {
|
|
18
|
+
id: "gd.gen-ai.input-placeholder",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
function StandaloneInputContent({ onStart, onAgentSet, className, canManage, canAnalyze, autofocus = true, }) {
|
|
22
|
+
const intl = useIntl();
|
|
23
|
+
const [value, setValue] = useState("");
|
|
24
|
+
const [editorApi, setApi] = useState(null);
|
|
25
|
+
const { selectedAgentId, agentSwitchingEnabled } = useGenAIStandaloneInputData();
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (selectedAgentId) {
|
|
28
|
+
onAgentSet?.(selectedAgentId);
|
|
29
|
+
}
|
|
30
|
+
}, [selectedAgentId, onAgentSet]);
|
|
31
|
+
const { isFullscreen, isBigScreen, isSmallScreen } = useFullscreenCheck();
|
|
32
|
+
const { onCompletion, used } = useCompletion([], { canManage, canAnalyze });
|
|
33
|
+
const { highlightExtension, atomicCursorExtension } = useHighlight(used);
|
|
34
|
+
const beforeExtensions = useMemo(() => [atomicCursorExtension], [atomicCursorExtension]);
|
|
35
|
+
const extensions = useMemo(() => [highlightExtension], [highlightExtension]);
|
|
36
|
+
// Force focus when autofocus is enables on the first mount, right after the initial state is loaded
|
|
37
|
+
const ref = useInputAutofocus(editorApi, autofocus, { isBusy: false });
|
|
38
|
+
const handleSubmit = useCallback(() => {
|
|
39
|
+
const trimmed = value.trim();
|
|
40
|
+
if (trimmed) {
|
|
41
|
+
onStart?.(trimmed, selectedAgentId);
|
|
42
|
+
setValue("");
|
|
43
|
+
}
|
|
44
|
+
}, [value, selectedAgentId, onStart]);
|
|
45
|
+
const handleKeyDown = (e) => {
|
|
46
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
47
|
+
const trimmed = value.trim();
|
|
48
|
+
if (trimmed) {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
e.stopPropagation();
|
|
51
|
+
handleSubmit();
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
return (_jsx("div", { className: cx("gd-gen-ai-chat__input", className, {
|
|
58
|
+
"gd-gen-ai-chat__input--fullscreen": isFullscreen,
|
|
59
|
+
"gd-gen-ai-chat__input--big-screen": isBigScreen,
|
|
60
|
+
"gd-gen-ai-chat__input--small-screen": isSmallScreen,
|
|
61
|
+
"gd-gen-ai-chat__input--agent-switching": agentSwitchingEnabled,
|
|
62
|
+
}), children: _jsx("div", { className: "gd-gen-ai-chat__input__content", children: _jsxs("div", { className: "gd-gen-ai-chat__input__container", children: [
|
|
63
|
+
_jsx("div", { className: "gd-gen-ai-chat__input__text", ...ref, children: _jsx(SyntaxHighlightingInput, { className: "gd-gen-ai-chat__input__mc", placeholder: intl.formatMessage(msgs.placeholder), value: value, onApi: setApi, onChange: setValue, onKeyDown: handleKeyDown, beforeExtensions: beforeExtensions, extensions: extensions, onCompletion: onCompletion }) }), _jsx(GenAiChatAgentSwitching, { disabled: !value.trim(), agentDropdownDisabled: false, isAssistantLoading: false, isConversationsLoading: false, handleSubmit: handleSubmit })
|
|
64
|
+
] }) }) }));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export function GenAIStandaloneInput(props) {
|
|
70
|
+
const { backend, workspace, locale, ...rest } = props;
|
|
71
|
+
const effectiveBackend = useBackendStrict(backend);
|
|
72
|
+
const effectiveWorkspace = useWorkspaceStrict(workspace);
|
|
73
|
+
return (_jsx(IntlWrapper, { locale: locale, children: _jsx(GenAiStore, { ...props, backend: effectiveBackend, workspace: effectiveWorkspace, children: _jsx(StandaloneInputContent, { ...rest }) }) }));
|
|
74
|
+
}
|
|
@@ -3,10 +3,11 @@ type GenAiChatAgentSwitchingOwnProps = {
|
|
|
3
3
|
disabled: boolean;
|
|
4
4
|
agentDropdownDisabled: boolean;
|
|
5
5
|
isAssistantLoading: boolean;
|
|
6
|
+
isConversationsLoading: boolean;
|
|
6
7
|
handleSubmit: () => void;
|
|
7
8
|
onMouseDown?: (event: MouseEvent<HTMLDivElement>) => void;
|
|
8
|
-
setBusy
|
|
9
|
-
setNoAgents
|
|
9
|
+
setBusy?: (busy: boolean) => void;
|
|
10
|
+
setNoAgents?: (noAgents: boolean) => void;
|
|
10
11
|
leftContent?: ReactNode;
|
|
11
12
|
};
|
|
12
13
|
export declare const GenAiChatAgentSwitching: FC<GenAiChatAgentSwitchingOwnProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAiChatAgentSwitching.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatAgentSwitching.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAA0B,MAAM,OAAO,CAAC;AAkCzF,KAAK,+BAA+B,GAAG;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"GenAiChatAgentSwitching.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatAgentSwitching.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAA0B,MAAM,OAAO,CAAC;AAkCzF,KAAK,+BAA+B,GAAG;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;IAChC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,SAAS,CAAC;CAC3B,CAAC;AAyLF,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,+BAA+B,CAG1C,CAAC"}
|
|
@@ -18,14 +18,14 @@ const msgs = defineMessages({
|
|
|
18
18
|
id: "gd.gen-ai.agent.unavailable",
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
|
-
function GenAiChatAgentSwitchingCore({ agentSwitchingEnabled, isAssistantLoading, handleSubmit, conversations, conversation, agentDropdownDisabled,
|
|
21
|
+
function GenAiChatAgentSwitchingCore({ agentSwitchingEnabled, isAssistantLoading, isConversationsLoading, handleSubmit, conversations, conversation, agentDropdownDisabled, agents, selectedAgentId, agentSwitchingActive, disabled, onMouseDown, setSelectedAgent, setBusy, setNoAgents, leftContent, }) {
|
|
22
22
|
const intl = useIntl();
|
|
23
23
|
const sendLabel = intl.formatMessage(msgs.send);
|
|
24
24
|
const noAgentAvailableLabel = intl.formatMessage(msgs.noAgentAvailable);
|
|
25
25
|
const { availableAgents, hasNoAgents, isSelectionLoading } = getAgentSelectionStatus({
|
|
26
26
|
agentSwitchingActive,
|
|
27
27
|
assistantLoading: isAssistantLoading,
|
|
28
|
-
|
|
28
|
+
conversationsLoading: isConversationsLoading,
|
|
29
29
|
agents,
|
|
30
30
|
selectedAgentId,
|
|
31
31
|
});
|
|
@@ -19,7 +19,7 @@ function GenAiChatContextChooserCore({ active, ambient, addContextReference, onA
|
|
|
19
19
|
return (_jsx("div", { className: "gd-gen-ai-chat__input__context", children: _jsx(Dropdown, { alignPoints: [{ align: "tl bl", offset: { x: 0, y: 0 } }], closeOnEscape: true, fullscreenOnMobile: false, autofocusOnOpen: true, accessibilityConfig: {}, renderButton: ({ isOpen, toggleDropdown, accessibilityConfig }) => (_jsx(UiIconButton, { icon: "plus", variant: "tertiary", size: "small", dataTestId: "choose_context", isActive: isOpen, accessibilityConfig: {
|
|
20
20
|
...accessibilityConfig,
|
|
21
21
|
ariaLabel: intl.formatMessage(msgs.add),
|
|
22
|
-
}, onClick: toggleDropdown, isDisabled: !items.length })), renderBody: ({ closeDropdown, ariaAttributes }) => (_jsx(UiMenu, { dataTestId: "agent_dropdown_menu", items: items, size: "medium", minWidth: 245, maxWidth: 245, containerTopPadding: "
|
|
22
|
+
}, onClick: toggleDropdown, isDisabled: !items.length })), renderBody: ({ closeDropdown, ariaAttributes }) => (_jsx(UiMenu, { dataTestId: "agent_dropdown_menu", items: items, size: "medium", minWidth: 245, maxWidth: 245, containerTopPadding: "none", containerBottomPadding: "none", MenuHeader: ContextMenuHeader, ariaAttributes: ariaAttributes, onSelect: (item) => {
|
|
23
23
|
addContextReference({ object: item.data });
|
|
24
24
|
onAddContext?.(item.data);
|
|
25
25
|
closeDropdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,SAAS,EAAsD,MAAM,OAAO,CAAC;AAqCpG,MAAM,MAAM,aAAa,GAAG;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;CACzC,CAAC;AA2PF,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,aAAa,CAAgE,CAAC"}
|
package/esm/components/Input.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2024-2026 GoodData Corporation
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import { FormattedMessage, defineMessages, useIntl } from "react-intl";
|
|
6
6
|
import { connect } from "react-redux";
|
|
7
7
|
import { SyntaxHighlightingInput } from "@gooddata/sdk-ui-kit";
|
|
8
8
|
import { makeTextContents, makeUserItem, makeUserMessage, } from "../model.js";
|
|
9
9
|
import { agentSwitchingEnabledSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
10
|
-
import { asyncProcessSelector, conversationMessagesSelector, conversationSelector, messagesSelector, } from "../store/messages/messagesSelectors.js";
|
|
10
|
+
import { asyncProcessSelector, conversationMessagesSelector, conversationSelector, conversationsLoadedSelector, messagesSelector, } from "../store/messages/messagesSelectors.js";
|
|
11
11
|
import { newMessageAction, setSelectedAgentAction } from "../store/messages/messagesSlice.js";
|
|
12
12
|
import { collectReferences } from "./completion/references.js";
|
|
13
13
|
import { useCompletion } from "./completion/useCompletion.js";
|
|
@@ -16,6 +16,7 @@ import { GenAiChatContextChooser } from "./GenAiChatContextChooser.js";
|
|
|
16
16
|
import { GenAIChatContextIndicator } from "./GenAIChatContextIndicator.js";
|
|
17
17
|
import { useHighlight } from "./highlight/useHighlight.js";
|
|
18
18
|
import { useFullscreenCheck } from "./hooks/useFullscreenCheck.js";
|
|
19
|
+
import { useInputAutofocus } from "./hooks/useInputAutofocus.js";
|
|
19
20
|
import { escapeMarkdown } from "./utils/markdownUtils.js";
|
|
20
21
|
const msgs = defineMessages({
|
|
21
22
|
placeholder: {
|
|
@@ -30,7 +31,7 @@ const msgs = defineMessages({
|
|
|
30
31
|
});
|
|
31
32
|
const isMac = typeof navigator !== "undefined" &&
|
|
32
33
|
(navigator.platform.toUpperCase().indexOf("MAC") >= 0 || navigator.userAgent.includes("Macintosh"));
|
|
33
|
-
function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, canManage, canAnalyze, targetRef, messages, conversation, items, agentSwitchingEnabled, loading, }) {
|
|
34
|
+
function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, canManage, canAnalyze, targetRef, messages, conversation, conversationsLoaded, items, agentSwitchingEnabled, loading, }) {
|
|
34
35
|
const intl = useIntl();
|
|
35
36
|
const { isBigScreen, isSmallScreen, isFullscreen } = useFullscreenCheck();
|
|
36
37
|
const isLoading = loading === "loading" || loading === "clearing";
|
|
@@ -46,36 +47,7 @@ function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, c
|
|
|
46
47
|
const beforeExtensions = useMemo(() => [atomicCursorExtension], [atomicCursorExtension]);
|
|
47
48
|
const extensions = useMemo(() => [highlightExtension], [highlightExtension]);
|
|
48
49
|
// Force focus when autofocus is enables on the first mount, right after the initial state is loaded
|
|
49
|
-
const
|
|
50
|
-
const [updates, update] = useReducer((x) => x + 1, 0);
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
// Autofocus the textarea when the chat is not disabled and the user is not focusing on another element
|
|
53
|
-
// Important, given the disabled states changes depending on the agent's loading state
|
|
54
|
-
// And it's loosing focus after the loading state changes
|
|
55
|
-
if (isBusy || !editorApi) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const makeFocus = forceFocusOnce.current || document.activeElement === document.body;
|
|
59
|
-
let timeout;
|
|
60
|
-
if (makeFocus) {
|
|
61
|
-
editorApi.focus();
|
|
62
|
-
if (document.activeElement === editorApi.contentDOM) {
|
|
63
|
-
forceFocusOnce.current = false;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
timeout = window.setTimeout(update, 25);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return () => {
|
|
70
|
-
if (timeout) {
|
|
71
|
-
window.clearTimeout(timeout);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}, [isBusy, editorApi, updates]);
|
|
75
|
-
useEffect(() => () => {
|
|
76
|
-
// When unmount occurred, reset the autofocus
|
|
77
|
-
forceFocusOnce.current = true;
|
|
78
|
-
}, []);
|
|
50
|
+
const ref = useInputAutofocus(editorApi, autofocus, { isBusy });
|
|
79
51
|
const handleSubmit = () => {
|
|
80
52
|
let item;
|
|
81
53
|
if (conversation) {
|
|
@@ -132,7 +104,7 @@ function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, c
|
|
|
132
104
|
"gd-gen-ai-chat__input--no-agents": hasNoAgents,
|
|
133
105
|
}), children: _jsxs("div", { className: "gd-gen-ai-chat__input__content", children: [
|
|
134
106
|
_jsx(HintText, { focused: focused, where: "top" }), _jsxs("div", { className: "gd-gen-ai-chat__input__container", children: [
|
|
135
|
-
_jsx("div", { className: "gd-gen-ai-chat__input__context", onMouseDown: handleContextMouseDown, children: _jsx(GenAIChatContextIndicator, { onDelete: handleOnFocus }) }), _jsx("div", { ref: targetRef, onFocus: handleOnFocus }), _jsx("div", { className: "gd-gen-ai-chat__input__text", children: _jsx(SyntaxHighlightingInput, { className: "gd-gen-ai-chat__input__mc", placeholder: intl.formatMessage(msgs.placeholder), label: isMac ? intl.formatMessage(msgs.labelMac) : intl.formatMessage(msgs.labelWin), value: value, autocompletion: {
|
|
107
|
+
_jsx("div", { className: "gd-gen-ai-chat__input__context", onMouseDown: handleContextMouseDown, children: _jsx(GenAIChatContextIndicator, { onDelete: handleOnFocus }) }), _jsx("div", { ref: targetRef, onFocus: handleOnFocus }), _jsx("div", { className: "gd-gen-ai-chat__input__text", ...ref, children: _jsx(SyntaxHighlightingInput, { className: "gd-gen-ai-chat__input__mc", placeholder: intl.formatMessage(msgs.placeholder), label: isMac ? intl.formatMessage(msgs.labelMac) : intl.formatMessage(msgs.labelWin), value: value, autocompletion: {
|
|
136
108
|
aboveCursor: true,
|
|
137
109
|
whenTyping: true,
|
|
138
110
|
whenTypingDelay: 300,
|
|
@@ -140,7 +112,7 @@ function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, c
|
|
|
140
112
|
setFocused(true);
|
|
141
113
|
}, onBlur: () => {
|
|
142
114
|
setFocused(false);
|
|
143
|
-
}, onKeyDown: handleKeyDown, onCompletion: onCompletion }) }), _jsx(GenAiChatAgentSwitching, { disabled: buttonDisabled, isAssistantLoading: isAssistantLoading, agentDropdownDisabled: agentDropdownDisabled, handleSubmit: handleSubmit, onMouseDown: handleActionsMouseDown, setBusy: setAreAgentsBusy, setNoAgents: setHasNoAgents, leftContent: _jsx(GenAiChatContextChooser, { onAddContext: handleOnFocus }) })
|
|
115
|
+
}, onKeyDown: handleKeyDown, onCompletion: onCompletion }) }), _jsx(GenAiChatAgentSwitching, { disabled: buttonDisabled, isConversationsLoading: !conversationsLoaded, isAssistantLoading: isAssistantLoading, agentDropdownDisabled: agentDropdownDisabled, handleSubmit: handleSubmit, onMouseDown: handleActionsMouseDown, setBusy: setAreAgentsBusy, setNoAgents: setHasNoAgents, leftContent: _jsx(GenAiChatContextChooser, { onAddContext: handleOnFocus }) })
|
|
144
116
|
] }), _jsx(HintText, { focused: focused, where: "bottom" })
|
|
145
117
|
] }) }));
|
|
146
118
|
}
|
|
@@ -159,6 +131,7 @@ const mapStateToProps = (state) => {
|
|
|
159
131
|
const asyncState = asyncProcessSelector(state);
|
|
160
132
|
return {
|
|
161
133
|
conversation: conversationSelector(state),
|
|
134
|
+
conversationsLoaded: conversationsLoadedSelector(state),
|
|
162
135
|
items: conversationMessagesSelector(state),
|
|
163
136
|
messages: messagesSelector(state),
|
|
164
137
|
loading: asyncState,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rehype-references.d.ts","sourceRoot":"","sources":["../../../../src/components/completion/plugins/rehype-references.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO,CAAC;AAGlC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK3D,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"rehype-references.d.ts","sourceRoot":"","sources":["../../../../src/components/completion/plugins/rehype-references.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO,CAAC;AAGlC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK3D,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,EAAE,8BAyC/D"}
|
|
@@ -15,7 +15,7 @@ export declare function getOptions(intl: IntlShape, { items, search, canManage,
|
|
|
15
15
|
includeTags?: string[];
|
|
16
16
|
excludeTags?: string[];
|
|
17
17
|
}): ICompletionItem[];
|
|
18
|
-
declare const SupportedReferenceTypes: readonly ["fact", "metric", "date", "attribute", "label", "dashboard"];
|
|
18
|
+
declare const SupportedReferenceTypes: readonly ["fact", "metric", "date", "attribute", "label", "dashboard", "visualization"];
|
|
19
19
|
export declare function getReferenceRegex(split?: boolean): RegExp;
|
|
20
20
|
export declare function getItems(intl: IntlShape, item: CatalogItem, { canManage, canAnalyze, onCompletionSelected }: {
|
|
21
21
|
canManage?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/completion/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,mCAAmC,EACxC,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAQd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAC/C,IAAI,EAAE,WAAW,GAAG,qBAAqB,CAAC;CAC7C;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,iBAW7C;AAGD,wBAAgB,UAAU,CACtB,IAAI,EAAE,SAAS,EACf,EACI,KAAK,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,oBAA+B,EAC/B,WAAW,EACX,WAAW,EACd,EAAE;IACC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,GACF,eAAe,EAAE,CAcnB;AAED,QAAA,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/completion/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,mCAAmC,EACxC,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EAQd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAC/C,IAAI,EAAE,WAAW,GAAG,qBAAqB,CAAC;CAC7C;AAGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,iBAW7C;AAGD,wBAAgB,UAAU,CACtB,IAAI,EAAE,SAAS,EACf,EACI,KAAK,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,oBAA+B,EAC/B,WAAW,EACX,WAAW,EACd,EAAE;IACC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,GACF,eAAe,EAAE,CAcnB;AAED,QAAA,MAAM,uBAAuB,yFAQnB,CAAC;AAGX,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE,OAAO,UAKhD;AAGD,wBAAgB,QAAQ,CACpB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,WAAW,EACjB,EACI,SAAS,EACT,UAAU,EACV,oBAAoB,EACvB,EAAE;IACC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;CAChE,GACF,eAAe,EAAE,CAqGnB;AAUD,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,GACtC,iBAAiB,GAAG,IAAI,CAgB1B;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,iBAExD;AAGD,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,WAAW,GAAG,qBAAqB,GAAG,mCAAmC,GAChF,MAAM,GAAG,IAAI,CAoBf;AAGD,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,WAAW,GAAG,qBAAqB,GAAG,mCAAmC,UAqBlF;AAGD,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,WAAW,GAAG,qBAAqB,GAAG,mCAAmC,GAChF,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAoBjD;AAsBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,WA0B1F"}
|
|
@@ -29,7 +29,15 @@ export function getOptions(intl, { items, search, canManage, canAnalyze, onCompl
|
|
|
29
29
|
return search ? label.includes(search.toLowerCase()) || apply.includes(search.toLowerCase()) : true;
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
const SupportedReferenceTypes = [
|
|
32
|
+
const SupportedReferenceTypes = [
|
|
33
|
+
"fact",
|
|
34
|
+
"metric",
|
|
35
|
+
"date",
|
|
36
|
+
"attribute",
|
|
37
|
+
"label",
|
|
38
|
+
"dashboard",
|
|
39
|
+
"visualization",
|
|
40
|
+
];
|
|
33
41
|
// Utility: Get regex for references
|
|
34
42
|
export function getReferenceRegex(split) {
|
|
35
43
|
if (split) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContextItems.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextItems.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useContextItems.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextItems.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,WAAW,EAAU,MAAM,sBAAsB,CAAC;AAMhE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,wBAAgB,eAAe,CAC3B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACtC,WAAW,CAAC;IAAE,WAAW,EAAE,mBAAmB,CAAA;CAAE,CAAC,EAAE,CAmCrD"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
3
|
import { useMemo } from "react";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
4
5
|
import { UiIcon } from "@gooddata/sdk-ui-kit";
|
|
5
6
|
import { collectAvailableReferences, collectContextReferences, } from "../../context/collectContextReferences.js";
|
|
6
7
|
import { getIconByType } from "../utils/icons.js";
|
|
7
8
|
export function useContextItems(ambient, active) {
|
|
9
|
+
const intl = useIntl();
|
|
10
|
+
const emptyReferenceLabel = intl.formatMessage({ id: "gd.gen-ai.context.untitled" });
|
|
8
11
|
return useMemo(() => {
|
|
9
12
|
const items = [];
|
|
10
|
-
const currentReferences = collectAvailableReferences(ambient);
|
|
11
|
-
const selectedReferences = collectContextReferences(active);
|
|
13
|
+
const currentReferences = collectAvailableReferences(ambient, emptyReferenceLabel);
|
|
14
|
+
const selectedReferences = collectContextReferences(active, emptyReferenceLabel);
|
|
12
15
|
currentReferences.forEach((reference) => {
|
|
13
16
|
const isSelected = selectedReferences.some((selectedReference) => selectedReference.id === reference.id && selectedReference.type === reference.type);
|
|
14
17
|
if (!isSelected) {
|
|
@@ -20,12 +23,12 @@ export function useContextItems(ambient, active) {
|
|
|
20
23
|
stringTitle: reference.title,
|
|
21
24
|
...(icon.iconBefore
|
|
22
25
|
? {
|
|
23
|
-
iconLeft: _jsx(UiIcon, { type: icon.iconBefore, color: icon.iconColor }),
|
|
26
|
+
iconLeft: _jsx(UiIcon, { size: 16, type: icon.iconBefore, color: icon.iconColor }),
|
|
24
27
|
}
|
|
25
28
|
: {}),
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
31
|
});
|
|
29
32
|
return items;
|
|
30
|
-
}, [active, ambient]);
|
|
33
|
+
}, [active, ambient, emptyReferenceLabel]);
|
|
31
34
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { EditorView } from "@codemirror/view";
|
|
2
|
+
export declare function useInputAutofocus(editorApi: EditorView | null, autofocus: boolean, opts: {
|
|
3
|
+
isBusy: boolean;
|
|
4
|
+
}): import("@gooddata/sdk-ui-kit").IUiFocusHelperConnectors<HTMLDivElement>;
|
|
5
|
+
//# sourceMappingURL=useInputAutofocus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputAutofocus.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useInputAutofocus.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,2EAiC5B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { createRef, useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import { useUiAutofocusConnectors } from "@gooddata/sdk-ui-kit";
|
|
4
|
+
export function useInputAutofocus(editorApi, autofocus, opts) {
|
|
5
|
+
// Force focus when autofocus is enables on the first mount, right after the initial state is loaded
|
|
6
|
+
const forceFocusOnce = useRef(autofocus);
|
|
7
|
+
const initialFocus = useMemo(() => {
|
|
8
|
+
const ref = createRef();
|
|
9
|
+
ref.current = editorApi?.contentDOM;
|
|
10
|
+
return ref;
|
|
11
|
+
}, [editorApi]);
|
|
12
|
+
const ref = useUiAutofocusConnectors({
|
|
13
|
+
initialFocus,
|
|
14
|
+
active: autofocus && !opts.isBusy && (forceFocusOnce.current || document.activeElement === document.body),
|
|
15
|
+
refocusKey: opts.isBusy,
|
|
16
|
+
});
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (document.activeElement === editorApi?.contentDOM) {
|
|
19
|
+
forceFocusOnce.current = false;
|
|
20
|
+
}
|
|
21
|
+
}, [editorApi]);
|
|
22
|
+
useEffect(() => () => {
|
|
23
|
+
// When unmount occurred, reset the autofocus
|
|
24
|
+
forceFocusOnce.current = true;
|
|
25
|
+
}, []);
|
|
26
|
+
return ref;
|
|
27
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationItemContents.d.ts","sourceRoot":"","sources":["../../../src/components/messages/ConversationItemContents.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGH,KAAK,0BAA0B,EAE/B,KAAK,iBAAiB,EACzB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationItemContents.d.ts","sourceRoot":"","sources":["../../../src/components/messages/ConversationItemContents.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGH,KAAK,0BAA0B,EAE/B,KAAK,iBAAiB,EACzB,MAAM,gBAAgB,CAAC;AAexB,KAAK,6BAA6B,GAAG;IACjC,OAAO,EAAE,0BAA0B,CAAC;IACpC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,6BAA6B,kDAuIzG"}
|
|
@@ -3,6 +3,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useIntl } from "react-intl";
|
|
4
4
|
import { loadWhatIfScenarios } from "../../whatIf/whatIfMapping.js";
|
|
5
5
|
import { ConversationAlertProposalContent } from "./conversationContents/ConversationAlertProposalContent.js";
|
|
6
|
+
import { ConversationDashboardContent } from "./conversationContents/ConversationDashboardContent.js";
|
|
6
7
|
import { ConversationErrorContent } from "./conversationContents/ConversationErrorContent.js";
|
|
7
8
|
import { ConversationKdaContent } from "./conversationContents/ConversationKdaContent.js";
|
|
8
9
|
import { ConversationReasoningContent } from "./conversationContents/ConversationReasoningContent.js";
|
|
@@ -45,6 +46,9 @@ export function ConversationItemContents({ message, references, isLoading }) {
|
|
|
45
46
|
if (part.type === "whatIf") {
|
|
46
47
|
return (_jsx(ConversationWhatIfContent, { message: message, part: part, whatIf: whatIf }, index));
|
|
47
48
|
}
|
|
49
|
+
if (part.type === "dashboard") {
|
|
50
|
+
return (_jsx(ConversationDashboardContent, { message: message, part: part, dashboard: part.dashboard }, index));
|
|
51
|
+
}
|
|
48
52
|
// Add more multipart types if needed
|
|
49
53
|
return null;
|
|
50
54
|
}) }));
|
|
@@ -213,7 +213,7 @@ function Operator({ operator, }) {
|
|
|
213
213
|
function AlertItem({ markdown, title, description, objects, bold, type = "normal" }) {
|
|
214
214
|
return (_jsxs("li", { className: "gd-gen-ai-chat__conversation__item__content-alertProposal-item", children: [
|
|
215
215
|
_jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-alertProposal-item-title", children: [title, ":"] }), _jsxs("div", { className: cx("gd-gen-ai-chat__conversation__item__content-alertProposal-item-description", {
|
|
216
|
-
bold,
|
|
216
|
+
"gd-gen-ai-chat__conversation__item__content-alertProposal-item-bold": bold,
|
|
217
217
|
}), children: [type === "normal" ? (_jsx(MarkdownComponent, { allowMarkdown: markdown, references: objects, children: description })) : null, type === "code" ? _jsx("code", { children: description }) : null] })
|
|
218
218
|
] }));
|
|
219
219
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IDashboard } from "@gooddata/sdk-model";
|
|
2
|
+
import type { IChatConversationLocalItem, IChatConversationMultipartLocalPart } from "../../../model.js";
|
|
3
|
+
export type ConversationDashboardContentProps = {
|
|
4
|
+
message: IChatConversationLocalItem;
|
|
5
|
+
part: IChatConversationMultipartLocalPart;
|
|
6
|
+
dashboard?: IDashboard | null;
|
|
7
|
+
className?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function ConversationDashboardContent(props: ConversationDashboardContentProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=ConversationDashboardContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversationDashboardContent.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/conversationContents/ConversationDashboardContent.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC,EAAE,MAAM,mBAAmB,CAAC;AAEzG,MAAM,MAAM,iCAAiC,GAAG;IAC5C,OAAO,EAAE,0BAA0B,CAAC;IACpC,IAAI,EAAE,mCAAmC,CAAC;IAC1C,SAAS,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iCAAiC,kDA8DpF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2024-2026 GoodData Corporation
|
|
3
|
+
import cx from "classnames";
|
|
4
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
+
import { UiButton, UiIcon } from "@gooddata/sdk-ui-kit";
|
|
6
|
+
export function ConversationDashboardContent(props) {
|
|
7
|
+
const { className, dashboard } = props;
|
|
8
|
+
const intl = useIntl();
|
|
9
|
+
const classNames = cx("gd-gen-ai-chat__conversation__item__content", "gd-gen-ai-chat__conversation__item__content--dashboard", className);
|
|
10
|
+
if (!dashboard) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return (_jsxs("div", { className: classNames, children: [
|
|
14
|
+
_jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-header", children: [
|
|
15
|
+
_jsx(UiIcon, { type: "dashboard", size: 14, color: "complementary-6", backgroundSize: 26, backgroundColor: "complementary-2" }), _jsx(FormattedMessage, { id: "gd.gen-ai.dashboard.title" })
|
|
16
|
+
] }), _jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-frame", children: [
|
|
17
|
+
_jsxs("ul", { children: [
|
|
18
|
+
_jsxs("li", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item", children: [
|
|
19
|
+
_jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item-title", children: [intl.formatMessage({ id: "gd.gen-ai.dashboard.name" }), ":"] }), _jsx("div", { className: cx("gd-gen-ai-chat__conversation__item__content-dashboard-item-description", "gd-gen-ai-chat__conversation__item__content-dashboard-item-bold"), children: _jsx("p", { children: dashboard.title }) })
|
|
20
|
+
] }), _jsxs("li", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item", children: [
|
|
21
|
+
_jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item-title", children: [intl.formatMessage({ id: "gd.gen-ai.dashboard.description" }), ":"] }), _jsx("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item-description", children: _jsx("p", { children: dashboard.description }) })
|
|
22
|
+
] })
|
|
23
|
+
] }), _jsx("div", { className: "gd-gen-ai-chat__conversation__item__content-dashboard-item-buttons", children: _jsx(UiButton, { label: intl.formatMessage({ id: "gd.gen-ai.dashboard.open-dashboard" }), variant: "tertiary" }) })
|
|
24
|
+
] })
|
|
25
|
+
] }));
|
|
26
|
+
}
|
|
@@ -9,10 +9,10 @@ export declare function getEffectiveSelectedAgentId({ agents, conversationAgentI
|
|
|
9
9
|
conversationAgentId?: string;
|
|
10
10
|
selectedAgentId?: string;
|
|
11
11
|
}): string | undefined;
|
|
12
|
-
export declare function getAgentSelectionStatus({ agentSwitchingActive, assistantLoading,
|
|
12
|
+
export declare function getAgentSelectionStatus({ agentSwitchingActive, assistantLoading, conversationsLoading, agents, selectedAgentId }: {
|
|
13
13
|
agentSwitchingActive: boolean;
|
|
14
14
|
assistantLoading?: boolean;
|
|
15
|
-
|
|
15
|
+
conversationsLoading?: boolean;
|
|
16
16
|
agents: GenAIAgent[] | undefined;
|
|
17
17
|
selectedAgentId?: string;
|
|
18
18
|
}): AgentSelectionStatus;
|