@gooddata/sdk-ui-gen-ai 11.54.0-alpha.0 → 11.54.0-alpha.2
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/GenAIChat.d.ts +7 -0
- package/esm/components/GenAIChat.d.ts.map +1 -1
- package/esm/components/GenAIChat.js +3 -1
- package/esm/components/GenAIChatContextIndicator.js +2 -2
- package/esm/components/GenAIChatDialog.d.ts +2 -1
- package/esm/components/GenAIChatDialog.d.ts.map +1 -1
- package/esm/components/GenAIChatDialog.js +4 -4
- package/esm/components/GenAiChatContextChooserBody.js +2 -2
- package/esm/components/completion/useToolsReferences.d.ts.map +1 -1
- package/esm/components/completion/useToolsReferences.js +80 -7
- package/esm/components/hooks/useContextItems.js +1 -0
- package/esm/components/intelligence/data/deriveInteractionIntelligenceFromSteps.d.ts.map +1 -1
- package/esm/components/intelligence/data/deriveInteractionIntelligenceFromSteps.js +29 -2
- package/esm/components/messages/AssistantItem.d.ts.map +1 -1
- package/esm/components/messages/AssistantItem.js +1 -1
- package/esm/components/utils/icons.d.ts +1 -1
- package/esm/components/utils/icons.d.ts.map +1 -1
- package/esm/components/utils/icons.js +36 -3
- package/esm/context/collectContextReferences.d.ts.map +1 -1
- package/esm/context/collectContextReferences.js +4 -0
- package/esm/context/dashboard.d.ts +2 -2
- package/esm/context/dashboard.d.ts.map +1 -1
- package/esm/context/dashboard.js +10 -2
- package/esm/context/hooks/useDashboardAmbientContext.d.ts +3 -0
- package/esm/context/hooks/useDashboardAmbientContext.d.ts.map +1 -0
- package/esm/context/hooks/useDashboardAmbientContext.js +68 -0
- package/esm/hooks/useGenAiDispatcher.d.ts +11 -0
- package/esm/hooks/useGenAiDispatcher.d.ts.map +1 -0
- package/esm/hooks/useGenAiDispatcher.js +14 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -0
- package/esm/localization/bundles/zh-HK.localization-bundle.js +1 -1
- package/esm/sdk-ui-gen-ai.d.ts +17 -0
- package/esm/store/sideEffects/loadContextObjects.js +3 -3
- package/esm/types.d.ts +8 -0
- package/esm/types.d.ts.map +1 -1
- package/esm/utils.d.ts +1 -1
- package/esm/utils.d.ts.map +1 -1
- package/esm/utils.js +2 -1
- package/package.json +20 -20
- package/styles/css/main.css +18 -0
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +18 -0
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/messages.scss +16 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ComponentType } from "react";
|
|
2
|
+
import { type DashboardSelectorEvaluator } from "@gooddata/sdk-ui-dashboard";
|
|
2
3
|
import { type GenAIAssistantMode, type LinkHandlerEvent } from "./ConfigContext.js";
|
|
3
4
|
import { type GenAiStoreProps } from "./GenAiStore.js";
|
|
4
5
|
/**
|
|
@@ -33,6 +34,12 @@ export type GenAIAssistantProps = Omit<GenAiStoreProps, "children"> & {
|
|
|
33
34
|
* This will disable full control permissions for the user even if the user has them defined.
|
|
34
35
|
*/
|
|
35
36
|
disableFullControl?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Selector that is used to automatically build ambient context for the chat.
|
|
39
|
+
* If its provided, the chat will automatically load the dashboards and related data
|
|
40
|
+
* from it.
|
|
41
|
+
*/
|
|
42
|
+
dashboardSelector?: DashboardSelectorEvaluator;
|
|
36
43
|
/**
|
|
37
44
|
* Custom React node rendered when no conversation exists yet.
|
|
38
45
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAO7E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGpG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IAClE;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IAEvE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,0BAA0B,CAAC;IAE/C;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IAErD;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAyDxD;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,uBAAiB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { BackendProvider, WorkspaceProvider, useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
3
|
+
import { useDashboardAmbientContext } from "../context/hooks/useDashboardAmbientContext.js";
|
|
3
4
|
import { IntlWrapper } from "../localization/IntlWrapper.js";
|
|
4
5
|
import { PermissionsProvider } from "../permissions/PermissionsContext.js";
|
|
5
6
|
import { usePermissions } from "../permissions/usePermissions.js";
|
|
@@ -24,7 +25,8 @@ export function GenAIAssistant(props) {
|
|
|
24
25
|
*/
|
|
25
26
|
export const GenAIChat = GenAIAssistant;
|
|
26
27
|
function GenAIContent(props) {
|
|
27
|
-
const { LandingScreenComponentProvider, DisclaimerComponentProvider, className, catalogItems } = props;
|
|
28
|
+
const { LandingScreenComponentProvider, DisclaimerComponentProvider, dashboardSelector, className, catalogItems, } = props;
|
|
28
29
|
const { permissions, loading } = usePermissions();
|
|
30
|
+
useDashboardAmbientContext(dashboardSelector);
|
|
29
31
|
return (_jsx(ConfigProvider, { catalogItems: catalogItems, canFullControl: props.disableFullControl ? false : (permissions.canManageProject ?? false), canManage: props.disableManage ? false : (permissions.canManageProject ?? false), canAnalyze: props.disableAnalyze ? false : (permissions.canCreateVisualization ?? false), children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, disclaimerComponentProvider: DisclaimerComponentProvider, children: _jsx(GenAIChatWrapper, { initializing: loading, className: className }) }) }));
|
|
30
32
|
}
|
|
@@ -8,7 +8,7 @@ import { collectContextReferences } from "../context/collectContextReferences.js
|
|
|
8
8
|
import { contextSetupEnabledSelector, userContextSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
9
9
|
import { removeContextReferenceAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
10
10
|
import { useContextChangeAnnouncement } from "./hooks/useContextChangeAnnouncement.js";
|
|
11
|
-
import {
|
|
11
|
+
import { getIconByObject, getTypeLabel } from "./utils/icons.js";
|
|
12
12
|
const msgs = defineMessages({
|
|
13
13
|
untitled: {
|
|
14
14
|
id: "gd.gen-ai.context.untitled",
|
|
@@ -48,7 +48,7 @@ export function GenAIChatContextIndicator({ onDelete }) {
|
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
50
|
return (_jsxs(_Fragment, { children: [references.length > 0 ? (_jsxs(_Fragment, { children: [
|
|
51
|
-
_jsx("span", { className: "sr-only", id: groupLabelId, children: intl.formatMessage(msgs.groupLabel) }), _jsx("div", { className: "gd-gen-ai-chat__context-indicator", role: "group", "aria-labelledby": groupLabelId, children: references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...
|
|
51
|
+
_jsx("span", { className: "sr-only", id: groupLabelId, children: intl.formatMessage(msgs.groupLabel) }), _jsx("div", { className: "gd-gen-ai-chat__context-indicator", role: "group", "aria-labelledby": groupLabelId, children: references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...getIconByObject(reference), label: reference.title, isExpandable: false, onDelete: onDeleteHandler(reference), accessibilityConfig: {
|
|
52
52
|
deleteAriaLabel: intl.formatMessage(msgs.remove, {
|
|
53
53
|
title: reference.title,
|
|
54
54
|
}),
|
|
@@ -15,11 +15,12 @@ export type GenAIChatDialogProps = Omit<GenAiStoreProps, "children"> & {
|
|
|
15
15
|
returnFocusTo?: RefObject<HTMLElement | null> | string;
|
|
16
16
|
onLinkClick?: (linkClickEvent: LinkHandlerEvent) => string | undefined;
|
|
17
17
|
LandingScreenComponentProvider?: () => ComponentType;
|
|
18
|
+
DisclaimerComponentProvider?: () => ComponentType | null;
|
|
18
19
|
/**
|
|
19
20
|
* Set to false while the host renders its own overlay above the chat, so that Escape aimed at
|
|
20
21
|
* that overlay does not also close the chat (see GenAIChatOverlayExternalProps.closeOnEscape).
|
|
21
22
|
*/
|
|
22
23
|
closeOnEscape?: boolean;
|
|
23
24
|
};
|
|
24
|
-
export declare function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks, returnFocusTo, objectTypes, includeTags, excludeTags, canManage, canAnalyze, canFullControl, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, closeOnEscape }: GenAIChatDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks, returnFocusTo, objectTypes, includeTags, excludeTags, canManage, canAnalyze, canFullControl, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape }: GenAIChatDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
25
26
|
//# sourceMappingURL=GenAIChatDialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAIChatDialog.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAcpG,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IACvD,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IACrD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AASF,wBAAgB,eAAe,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,cAAc,EACd,gBAAuB,EACvB,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAiB,EACjB,UAAkB,EAClB,cAAsB,EACtB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,8BAA8B,EAC9B,aAAa,EAChB,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"GenAIChatDialog.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAcpG,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IACvD,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IACrD,2BAA2B,CAAC,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IACzD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AASF,wBAAgB,eAAe,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,cAAc,EACd,gBAAuB,EACvB,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAiB,EACjB,UAAkB,EAClB,cAAsB,EACtB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EAChB,EAAE,oBAAoB,2CA+CtB"}
|
|
@@ -18,12 +18,12 @@ import { KeyDriverAnalysis } from "./KeyDriverAnalysis.js";
|
|
|
18
18
|
const DEFAULT_CHAT_Z_INDEX = 3000;
|
|
19
19
|
// - Must be more than DEFAULT_CHAT_Z_INDEX
|
|
20
20
|
const DEFAULT_KDA_Z_INDEX = 3050;
|
|
21
|
-
export function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks = true, returnFocusTo, objectTypes, includeTags, excludeTags, canManage = false, canAnalyze = false, canFullControl = false, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, closeOnEscape, }) {
|
|
21
|
+
export function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks = true, returnFocusTo, objectTypes, includeTags, excludeTags, canManage = false, canAnalyze = false, canFullControl = false, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape, }) {
|
|
22
22
|
const effectiveBackend = useBackendStrict(backend);
|
|
23
23
|
const effectiveWorkspace = useWorkspaceStrict(workspace);
|
|
24
|
-
return (_jsx(IntlWrapper, { locale: locale, children: _jsx(GenAiStore, { backend: effectiveBackend, workspace: effectiveWorkspace, onDispatcher: onDispatcher, eventHandlers: eventHandlers, colorPalette: colorPalette, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, settings: settings, objectTypes: objectTypes, includeTags: includeTags, excludeTags: excludeTags, catalogItems: catalogItems, mode: mode, children: (genAIStore) => (_jsx(GenAIChatDialogContent, { genAIStore: genAIStore, backend: effectiveBackend, workspace: effectiveWorkspace, className: className, dialogPosition: dialogPosition, disabled: disabled, isOpen: isOpen, onOpen: onOpen, onClose: onClose, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, LandingScreenComponentProvider: LandingScreenComponentProvider })) }) }));
|
|
24
|
+
return (_jsx(IntlWrapper, { locale: locale, children: _jsx(GenAiStore, { backend: effectiveBackend, workspace: effectiveWorkspace, onDispatcher: onDispatcher, eventHandlers: eventHandlers, colorPalette: colorPalette, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, settings: settings, objectTypes: objectTypes, includeTags: includeTags, excludeTags: excludeTags, catalogItems: catalogItems, mode: mode, children: (genAIStore) => (_jsx(GenAIChatDialogContent, { genAIStore: genAIStore, backend: effectiveBackend, workspace: effectiveWorkspace, className: className, dialogPosition: dialogPosition, disabled: disabled, isOpen: isOpen, onOpen: onOpen, onClose: onClose, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, LandingScreenComponentProvider: LandingScreenComponentProvider, DisclaimerComponentProvider: DisclaimerComponentProvider })) }) }));
|
|
25
25
|
}
|
|
26
|
-
function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dialogPosition, disabled, isOpen, onOpen, onClose, returnFocusTo, onLinkClick, allowNativeLinks, catalogItems, canManage, canAnalyze, canFullControl, LandingScreenComponentProvider, closeOnEscape, }) {
|
|
26
|
+
function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dialogPosition, disabled, isOpen, onOpen, onClose, returnFocusTo, onLinkClick, allowNativeLinks, catalogItems, canManage, canAnalyze, canFullControl, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape, }) {
|
|
27
27
|
const open = useRef(onOpen);
|
|
28
28
|
open.current = onOpen;
|
|
29
29
|
const close = useRef(onClose);
|
|
@@ -63,6 +63,6 @@ function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dia
|
|
|
63
63
|
const parentOverlayController = useOverlayController();
|
|
64
64
|
const chatOverlayController = useMemo(() => parentOverlayController ?? OverlayController.getInstance(DEFAULT_CHAT_Z_INDEX), [parentOverlayController]);
|
|
65
65
|
const kdaOverlayController = useMemo(() => parentOverlayController ?? OverlayController.getInstance(DEFAULT_KDA_Z_INDEX), [parentOverlayController]);
|
|
66
|
-
return (_jsx(BackendProvider, { backend: backend, children: _jsx(WorkspaceProvider, { workspace: workspace, children: _jsxs(OverlayControllerProvider, { overlayController: chatOverlayController, children: [isOpen && !disabled ? (_jsx(ConfigProvider, { allowNativeLinks: allowNativeLinks, linkHandler: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, children: _jsx(GenAIChatOverlay, { className: className, dialogPosition: dialogPosition, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, onClose: onCloseHandler }) }) })) : null, _jsx(OverlayControllerProvider, { overlayController: kdaOverlayController, children: _jsx(KeyDriverAnalysis, {}) })
|
|
66
|
+
return (_jsx(BackendProvider, { backend: backend, children: _jsx(WorkspaceProvider, { workspace: workspace, children: _jsxs(OverlayControllerProvider, { overlayController: chatOverlayController, children: [isOpen && !disabled ? (_jsx(ConfigProvider, { allowNativeLinks: allowNativeLinks, linkHandler: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, disclaimerComponentProvider: DisclaimerComponentProvider, children: _jsx(GenAIChatOverlay, { className: className, dialogPosition: dialogPosition, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, onClose: onCloseHandler }) }) })) : null, _jsx(OverlayControllerProvider, { overlayController: kdaOverlayController, children: _jsx(KeyDriverAnalysis, {}) })
|
|
67
67
|
] }) }) }));
|
|
68
68
|
}
|
|
@@ -5,7 +5,7 @@ import cx from "classnames";
|
|
|
5
5
|
import { defineMessages, useIntl } from "react-intl";
|
|
6
6
|
import { useDebouncedState } from "@gooddata/sdk-ui";
|
|
7
7
|
import { DEFAULT_ITEM_HEIGHT, DETAILED_ANNOUNCEMENT_THRESHOLD, Input, NoData, ScopedIdStore, ShortenedText, UiIcon, UiPagedVirtualList, UiSearchResultsAnnouncement, UiSubmenuHeader, isTypingKey, useScopedIdStoreValue, } from "@gooddata/sdk-ui-kit";
|
|
8
|
-
import {
|
|
8
|
+
import { getIconByObject } from "./utils/icons.js";
|
|
9
9
|
const SEARCH_FIELD_VISIBILITY_THRESHOLD = 7;
|
|
10
10
|
const SEARCH_DEBOUNCE_MS = 300;
|
|
11
11
|
const MAX_VISIBLE_ITEMS = 7;
|
|
@@ -79,7 +79,7 @@ export function GenAiChatContextChooserBody({ inputItems, title, titleId, search
|
|
|
79
79
|
}, children: (item) => _jsx(ContextChooserItem, { item: item, onSelect: () => handleSelect(item) }) }) })) : (_jsx(NoData, { hasNoMatchingData: hasNoMatchingData, notFoundLabel: intl.formatMessage(msgs.noMatchingData), noDataLabel: intl.formatMessage(msgs.noDataAvailable) }))] }));
|
|
80
80
|
}
|
|
81
81
|
function ContextChooserItem({ item, onSelect }) {
|
|
82
|
-
const icon =
|
|
82
|
+
const icon = getIconByObject(item);
|
|
83
83
|
return (_jsxs("div", { className: "gd-list-item", onClick: onSelect, children: [icon.iconBefore ? _jsx(UiIcon, { size: 16, type: icon.iconBefore, color: icon.iconColor }) : null, _jsx(ShortenedText, { ellipsisPosition: "end", children: item.title })
|
|
84
84
|
] }));
|
|
85
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToolsReferences.d.ts","sourceRoot":"","sources":["../../../src/components/completion/useToolsReferences.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useToolsReferences.d.ts","sourceRoot":"","sources":["../../../src/components/completion/useToolsReferences.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,EAAE,CAuBpF"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { isChatConversationToolResultContent, } from "@gooddata/sdk-backend-spi";
|
|
3
|
+
import { isChatConversationToolCallContent, isChatConversationToolResultContent, } from "@gooddata/sdk-backend-spi";
|
|
4
4
|
export function useToolsReferences(groups) {
|
|
5
5
|
return useMemo(() => {
|
|
6
6
|
const references = [];
|
|
7
|
+
const mapping = {};
|
|
7
8
|
groups.forEach((group) => {
|
|
8
9
|
group.messages.forEach((message) => {
|
|
9
10
|
const cont = message.content;
|
|
@@ -11,15 +12,18 @@ export function useToolsReferences(groups) {
|
|
|
11
12
|
if (cont.type === "error" || cont.type === "system") {
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
15
|
+
if (isChatConversationToolCallContent(cont)) {
|
|
16
|
+
mapping[cont.callId] = cont;
|
|
17
|
+
}
|
|
14
18
|
if (isChatConversationToolResultContent(cont)) {
|
|
15
|
-
parseToolResults(references, cont);
|
|
19
|
+
parseToolResults(references, mapping[cont.callId], cont);
|
|
16
20
|
}
|
|
17
21
|
});
|
|
18
22
|
});
|
|
19
|
-
return references;
|
|
23
|
+
return references.map((obj) => ({ ...obj, title: obj.title ?? obj.id }));
|
|
20
24
|
}, [groups]);
|
|
21
25
|
}
|
|
22
|
-
function parseToolResults(references, cont) {
|
|
26
|
+
function parseToolResults(references, call, cont) {
|
|
23
27
|
// Is not an objects, skip it
|
|
24
28
|
if (typeof cont.result === "string") {
|
|
25
29
|
return;
|
|
@@ -31,7 +35,6 @@ function parseToolResults(references, cont) {
|
|
|
31
35
|
const created = res.parsed_objects.map((obj) => ({
|
|
32
36
|
type: obj.object_type,
|
|
33
37
|
id: obj.object_id,
|
|
34
|
-
title: "",
|
|
35
38
|
}));
|
|
36
39
|
mergeReferenceObjectInfos(references, created);
|
|
37
40
|
}
|
|
@@ -44,15 +47,85 @@ function parseToolResults(references, cont) {
|
|
|
44
47
|
}));
|
|
45
48
|
mergeReferenceObjectInfos(references, created);
|
|
46
49
|
}
|
|
47
|
-
//.
|
|
50
|
+
//.res.data.metrics
|
|
48
51
|
if (Array.isArray(res.data?.metrics)) {
|
|
49
52
|
const created = res.data.metrics.map((obj) => ({
|
|
50
53
|
type: obj.type,
|
|
51
54
|
id: obj.id,
|
|
52
|
-
title: obj.attributes?.title
|
|
55
|
+
title: obj.attributes?.title,
|
|
53
56
|
}));
|
|
54
57
|
mergeReferenceObjectInfos(references, created);
|
|
55
58
|
}
|
|
59
|
+
//.dashboard in "get_dashboard_context"
|
|
60
|
+
if (call?.name === "get_dashboard_context" && res.dashboard) {
|
|
61
|
+
const dash = res.dashboard;
|
|
62
|
+
if (dash.id) {
|
|
63
|
+
mergeReferenceObjectInfos(references, [
|
|
64
|
+
{
|
|
65
|
+
type: "dashboard",
|
|
66
|
+
id: dash.id,
|
|
67
|
+
title: dash.title,
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
dash.widgets?.forEach((widget) => {
|
|
71
|
+
switch (widget.widget_type) {
|
|
72
|
+
case "visualization_switcher": {
|
|
73
|
+
const created = [];
|
|
74
|
+
created.push({
|
|
75
|
+
type: "visualization",
|
|
76
|
+
id: widget.active_visualization_id,
|
|
77
|
+
title: widget.title,
|
|
78
|
+
});
|
|
79
|
+
widget.visualization_ids?.forEach((id) => {
|
|
80
|
+
created.push({
|
|
81
|
+
type: "visualization",
|
|
82
|
+
id,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
widget.visualizations?.forEach(({ visualization_id, title }) => {
|
|
86
|
+
created.push({
|
|
87
|
+
type: "visualization",
|
|
88
|
+
id: visualization_id,
|
|
89
|
+
title,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
mergeReferenceObjectInfos(references, created);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "insight": {
|
|
96
|
+
mergeReferenceObjectInfos(references, [
|
|
97
|
+
{
|
|
98
|
+
type: "visualization",
|
|
99
|
+
id: widget.visualization_id,
|
|
100
|
+
title: widget.title,
|
|
101
|
+
},
|
|
102
|
+
]);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//.parent in "get_object_with_children"
|
|
110
|
+
if (call?.name === "get_object_with_children" && res.parent) {
|
|
111
|
+
const par = res.parent;
|
|
112
|
+
mergeReferenceObjectInfos(references, [
|
|
113
|
+
{
|
|
114
|
+
type: (par.final_type ?? par.type),
|
|
115
|
+
id: par.id,
|
|
116
|
+
title: par.title,
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
//.children in "get_object_with_children"
|
|
121
|
+
if (call?.name === "get_object_with_children" && res.children) {
|
|
122
|
+
const children = res.children;
|
|
123
|
+
mergeReferenceObjectInfos(references, children.map((child) => ({
|
|
124
|
+
type: (child.final_type ?? child.type),
|
|
125
|
+
id: child.id,
|
|
126
|
+
title: child.title,
|
|
127
|
+
})));
|
|
128
|
+
}
|
|
56
129
|
}
|
|
57
130
|
function mergeReferenceObjectInfos(objects, created) {
|
|
58
131
|
created.forEach((obj) => {
|
|
@@ -73,6 +73,7 @@ function toContextObjects(items, type, emptyReferenceLabel) {
|
|
|
73
73
|
where: "referencedObjects",
|
|
74
74
|
title: item.title || emptyReferenceLabel || item.id,
|
|
75
75
|
nesting: 1,
|
|
76
|
+
...(item.visualizationUrl ? { visualizationUrl: item.visualizationUrl } : {}),
|
|
76
77
|
}));
|
|
77
78
|
}
|
|
78
79
|
function isSameObject(a, b) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveInteractionIntelligenceFromSteps.d.ts","sourceRoot":"","sources":["../../../../src/components/intelligence/data/deriveInteractionIntelligenceFromSteps.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,KAAK,EAIR,wBAAwB,EACxB,8BAA8B,EAEjC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"deriveInteractionIntelligenceFromSteps.d.ts","sourceRoot":"","sources":["../../../../src/components/intelligence/data/deriveInteractionIntelligenceFromSteps.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,KAAK,EAIR,wBAAwB,EACxB,8BAA8B,EAEjC,MAAM,YAAY,CAAC;AAmEpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sCAAsC,CAClD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,8BAA8B,GACtC,wBAAwB,CAoF1B;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAC/C,KAAK,EAAE,8BAA8B,GACtC,8BAA8B,CAgBhC"}
|
|
@@ -16,10 +16,36 @@ const CATEGORY_LABEL_MESSAGES = defineMessages({
|
|
|
16
16
|
});
|
|
17
17
|
/** `stepId` of the memory step. The backend records none for it, so this collides with no real one. */
|
|
18
18
|
const MEMORY_STEP_ID = "memory";
|
|
19
|
+
/**
|
|
20
|
+
* Skills hidden from the skill-routing card. Neither is user-configurable — Object search is
|
|
21
|
+
* auto-attached to every agent, Knowledge search comes from the agent's "AI knowledge" setting —
|
|
22
|
+
* so showing them implies a routing decision the model never made. The detail identifies skills
|
|
23
|
+
* by title only; these literals mirror the backend's `SearchSkill`/`KnowledgeSkill` title constants.
|
|
24
|
+
*/
|
|
25
|
+
const HIDDEN_SKILL_TITLES = ["Object search", "Knowledge search"];
|
|
26
|
+
/**
|
|
27
|
+
* Drops the hidden skills from a skill-routing detail, and the whole detail when no configurable
|
|
28
|
+
* skill was available — routing over auto-attached skills alone is no decision to display. Other
|
|
29
|
+
* categories pass through unchanged.
|
|
30
|
+
*/
|
|
31
|
+
function filterHiddenSkills(detail) {
|
|
32
|
+
if (detail.category !== "skillRouting") {
|
|
33
|
+
return detail;
|
|
34
|
+
}
|
|
35
|
+
const available = detail.available.filter((title) => !HIDDEN_SKILL_TITLES.includes(title));
|
|
36
|
+
if (available.length === 0) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
...detail,
|
|
41
|
+
available,
|
|
42
|
+
activated: detail.activated.filter((title) => !HIDDEN_SKILL_TITLES.includes(title)),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
19
45
|
/** The details of the work done before the first step — the memory applied to the turn. */
|
|
20
46
|
function preStepDetails(trace) {
|
|
21
47
|
return (trace.responseDetails ?? [])
|
|
22
|
-
.map(({ detail }) => detail)
|
|
48
|
+
.map(({ detail }) => (detail ? filterHiddenSkills(detail) : undefined))
|
|
23
49
|
.filter((detail) => !!detail);
|
|
24
50
|
}
|
|
25
51
|
/** How long that work took, and so the width of its step. 0 when it reported no duration. */
|
|
@@ -64,7 +90,8 @@ export function deriveInteractionIntelligenceFromSteps(responseId, trace) {
|
|
|
64
90
|
const index = position + firstStepIndex;
|
|
65
91
|
const actions = trace.detailsByStepId[step.stepId] ?? [];
|
|
66
92
|
const categoriesInStep = [];
|
|
67
|
-
for (const
|
|
93
|
+
for (const action of actions) {
|
|
94
|
+
const detail = action.detail ? filterHiddenSkills(action.detail) : undefined;
|
|
68
95
|
if (!detail) {
|
|
69
96
|
continue;
|
|
70
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/AssistantItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMjE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,KAAK,kBAAkB,GAAG;IACtB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"AssistantItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/AssistantItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMjE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,KAAK,kBAAkB,GAAG;IACtB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,kDAiFrF"}
|
|
@@ -21,7 +21,7 @@ export function AssistantItemComponent({ message, groups, isLast }) {
|
|
|
21
21
|
const references = useToolsReferences(groups);
|
|
22
22
|
const [isInteractionIntelligenceOpen, setIsInteractionIntelligenceOpen] = useState(false);
|
|
23
23
|
const interactionIntelligenceEnabled = useSelector(interactionIntelligenceEnabledSelector);
|
|
24
|
-
const showInteractionIntelligence = interactionIntelligenceEnabled && !!message.responseId;
|
|
24
|
+
const showInteractionIntelligence = interactionIntelligenceEnabled && !!message.responseId && message.content.type !== "reasoning";
|
|
25
25
|
const interactionIntelligenceTotals = useInteractionIntelligenceTotals(showInteractionIntelligence ? message.responseId : "");
|
|
26
26
|
// The trigger only renders once its totals exist, so this is what actually shares the actions
|
|
27
27
|
// row with feedback — a message with no trace keeps its feedback exactly as before.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type IntlShape } from "react-intl";
|
|
2
2
|
import { type IconType, type ThemeColor } from "@gooddata/sdk-ui-kit";
|
|
3
3
|
import { type IGenAIContextObject } from "../../types.js";
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function getIconByObject(object: Pick<IGenAIContextObject, "type" | "visualizationUrl">): {
|
|
5
5
|
iconBefore?: IconType;
|
|
6
6
|
iconColor?: ThemeColor;
|
|
7
7
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/utils/icons.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/utils/icons.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAuC1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,kBAAkB,CAAC,GAAG;IAC7F,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,CAAC;CAC1B,CAgBA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAUnG"}
|
|
@@ -8,8 +8,35 @@ const msgs = defineMessages({
|
|
|
8
8
|
id: "gd.gen-ai.context.type.visualization",
|
|
9
9
|
},
|
|
10
10
|
});
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const VISUALIZATION_TYPE_ICONS = {
|
|
12
|
+
area: "visualizationArea",
|
|
13
|
+
bar: "visualizationBar",
|
|
14
|
+
bubble: "visualizationBubble",
|
|
15
|
+
bullet: "visualizationBullet",
|
|
16
|
+
column: "visualizationColumn",
|
|
17
|
+
combo: "visualizationCombo",
|
|
18
|
+
combo2: "visualizationCombo",
|
|
19
|
+
dependencywheel: "visualizationDependencywheel",
|
|
20
|
+
donut: "visualizationDonut",
|
|
21
|
+
funnel: "visualizationFunnel",
|
|
22
|
+
headline: "visualizationHeadline",
|
|
23
|
+
heatmap: "visualizationHeatmap",
|
|
24
|
+
line: "visualizationLine",
|
|
25
|
+
pie: "visualizationPie",
|
|
26
|
+
pushpin: "visualizationPushpin",
|
|
27
|
+
pushpinnext: "visualizationPushpin",
|
|
28
|
+
pyramid: "visualizationPyramid",
|
|
29
|
+
repeater: "visualizationRepeater",
|
|
30
|
+
sankey: "visualizationSankey",
|
|
31
|
+
scatter: "visualizationScatter",
|
|
32
|
+
table: "visualizationTable",
|
|
33
|
+
tablenext: "visualizationTable",
|
|
34
|
+
treemap: "visualizationTreemap",
|
|
35
|
+
waterfall: "visualizationWaterfall",
|
|
36
|
+
xirr: "visualizationXirr",
|
|
37
|
+
};
|
|
38
|
+
export function getIconByObject(object) {
|
|
39
|
+
switch (object.type) {
|
|
13
40
|
case "dashboard":
|
|
14
41
|
return {
|
|
15
42
|
iconBefore: "dashboard",
|
|
@@ -18,7 +45,7 @@ export function getIconByType(type) {
|
|
|
18
45
|
case "visualization":
|
|
19
46
|
case "widget":
|
|
20
47
|
return {
|
|
21
|
-
iconBefore:
|
|
48
|
+
iconBefore: getVisualizationIcon(object.visualizationUrl),
|
|
22
49
|
iconColor: "complementary-6",
|
|
23
50
|
};
|
|
24
51
|
default:
|
|
@@ -36,3 +63,9 @@ export function getTypeLabel(type, intl) {
|
|
|
36
63
|
return undefined;
|
|
37
64
|
}
|
|
38
65
|
}
|
|
66
|
+
function getVisualizationIcon(visualizationUrl) {
|
|
67
|
+
const type = visualizationUrl?.split(":").at(-1);
|
|
68
|
+
return type && Object.hasOwn(VISUALIZATION_TYPE_ICONS, type)
|
|
69
|
+
? VISUALIZATION_TYPE_ICONS[type]
|
|
70
|
+
: "visualization";
|
|
71
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EAGzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAwCvB;AAED,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EAGzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAwCvB;AAED,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAuFvB"}
|
|
@@ -82,6 +82,7 @@ export function collectAvailableReferences(context, placeholderTitle) {
|
|
|
82
82
|
type: "widget",
|
|
83
83
|
context,
|
|
84
84
|
insightRef: widget.insightRef,
|
|
85
|
+
...(widget.visualizationUrl ? { visualizationUrl: widget.visualizationUrl } : {}),
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
break;
|
|
@@ -105,6 +106,9 @@ export function collectAvailableReferences(context, placeholderTitle) {
|
|
|
105
106
|
type: "widget",
|
|
106
107
|
context,
|
|
107
108
|
insightRef: visualization.insightRef,
|
|
109
|
+
...(visualization.visualizationUrl
|
|
110
|
+
? { visualizationUrl: visualization.visualizationUrl }
|
|
111
|
+
: {}),
|
|
108
112
|
});
|
|
109
113
|
}
|
|
110
114
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FilterContextItem, type GenAIUserContextFilter, type IAttributeDisplayFormMetadataObject, type IDashboardDefinition, type IGenAIDashboardContext, type IGenAIObjectReference, type IGenAIUserContext, type IGenAIWidgetDescriptor, type IWidget, type ObjRef } from "@gooddata/sdk-model";
|
|
1
|
+
import { type FilterContextItem, type GenAIUserContextFilter, type IAttributeDisplayFormMetadataObject, type IDashboardDefinition, type IGenAIDashboardContext, type IGenAIObjectReference, type IGenAIUserContext, type IGenAIWidgetDescriptor, type IInsight, type IWidget, type ObjRef } from "@gooddata/sdk-model";
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
@@ -14,7 +14,7 @@ export declare function buildFiltersContext(filters: FilterContextItem[], displa
|
|
|
14
14
|
/**
|
|
15
15
|
* @internal
|
|
16
16
|
*/
|
|
17
|
-
export declare function buildWidgetsContext(widgetsMap: Pick<Map<ObjRef, IWidget>, "values" | "get"> | undefined, resultsIdMap?: Pick<Map<string, string | undefined>, "values" | "get">, visualizationSwitcherActiveVisualizations?: Record<string, string>): {
|
|
17
|
+
export declare function buildWidgetsContext(widgetsMap: Pick<Map<ObjRef, IWidget>, "values" | "get"> | undefined, resultsIdMap?: Pick<Map<string, string | undefined>, "values" | "get">, visualizationSwitcherActiveVisualizations?: Record<string, string>, insightsMap?: Pick<Map<ObjRef, IInsight>, "get">): {
|
|
18
18
|
widgets: IGenAIWidgetDescriptor[];
|
|
19
19
|
referencedObjects: IGenAIObjectReference[];
|
|
20
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/context/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEtB,KAAK,sBAAsB,EAC3B,KAAK,OAAO,EACZ,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/context/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEtB,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,MAAM,EAUd,MAAM,qBAAqB,CAAC;AAM7B;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC,EACrD,UAAU,CAAC,EAAE,oBAAoB,GAClC,iBAAiB,CASnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,SAAS,GAAG,uBAAuB,GAAG,UAAU,EAC5D,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,GACpF,sBAAsB,CAOxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,CAAC,EAAE,KAAK,CAAC,GAC7E,sBAAsB,EAAE,CA2E1B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,GAAG,SAAS,EACpE,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,EACtE,yCAAyC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClE,WAAW,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,GACjD;IAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,CA0EnF"}
|
package/esm/context/dashboard.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
-
import { isAttributeElementsByRef, isDashboardAttributeFilter, isDashboardDateFilter, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
2
|
+
import { insightVisualizationUrl, isAttributeElementsByRef, isDashboardAttributeFilter, isDashboardDateFilter, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
3
3
|
import { DEFAULT_MESSAGES } from "@gooddata/sdk-ui";
|
|
4
4
|
import { DateFilterHelpers } from "@gooddata/sdk-ui-filters";
|
|
5
5
|
import { buildContext } from "./build.js";
|
|
@@ -94,7 +94,7 @@ export function buildFiltersContext(filters, displayForms) {
|
|
|
94
94
|
/**
|
|
95
95
|
* @internal
|
|
96
96
|
*/
|
|
97
|
-
export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitcherActiveVisualizations) {
|
|
97
|
+
export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitcherActiveVisualizations, insightsMap) {
|
|
98
98
|
const widgets = [];
|
|
99
99
|
const referencedObjects = [];
|
|
100
100
|
if (!widgetsMap) {
|
|
@@ -114,6 +114,7 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
|
|
|
114
114
|
widgets.push(buildWidgetContext(widget.title, widget.ref, "insight", {
|
|
115
115
|
insightRef: widget.insight,
|
|
116
116
|
resultId: resultsIdMap?.get(serializeObjRef(widget.ref)),
|
|
117
|
+
...visualizationUrlOf(insightsMap, widget.insight),
|
|
117
118
|
}));
|
|
118
119
|
referencedObjects.push({ type: "WIDGET", ref: widget.ref, title: widget.title });
|
|
119
120
|
}
|
|
@@ -127,10 +128,12 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
|
|
|
127
128
|
resultId: activeVisualization
|
|
128
129
|
? resultsIdMap?.get(serializeObjRef(activeVisualization.ref))
|
|
129
130
|
: undefined,
|
|
131
|
+
...visualizationUrlOf(insightsMap, activeVisualization?.insight),
|
|
130
132
|
// All child insights, so the BE can execute the non-active children
|
|
131
133
|
// (which have no cached result).
|
|
132
134
|
visualizations: widget.visualizations.map((v) => buildWidgetContext(v.title, v.ref, "insight", {
|
|
133
135
|
insightRef: v.insight,
|
|
136
|
+
...visualizationUrlOf(insightsMap, v.insight),
|
|
134
137
|
})),
|
|
135
138
|
}));
|
|
136
139
|
referencedObjects.push({
|
|
@@ -147,6 +150,11 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
|
|
|
147
150
|
}
|
|
148
151
|
return { widgets, referencedObjects };
|
|
149
152
|
}
|
|
153
|
+
//utils
|
|
154
|
+
function visualizationUrlOf(insightsMap, insightRef) {
|
|
155
|
+
const insight = insightRef ? insightsMap?.get(insightRef) : undefined;
|
|
156
|
+
return insight ? { visualizationUrl: insightVisualizationUrl(insight) } : {};
|
|
157
|
+
}
|
|
150
158
|
const GRANULARITY_TO_GENAI = {
|
|
151
159
|
"GDC.time.minute": "MINUTE",
|
|
152
160
|
"GDC.time.hour": "HOUR",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDashboardAmbientContext.d.ts","sourceRoot":"","sources":["../../../src/context/hooks/useDashboardAmbientContext.ts"],"names":[],"mappings":"AAOA,OAAO,EAEH,KAAK,0BAA0B,EAalC,MAAM,4BAA4B,CAAC;AAMpC,wBAAgB,0BAA0B,CAAC,iBAAiB,CAAC,EAAE,0BAA0B,QAQxF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { useDispatch } from "react-redux";
|
|
4
|
+
import { idRef } from "@gooddata/sdk-model";
|
|
5
|
+
import { newDisplayFormMap, newMapForObjectWithIdentity, selectActiveTab, selectAttributeFilterDisplayFormsMap, selectDashboardId, selectDashboardTitle, selectDashboardWorkingDefinition, selectFilterContextFilters, selectIsNewDashboard, selectVisualizationSwitcherActiveVisualizations, selectWidgetsMap, } from "@gooddata/sdk-ui-dashboard";
|
|
6
|
+
import { setAmbientUserContextAction } from "../../store/chatWindow/chatWindowSlice.js";
|
|
7
|
+
import { mergeContexts } from "../build.js";
|
|
8
|
+
import { buildDashboardContext, buildFiltersContext, buildWidgetsContext } from "../dashboard.js";
|
|
9
|
+
export function useDashboardAmbientContext(dashboardSelector) {
|
|
10
|
+
const dispatch = useDispatch();
|
|
11
|
+
const used = useRef(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const context = dashboardSelector ? buildFromDashboard(dashboardSelector) : undefined;
|
|
14
|
+
setContext(dispatch, context, used);
|
|
15
|
+
}, [dashboardSelector, dispatch]);
|
|
16
|
+
}
|
|
17
|
+
function setContext(dispatch, context, used) {
|
|
18
|
+
if (context) {
|
|
19
|
+
dispatch(setAmbientUserContextAction({ userContext: context }));
|
|
20
|
+
used.current = true;
|
|
21
|
+
}
|
|
22
|
+
if (!context && used.current) {
|
|
23
|
+
dispatch(setAmbientUserContextAction({ userContext: undefined }));
|
|
24
|
+
used.current = false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function buildFromDashboard(dashboardSelector) {
|
|
28
|
+
const dashboardId = selectWithDefault(dashboardSelector, selectDashboardId, "new-dashboard");
|
|
29
|
+
const dashboardTitle = selectWithDefault(dashboardSelector, selectDashboardTitle, "");
|
|
30
|
+
const isNewDashboard = selectWithDefault(dashboardSelector, selectIsNewDashboard, false);
|
|
31
|
+
const filterContextItems = selectWithDefault(dashboardSelector, selectFilterContextFilters, []);
|
|
32
|
+
const displayForms = selectWithDefault(dashboardSelector, selectAttributeFilterDisplayFormsMap, newDisplayFormMap([]));
|
|
33
|
+
const widgetsMap = selectWithDefault(dashboardSelector, selectWidgetsMap, newMapForObjectWithIdentity([]));
|
|
34
|
+
const activeTab = selectWithOptional(dashboardSelector, selectActiveTab);
|
|
35
|
+
const workingDefinition = selectWithOptional(dashboardSelector, selectDashboardWorkingDefinition);
|
|
36
|
+
const visualizationSwitcherActiveVisualizations = selectWithDefault(dashboardSelector, selectVisualizationSwitcherActiveVisualizations, {});
|
|
37
|
+
const resultsEnvelopes = dashboardSelector((state) => state.executionResults.entities);
|
|
38
|
+
const results = Object.entries(resultsEnvelopes).reduce((acc, [key, value]) => {
|
|
39
|
+
acc.set(key, value.executionResult?.resultId() ?? undefined);
|
|
40
|
+
return acc;
|
|
41
|
+
}, new Map());
|
|
42
|
+
const filters = buildFiltersContext(filterContextItems ?? [], displayForms);
|
|
43
|
+
const { widgets } = buildWidgetsContext(widgetsMap, results, visualizationSwitcherActiveVisualizations);
|
|
44
|
+
return mergeContexts(buildDashboardContext({
|
|
45
|
+
ref: idRef(dashboardId, "analyticalDashboard"),
|
|
46
|
+
isNew: isNewDashboard,
|
|
47
|
+
title: dashboardTitle,
|
|
48
|
+
widgets,
|
|
49
|
+
filters,
|
|
50
|
+
...(activeTab ? { activeTabId: activeTab.localIdentifier } : {}),
|
|
51
|
+
}, workingDefinition));
|
|
52
|
+
}
|
|
53
|
+
function selectWithDefault(dashboardSelector, selector, defaultValue) {
|
|
54
|
+
try {
|
|
55
|
+
return dashboardSelector(selector) ?? defaultValue;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return defaultValue;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function selectWithOptional(dashboardSelector, selector) {
|
|
62
|
+
try {
|
|
63
|
+
return dashboardSelector(selector);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type EnhancedStore } from "@reduxjs/toolkit";
|
|
2
|
+
/**
|
|
3
|
+
* Hook to retrieve the GenAI dispatcher.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* This hook must be used within a GenAiStore component.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare function useGenAiDispatcher(): EnhancedStore["dispatch"];
|
|
11
|
+
//# sourceMappingURL=useGenAiDispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGenAiDispatcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useGenAiDispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAAC,UAAU,CAAC,CAE9D"}
|