@gooddata/sdk-ui-gen-ai 11.55.0-alpha.2 → 11.55.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +4 -4
- package/esm/components/GenAIChatContextIndicator.d.ts +2 -2
- package/esm/components/GenAIChatContextIndicator.d.ts.map +1 -1
- package/esm/components/GenAIChatContextIndicator.js +81 -13
- package/esm/components/GenAiChatContextChooser.d.ts.map +1 -1
- package/esm/components/GenAiChatContextChooser.js +4 -3
- package/esm/components/GenAiChatContextChooserBody.d.ts +3 -1
- package/esm/components/GenAiChatContextChooserBody.d.ts.map +1 -1
- package/esm/components/GenAiChatContextChooserBody.js +7 -4
- package/esm/components/Input.js +1 -1
- package/esm/components/hooks/useContextChangeAnnouncement.d.ts +2 -2
- package/esm/components/hooks/useContextChangeAnnouncement.d.ts.map +1 -1
- package/esm/components/hooks/useContextChangeAnnouncement.js +9 -4
- package/esm/components/hooks/useContextItems.d.ts +9 -3
- package/esm/components/hooks/useContextItems.d.ts.map +1 -1
- package/esm/components/hooks/useContextItems.js +51 -8
- package/esm/context/addContextReference.d.ts +0 -2
- package/esm/context/addContextReference.d.ts.map +1 -1
- package/esm/context/addContextReference.js +12 -35
- package/esm/context/collectContextReferences.d.ts +2 -2
- package/esm/context/collectContextReferences.d.ts.map +1 -1
- package/esm/context/collectContextReferences.js +22 -20
- package/esm/context/removeContextReference.d.ts +2 -16
- package/esm/context/removeContextReference.d.ts.map +1 -1
- package/esm/context/removeContextReference.js +7 -70
- package/esm/context/selectContextReferences.d.ts +5 -0
- package/esm/context/selectContextReferences.d.ts.map +1 -0
- package/esm/context/selectContextReferences.js +68 -0
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +8 -0
- package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +8 -0
- package/esm/localization/bundles/zh-HK.localization-bundle.js +9 -9
- package/esm/store/chatWindow/chatWindowSelectors.d.ts +2 -1
- package/esm/store/chatWindow/chatWindowSelectors.d.ts.map +1 -1
- package/esm/store/chatWindow/chatWindowSelectors.js +1 -0
- package/esm/store/chatWindow/chatWindowSlice.d.ts +2 -2
- package/esm/store/chatWindow/chatWindowSlice.d.ts.map +1 -1
- package/esm/store/chatWindow/chatWindowSlice.js +11 -6
- package/esm/types.d.ts +22 -0
- package/esm/types.d.ts.map +1 -1
- package/package.json +20 -20
- package/styles/css/main.css +4 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/main.scss +5 -0
package/NOTICE
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
The following 3rd-party software packages may be used by or distributed with gooddata-ui-sdk. Any information relevant to third-party vendors listed below are collected using common, reasonable means.
|
|
9
9
|
|
|
10
|
-
Date generated: 2026-8-
|
|
10
|
+
Date generated: 2026-8-31
|
|
11
11
|
|
|
12
|
-
Revision ID:
|
|
12
|
+
Revision ID: 14f5c085f7e749fb111a5c2dfbbf7a3d25b73682
|
|
13
13
|
|
|
14
14
|
================================================================================
|
|
15
15
|
================================================================================
|
|
@@ -35327,7 +35327,7 @@ MIT
|
|
|
35327
35327
|
|
|
35328
35328
|
Authors: admin@simonboudrias.com
|
|
35329
35329
|
Package Manager: NPM
|
|
35330
|
-
Project URL: https://
|
|
35330
|
+
Project URL: https://github.com/SBoudrias/run-async#readme
|
|
35331
35331
|
Package Download URL: https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz
|
|
35332
35332
|
Dependency Path: inquirer > run-async
|
|
35333
35333
|
File Path(s): common/config/subspaces/sdk/pnpm-lock.yaml
|
|
@@ -64321,4 +64321,4 @@ File Path(s): common/config/subspaces/sdk/pnpm-lock.yaml
|
|
|
64321
64321
|
--------------------------------------------------------------------------------
|
|
64322
64322
|
--------------------------------------------------------------------------------
|
|
64323
64323
|
|
|
64324
|
-
Report Generated by FOSSA on 2026-8-
|
|
64324
|
+
Report Generated by FOSSA on 2026-8-31
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type GenAIChatContextIndicatorOwnProps = {
|
|
2
|
-
|
|
2
|
+
onUpdate?: () => void;
|
|
3
3
|
};
|
|
4
4
|
/**
|
|
5
5
|
* Shows what ambient context the assistant is answering about — the open dashboard and its live
|
|
@@ -9,6 +9,6 @@ type GenAIChatContextIndicatorOwnProps = {
|
|
|
9
9
|
*
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
|
-
export declare function GenAIChatContextIndicator({
|
|
12
|
+
export declare function GenAIChatContextIndicator({ onUpdate }: GenAIChatContextIndicatorOwnProps): import("react/jsx-runtime").JSX.Element | null;
|
|
13
13
|
export {};
|
|
14
14
|
//# sourceMappingURL=GenAIChatContextIndicator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAIChatContextIndicator.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatContextIndicator.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GenAIChatContextIndicator.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatContextIndicator.tsx"],"names":[],"mappings":"AA0CA,KAAK,iCAAiC,GAAG;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,QAAQ,EAAE,EAAE,iCAAiC,kDAyJxF"}
|
|
@@ -3,11 +3,13 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { useCallback, useMemo } from "react";
|
|
4
4
|
import { defineMessages, useIntl } from "react-intl";
|
|
5
5
|
import { useDispatch, useSelector } from "react-redux";
|
|
6
|
-
import { UiChip, useIdPrefixed } from "@gooddata/sdk-ui-kit";
|
|
6
|
+
import { Dropdown, UiChip, useIdPrefixed } from "@gooddata/sdk-ui-kit";
|
|
7
7
|
import { collectContextReferences } from "../context/collectContextReferences.js";
|
|
8
|
-
import { contextSetupEnabledSelector, userContextSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
9
|
-
import { removeContextReferenceAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
8
|
+
import { ambientContextSelector, contextSetupEnabledSelector, selectedContextSelector, userContextSelector, } from "../store/chatWindow/chatWindowSelectors.js";
|
|
9
|
+
import { removeContextReferenceAction, selectedContextReferencesAction, } from "../store/chatWindow/chatWindowSlice.js";
|
|
10
|
+
import { GenAiChatContextChooserBody } from "./GenAiChatContextChooserBody.js";
|
|
10
11
|
import { useContextChangeAnnouncement } from "./hooks/useContextChangeAnnouncement.js";
|
|
12
|
+
import { useAmbientContextItems } from "./hooks/useContextItems.js";
|
|
11
13
|
import { getIconByObject, getTypeLabel } from "./utils/icons.js";
|
|
12
14
|
const msgs = defineMessages({
|
|
13
15
|
untitled: {
|
|
@@ -19,6 +21,9 @@ const msgs = defineMessages({
|
|
|
19
21
|
groupLabel: {
|
|
20
22
|
id: "gd.gen-ai.context.group.ariaLabel",
|
|
21
23
|
},
|
|
24
|
+
focusOn: {
|
|
25
|
+
id: "gd.gen-ai.context.focus_on",
|
|
26
|
+
},
|
|
22
27
|
});
|
|
23
28
|
/**
|
|
24
29
|
* Shows what ambient context the assistant is answering about — the open dashboard and its live
|
|
@@ -28,32 +33,95 @@ const msgs = defineMessages({
|
|
|
28
33
|
*
|
|
29
34
|
* @internal
|
|
30
35
|
*/
|
|
31
|
-
export function GenAIChatContextIndicator({
|
|
36
|
+
export function GenAIChatContextIndicator({ onUpdate }) {
|
|
32
37
|
const intl = useIntl();
|
|
33
38
|
const emptyReferenceLabel = intl.formatMessage(msgs.untitled);
|
|
34
39
|
const groupLabelId = useIdPrefixed("context-indicator-label");
|
|
35
40
|
const isContextSetupEnabled = useSelector(contextSetupEnabledSelector);
|
|
36
|
-
const
|
|
37
|
-
const
|
|
41
|
+
const ambientContext = useSelector(ambientContextSelector);
|
|
42
|
+
const userContext = useSelector(userContextSelector);
|
|
43
|
+
const selectedContext = useSelector(selectedContextSelector);
|
|
44
|
+
const { items, search, setSearch, selectedIds } = useAmbientContextItems(ambientContext);
|
|
45
|
+
const addContextLabel = intl.formatMessage(msgs.focusOn);
|
|
46
|
+
const titleId = useIdPrefixed("context-focuson-title");
|
|
47
|
+
const references = useMemo(() => collectContextReferences(userContext, selectedContext, emptyReferenceLabel), [userContext, selectedContext, emptyReferenceLabel]);
|
|
38
48
|
const dispatch = useDispatch();
|
|
39
49
|
const removeContextReference = useCallback((payload) => dispatch(removeContextReferenceAction(payload)), [dispatch]);
|
|
50
|
+
const onAmbientToggleHandler = useCallback(() => {
|
|
51
|
+
return () => {
|
|
52
|
+
dispatch(selectedContextReferencesAction({
|
|
53
|
+
...selectedContext,
|
|
54
|
+
activated: !selectedContext?.activated,
|
|
55
|
+
}));
|
|
56
|
+
onUpdate?.();
|
|
57
|
+
};
|
|
58
|
+
}, [dispatch, onUpdate, selectedContext]);
|
|
40
59
|
const onDeleteHandler = useCallback((reference) => {
|
|
41
60
|
return () => {
|
|
42
61
|
removeContextReference({ object: reference });
|
|
43
|
-
|
|
62
|
+
onUpdate?.();
|
|
44
63
|
};
|
|
45
|
-
}, [removeContextReference,
|
|
46
|
-
const
|
|
64
|
+
}, [removeContextReference, onUpdate]);
|
|
65
|
+
const onOpenStateChanged = useCallback(() => {
|
|
66
|
+
setSearch("");
|
|
67
|
+
}, [setSearch]);
|
|
68
|
+
const announcement = useContextChangeAnnouncement(selectedContext, references);
|
|
47
69
|
if (!isContextSetupEnabled) {
|
|
48
70
|
return null;
|
|
49
71
|
}
|
|
50
|
-
return (_jsxs(_Fragment, { children: [
|
|
51
|
-
|
|
72
|
+
return (_jsxs(_Fragment, { children: [
|
|
73
|
+
_jsxs(ContextWrapper, { groupLabel: msgs.groupLabel, groupLabelId: groupLabelId, children: [selectedContext?.dashboard ? (_jsx(Dropdown, { alignPoints: [{ align: "tl bl", offset: { x: 0, y: 0 } }], closeOnEscape: true, fullscreenOnMobile: false, autofocusOnOpen: true, accessibilityConfig: { popupRole: "dialog" }, onOpenStateChanged: onOpenStateChanged, renderButton: ({ isOpen, toggleDropdown, accessibilityConfig }) => {
|
|
74
|
+
const item = selectedContext.visualization ?? selectedContext.dashboard;
|
|
75
|
+
if (!item) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return (_jsx(UiChip, { isActionable: true, isExpandable: true, isActive: isOpen, ...getIconByObject(item), label: getSelectedTitle(selectedContext, emptyReferenceLabel), iconAction: selectedContext.activated ? "visible" : "invisible", variant: selectedContext.activated ? "normal" : "inactive", onClick: toggleDropdown, onAction: onAmbientToggleHandler(), accessibilityConfig: {
|
|
79
|
+
...accessibilityConfig,
|
|
80
|
+
deleteAriaLabel: intl.formatMessage(msgs.remove, {
|
|
81
|
+
title: getSelectedTitle(selectedContext, emptyReferenceLabel),
|
|
82
|
+
}),
|
|
83
|
+
iconBeforeAriaLabel: getTypeLabel(item.type, intl),
|
|
84
|
+
} }));
|
|
85
|
+
}, renderBody: ({ closeDropdown, ariaAttributes }) => (_jsx(GenAiChatContextChooserBody, { inputItems: items, selectedIds: selectedIds, title: addContextLabel, titleId: titleId, search: search, onSearchChange: setSearch, ariaAttributes: ariaAttributes, closeDropdown: closeDropdown, onSelect: (item) => {
|
|
86
|
+
dispatch(selectedContextReferencesAction({
|
|
87
|
+
...selectedContext,
|
|
88
|
+
...(item.type === "dashboard"
|
|
89
|
+
? {
|
|
90
|
+
dashboard: item,
|
|
91
|
+
visualization: undefined,
|
|
92
|
+
}
|
|
93
|
+
: {}),
|
|
94
|
+
...(item.type === "visualization" || item.type === "widget"
|
|
95
|
+
? {
|
|
96
|
+
visualization: item,
|
|
97
|
+
}
|
|
98
|
+
: {}),
|
|
99
|
+
activated: true,
|
|
100
|
+
}));
|
|
101
|
+
onUpdate?.();
|
|
102
|
+
} })) })) : null, references.length > 0
|
|
103
|
+
? references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...getIconByObject(reference), label: reference.title, isExpandable: false, onDelete: onDeleteHandler(reference), accessibilityConfig: {
|
|
52
104
|
deleteAriaLabel: intl.formatMessage(msgs.remove, {
|
|
53
105
|
title: reference.title,
|
|
54
106
|
}),
|
|
55
107
|
iconBeforeAriaLabel: getTypeLabel(reference.type, intl),
|
|
56
|
-
} }, index)))
|
|
57
|
-
|
|
108
|
+
} }, index)))
|
|
109
|
+
: null] }), _jsx("span", { className: "sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement })
|
|
58
110
|
] }));
|
|
59
111
|
}
|
|
112
|
+
function ContextWrapper({ groupLabel, groupLabelId, children }) {
|
|
113
|
+
const intl = useIntl();
|
|
114
|
+
return (_jsxs(_Fragment, { children: [
|
|
115
|
+
_jsx("span", { className: "sr-only", id: groupLabelId, children: intl.formatMessage(groupLabel) }), _jsx("div", { className: "gd-gen-ai-chat__context-indicator", role: "group", "aria-labelledby": groupLabelId, children: children })
|
|
116
|
+
] }));
|
|
117
|
+
}
|
|
118
|
+
// utils
|
|
119
|
+
function getSelectedTitle(selectedContext, emptyReferenceLabel) {
|
|
120
|
+
const label = [
|
|
121
|
+
...(selectedContext.dashboard ? [selectedContext.dashboard.title || emptyReferenceLabel] : []),
|
|
122
|
+
...(selectedContext.visualization
|
|
123
|
+
? [selectedContext.visualization.title || emptyReferenceLabel]
|
|
124
|
+
: []),
|
|
125
|
+
];
|
|
126
|
+
return label.join(" / ");
|
|
127
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAiChatContextChooser.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatContextChooser.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GenAiChatContextChooser.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatContextChooser.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAWvD,KAAK,+BAA+B,GAAG;IACnC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,EAAE,YAAY,EAAE,EAAE,+BAA+B,kDA6ExF"}
|
|
@@ -4,10 +4,10 @@ import { useCallback } from "react";
|
|
|
4
4
|
import { defineMessages, useIntl } from "react-intl";
|
|
5
5
|
import { useDispatch, useSelector } from "react-redux";
|
|
6
6
|
import { Dropdown, UiIconButton, useIdPrefixed } from "@gooddata/sdk-ui-kit";
|
|
7
|
-
import { ambientContextSelector, userContextSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
7
|
+
import { ambientContextSelector, selectedContextSelector, userContextSelector, } from "../store/chatWindow/chatWindowSelectors.js";
|
|
8
8
|
import { addContextReferenceAction, initContextObjectsAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
9
9
|
import { GenAiChatContextChooserBody } from "./GenAiChatContextChooserBody.js";
|
|
10
|
-
import {
|
|
10
|
+
import { useUserContextItems } from "./hooks/useContextItems.js";
|
|
11
11
|
const msgs = defineMessages({
|
|
12
12
|
add: {
|
|
13
13
|
id: "gd.gen-ai.context.add_context",
|
|
@@ -18,8 +18,9 @@ export function GenAiChatContextChooser({ onAddContext }) {
|
|
|
18
18
|
const dispatch = useDispatch();
|
|
19
19
|
const titleId = useIdPrefixed("context-chooser-title");
|
|
20
20
|
const ambient = useSelector((state) => ambientContextSelector(state));
|
|
21
|
+
const selected = useSelector((state) => selectedContextSelector(state));
|
|
21
22
|
const active = useSelector((state) => userContextSelector(state));
|
|
22
|
-
const { items: inputItems, search, setSearch, isLoading, hasNextPage, loadNextPage, } =
|
|
23
|
+
const { items: inputItems, search, setSearch, isLoading, hasNextPage, loadNextPage, } = useUserContextItems(ambient, selected, active);
|
|
23
24
|
const addContextLabel = intl.formatMessage(msgs.add);
|
|
24
25
|
const onOpenStateChanged = useCallback((isOpen) => {
|
|
25
26
|
setSearch("");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ObjRef } from "@gooddata/sdk-model";
|
|
1
2
|
import { type IGenAIContextObject } from "../types.js";
|
|
2
3
|
type GenAiChatContextChooserBodyProps = {
|
|
3
4
|
inputItems: IGenAIContextObject[];
|
|
@@ -5,6 +6,7 @@ type GenAiChatContextChooserBodyProps = {
|
|
|
5
6
|
titleId: string;
|
|
6
7
|
search: string;
|
|
7
8
|
onSearchChange: (search: string) => void;
|
|
9
|
+
selectedIds?: ObjRef[];
|
|
8
10
|
isLoading?: boolean;
|
|
9
11
|
hasNextPage?: boolean;
|
|
10
12
|
loadNextPage?: () => void;
|
|
@@ -16,6 +18,6 @@ type GenAiChatContextChooserBodyProps = {
|
|
|
16
18
|
onSelect: (item: IGenAIContextObject) => void;
|
|
17
19
|
closeDropdown: () => void;
|
|
18
20
|
};
|
|
19
|
-
export declare function GenAiChatContextChooserBody({ inputItems, title, titleId, search, onSearchChange, isLoading, hasNextPage, loadNextPage, ariaAttributes, onSelect, closeDropdown }: GenAiChatContextChooserBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function GenAiChatContextChooserBody({ inputItems, title, titleId, search, selectedIds, onSearchChange, isLoading, hasNextPage, loadNextPage, ariaAttributes, onSelect, closeDropdown }: GenAiChatContextChooserBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
20
22
|
export {};
|
|
21
23
|
//# sourceMappingURL=GenAiChatContextChooserBody.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenAiChatContextChooserBody.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatContextChooserBody.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GenAiChatContextChooserBody.d.ts","sourceRoot":"","sources":["../../src/components/GenAiChatContextChooserBody.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,qBAAqB,CAAC;AAiBnE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA8BvD,KAAK,gCAAgC,GAAG;IACpC,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,QAAQ,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,EACxC,UAAU,EACV,KAAK,EACL,OAAO,EACP,MAAM,EACN,WAAW,EACX,cAAc,EACd,SAAiB,EACjB,WAAmB,EACnB,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,aAAa,EAChB,EAAE,gCAAgC,2CAyIlC"}
|
|
@@ -3,6 +3,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { useCallback, useEffect, useId } from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import { defineMessages, useIntl } from "react-intl";
|
|
6
|
+
import { areObjRefsEqual } from "@gooddata/sdk-model";
|
|
6
7
|
import { useDebouncedState } from "@gooddata/sdk-ui";
|
|
7
8
|
import { DEFAULT_ITEM_HEIGHT, DETAILED_ANNOUNCEMENT_THRESHOLD, Input, NoData, ScopedIdStore, ShortenedText, UiIcon, UiPagedVirtualList, UiSearchResultsAnnouncement, UiSubmenuHeader, isTypingKey, useScopedIdStoreValue, } from "@gooddata/sdk-ui-kit";
|
|
8
9
|
import { getIconByObject } from "./utils/icons.js";
|
|
@@ -30,7 +31,7 @@ const msgs = defineMessages({
|
|
|
30
31
|
id: "gd.gen-ai.context.noDataAvailable",
|
|
31
32
|
},
|
|
32
33
|
});
|
|
33
|
-
export function GenAiChatContextChooserBody({ inputItems, title, titleId, search, onSearchChange, isLoading = false, hasNextPage = false, loadNextPage, ariaAttributes, onSelect, closeDropdown, }) {
|
|
34
|
+
export function GenAiChatContextChooserBody({ inputItems, title, titleId, search, selectedIds, onSearchChange, isLoading = false, hasNextPage = false, loadNextPage, ariaAttributes, onSelect, closeDropdown, }) {
|
|
34
35
|
const intl = useIntl();
|
|
35
36
|
const listboxId = useId();
|
|
36
37
|
const [searchString, setSearchString, debouncedSearch] = useDebouncedState(search, SEARCH_DEBOUNCE_MS);
|
|
@@ -76,10 +77,12 @@ export function GenAiChatContextChooserBody({ inputItems, title, titleId, search
|
|
|
76
77
|
] })) : null, shouldShowPagedList ? (_jsx(ScopedIdStore, { value: scopedIdStoreValue, children: _jsx(UiPagedVirtualList, { maxHeight: listMaxHeight, items: inputItems, itemHeight: DEFAULT_ITEM_HEIGHT, itemsGap: 0, itemPadding: 0, skeletonItemsCount: skeletonItemsCount, isLoading: isLoading, hasNextPage: hasNextPage, loadNextPage: loadNextPage, representAs: "listbox", closeDropdown: closeDropdown, onKeyDownConfirm: handleSelect, listboxProps: {
|
|
77
78
|
id: listboxId,
|
|
78
79
|
"aria-label": intl.formatMessage(msgs.listAriaLabel),
|
|
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
|
+
}, children: (item) => (_jsx(ContextChooserItem, { item: item, selected: selectedIds?.some((r) => areObjRefsEqual(r, item.ref)), onSelect: () => handleSelect(item) })) }) })) : (_jsx(NoData, { hasNoMatchingData: hasNoMatchingData, notFoundLabel: intl.formatMessage(msgs.noMatchingData), noDataLabel: intl.formatMessage(msgs.noDataAvailable) }))] }));
|
|
80
81
|
}
|
|
81
|
-
function ContextChooserItem({ item, onSelect }) {
|
|
82
|
+
function ContextChooserItem({ item, selected, onSelect, }) {
|
|
82
83
|
const icon = getIconByObject(item);
|
|
83
|
-
return (_jsxs("div", { className: "gd-list-item",
|
|
84
|
+
return (_jsxs("div", { className: cx("gd-list-item", {
|
|
85
|
+
"gd-list-item--selected": selected,
|
|
86
|
+
}), onClick: onSelect, "aria-selected": selected, children: [icon.iconBefore ? _jsx(UiIcon, { size: 16, type: icon.iconBefore, color: icon.iconColor }) : null, _jsx(ShortenedText, { ellipsisPosition: "end", children: item.title })
|
|
84
87
|
] }));
|
|
85
88
|
}
|
package/esm/components/Input.js
CHANGED
|
@@ -113,7 +113,7 @@ function InputComponent({ autofocus = false, canManage, canAnalyze, targetRef })
|
|
|
113
113
|
"gd-gen-ai-chat__input--no-agents": hasNoAgents,
|
|
114
114
|
}), children: _jsxs("div", { className: "gd-gen-ai-chat__input__content", children: [
|
|
115
115
|
_jsx(HintText, { focused: focused, where: "top" }), _jsxs("div", { className: "gd-gen-ai-chat__input__container", children: [
|
|
116
|
-
_jsx("div", { className: "gd-gen-ai-chat__input__context", onMouseDown: handleContextMouseDown, children: _jsx(GenAIChatContextIndicator, {
|
|
116
|
+
_jsx("div", { className: "gd-gen-ai-chat__input__context", onMouseDown: handleContextMouseDown, children: _jsx(GenAIChatContextIndicator, { onUpdate: 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: {
|
|
117
117
|
aboveCursor: true,
|
|
118
118
|
whenTyping: true,
|
|
119
119
|
whenTypingDelay: 300,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type IGenAIContextObject } from "../../types.js";
|
|
1
|
+
import { type IGenAIContextObject, type SelectedContext } from "../../types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Turns each change of the assistant context into one spoken sentence: what was added, what was
|
|
4
4
|
* removed, that the whole context was swapped (the user navigated to another dashboard), or that
|
|
5
5
|
* nothing is left.
|
|
6
6
|
* @internal
|
|
7
7
|
*/
|
|
8
|
-
export declare function useContextChangeAnnouncement(references: IGenAIContextObject[]): string;
|
|
8
|
+
export declare function useContextChangeAnnouncement(selected: SelectedContext | undefined, references: IGenAIContextObject[]): string;
|
|
9
9
|
//# sourceMappingURL=useContextChangeAnnouncement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContextChangeAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextChangeAnnouncement.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useContextChangeAnnouncement.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextChangeAnnouncement.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAmBhF;;;;;GAKG;AACH,wBAAgB,4BAA4B,CACxC,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,UAAU,EAAE,mBAAmB,EAAE,GAClC,MAAM,CA6BR"}
|
|
@@ -22,24 +22,29 @@ const ANNOUNCEMENT_DELAY = 250;
|
|
|
22
22
|
* nothing is left.
|
|
23
23
|
* @internal
|
|
24
24
|
*/
|
|
25
|
-
export function useContextChangeAnnouncement(references) {
|
|
25
|
+
export function useContextChangeAnnouncement(selected, references) {
|
|
26
26
|
const intl = useIntl();
|
|
27
27
|
const [announcement, setAnnouncement] = useState("");
|
|
28
28
|
const previousReferences = useRef(null);
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
const previous = previousReferences.current;
|
|
31
|
-
|
|
31
|
+
const all = [
|
|
32
|
+
...(selected?.activated && selected.dashboard ? [selected.dashboard] : []),
|
|
33
|
+
...(selected?.activated && selected.visualization ? [selected.visualization] : []),
|
|
34
|
+
...references,
|
|
35
|
+
];
|
|
36
|
+
previousReferences.current = all;
|
|
32
37
|
if (previous === null) {
|
|
33
38
|
return undefined;
|
|
34
39
|
}
|
|
35
|
-
const message = getAnnouncement(previous,
|
|
40
|
+
const message = getAnnouncement(previous, all, intl);
|
|
36
41
|
if (!message) {
|
|
37
42
|
return undefined;
|
|
38
43
|
}
|
|
39
44
|
setAnnouncement("");
|
|
40
45
|
const timeout = setTimeout(() => setAnnouncement(message), ANNOUNCEMENT_DELAY);
|
|
41
46
|
return () => clearTimeout(timeout);
|
|
42
|
-
}, [references, intl]);
|
|
47
|
+
}, [references, intl, selected]);
|
|
43
48
|
return announcement;
|
|
44
49
|
}
|
|
45
50
|
function getAnnouncement(previous, current, intl) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type IGenAIUserContext } from "@gooddata/sdk-model";
|
|
2
|
-
import { type IGenAIContextObject } from "../../types.js";
|
|
3
|
-
export declare function
|
|
1
|
+
import { type IGenAIUserContext, type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { type IGenAIContextObject, type SelectedContext } from "../../types.js";
|
|
3
|
+
export declare function useUserContextItems(ambientContext: IGenAIUserContext | undefined, selectedContext: SelectedContext | undefined, activeContext: IGenAIUserContext | undefined): {
|
|
4
4
|
items: IGenAIContextObject[];
|
|
5
5
|
search: string;
|
|
6
6
|
setSearch: (value: string) => void;
|
|
@@ -8,4 +8,10 @@ export declare function useContextItems(ambient: IGenAIUserContext | undefined,
|
|
|
8
8
|
hasNextPage: boolean;
|
|
9
9
|
loadNextPage: () => void;
|
|
10
10
|
};
|
|
11
|
+
export declare function useAmbientContextItems(ambientContext: IGenAIUserContext | undefined): {
|
|
12
|
+
items: IGenAIContextObject[];
|
|
13
|
+
search: string;
|
|
14
|
+
setSearch: (value: string) => void;
|
|
15
|
+
selectedIds: ObjRef[];
|
|
16
|
+
};
|
|
11
17
|
//# sourceMappingURL=useContextItems.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContextItems.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextItems.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"useContextItems.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useContextItems.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,MAAM,EAAmB,MAAM,qBAAqB,CAAC;AAe3F,OAAO,EAIH,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACvB,MAAM,gBAAgB,CAAC;AAExB,wBAAgB,mBAAmB,CAC/B,cAAc,EAAE,iBAAiB,GAAG,SAAS,EAC7C,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,aAAa,EAAE,iBAAiB,GAAG,SAAS;;;;;;;EA8E/C;AAED,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,iBAAiB,GAAG,SAAS;;;;;EA0CnF"}
|
|
@@ -4,9 +4,9 @@ import { useIntl } from "react-intl";
|
|
|
4
4
|
import { useDispatch, useSelector } from "react-redux";
|
|
5
5
|
import { serializeObjRef } from "@gooddata/sdk-model";
|
|
6
6
|
import { collectAvailableReferences, collectContextReferences, } from "../../context/collectContextReferences.js";
|
|
7
|
-
import { contextObjectsSearchSelector, contextObjectsSelector, } from "../../store/chatWindow/chatWindowSelectors.js";
|
|
7
|
+
import { contextObjectsSearchSelector, contextObjectsSelector, selectedContextSelector, } from "../../store/chatWindow/chatWindowSelectors.js";
|
|
8
8
|
import { loadContextObjectsNextPageAction, setContextObjectsSearchAction, } from "../../store/chatWindow/chatWindowSlice.js";
|
|
9
|
-
export function
|
|
9
|
+
export function useUserContextItems(ambientContext, selectedContext, activeContext) {
|
|
10
10
|
const intl = useIntl();
|
|
11
11
|
const dispatch = useDispatch();
|
|
12
12
|
const emptyReferenceLabel = intl.formatMessage({ id: "gd.gen-ai.context.untitled" });
|
|
@@ -16,10 +16,9 @@ export function useContextItems(ambient, active) {
|
|
|
16
16
|
const visualizations = contextObjects.visualization;
|
|
17
17
|
const items = useMemo(() => {
|
|
18
18
|
const matchesSearch = titleMatcher(search);
|
|
19
|
-
const
|
|
20
|
-
const selectedReferences = collectContextReferences(active, emptyReferenceLabel);
|
|
19
|
+
const selectedReferences = collectContextReferences(activeContext, selectedContext, emptyReferenceLabel);
|
|
21
20
|
const offered = new Set();
|
|
22
|
-
collectAvailableReferences(
|
|
21
|
+
collectAvailableReferences(ambientContext, emptyReferenceLabel).forEach((reference) => {
|
|
23
22
|
offered.add(serializeObjRef(reference.ref));
|
|
24
23
|
if (reference.insightRef) {
|
|
25
24
|
offered.add(serializeObjRef(reference.insightRef));
|
|
@@ -29,8 +28,16 @@ export function useContextItems(ambient, active) {
|
|
|
29
28
|
...searchable(dashboards, "dashboard", emptyReferenceLabel, matchesSearch),
|
|
30
29
|
...searchable(visualizations, "visualization", emptyReferenceLabel, matchesSearch),
|
|
31
30
|
].filter((reference) => !offered.has(serializeObjRef(reference.ref)));
|
|
32
|
-
return
|
|
33
|
-
}, [
|
|
31
|
+
return workspaceReferences.filter((reference) => !selectedReferences.some((selectedReference) => isSameObject(selectedReference, reference)));
|
|
32
|
+
}, [
|
|
33
|
+
search,
|
|
34
|
+
ambientContext,
|
|
35
|
+
emptyReferenceLabel,
|
|
36
|
+
activeContext,
|
|
37
|
+
selectedContext,
|
|
38
|
+
dashboards,
|
|
39
|
+
visualizations,
|
|
40
|
+
]);
|
|
34
41
|
const setSearch = useCallback((value) => {
|
|
35
42
|
if (value === search) {
|
|
36
43
|
return;
|
|
@@ -57,8 +64,44 @@ export function useContextItems(ambient, active) {
|
|
|
57
64
|
loadNextPage,
|
|
58
65
|
};
|
|
59
66
|
}
|
|
67
|
+
export function useAmbientContextItems(ambientContext) {
|
|
68
|
+
const intl = useIntl();
|
|
69
|
+
const dispatch = useDispatch();
|
|
70
|
+
const emptyReferenceLabel = intl.formatMessage({ id: "gd.gen-ai.context.untitled" });
|
|
71
|
+
const thisDashboardLabel = intl.formatMessage({ id: "gd.gen-ai.context.this" });
|
|
72
|
+
const search = useSelector(contextObjectsSearchSelector);
|
|
73
|
+
const selected = useSelector(selectedContextSelector);
|
|
74
|
+
const items = useMemo(() => {
|
|
75
|
+
const matchesSearch = titleMatcher(search);
|
|
76
|
+
return collectAvailableReferences(ambientContext, emptyReferenceLabel)
|
|
77
|
+
.map((item) => {
|
|
78
|
+
if (item.type === "dashboard") {
|
|
79
|
+
return {
|
|
80
|
+
...item,
|
|
81
|
+
title: thisDashboardLabel,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return item;
|
|
85
|
+
})
|
|
86
|
+
.filter(matchesSearch);
|
|
87
|
+
}, [search, ambientContext, emptyReferenceLabel, thisDashboardLabel]);
|
|
88
|
+
const setSearch = useCallback((value) => {
|
|
89
|
+
if (value === search) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
dispatch(setContextObjectsSearchAction({ search: value }));
|
|
93
|
+
}, [dispatch, search]);
|
|
94
|
+
return {
|
|
95
|
+
items,
|
|
96
|
+
search,
|
|
97
|
+
setSearch,
|
|
98
|
+
selectedIds: [
|
|
99
|
+
selected?.visualization?.ref ? selected?.visualization?.ref : selected?.dashboard?.ref,
|
|
100
|
+
].filter(Boolean),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
60
103
|
function titleMatcher(search) {
|
|
61
|
-
const normalized = search.trim().toLowerCase();
|
|
104
|
+
const normalized = (search || "").trim().toLowerCase();
|
|
62
105
|
return normalized ? (reference) => reference.title.toLowerCase().includes(normalized) : () => true;
|
|
63
106
|
}
|
|
64
107
|
function searchable(list, type, emptyReferenceLabel, matchesSearch) {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { type IGenAIUserContext } from "@gooddata/sdk-model";
|
|
2
1
|
import { type IGenAIContextObject, type StoreContext } from "../types.js";
|
|
3
2
|
export declare function addContextReference(context: StoreContext, reference?: IGenAIContextObject): StoreContext;
|
|
4
|
-
export declare function addAmbientContextReferences(context: StoreContext, userContext?: IGenAIUserContext): StoreContext;
|
|
5
3
|
//# sourceMappingURL=addContextReference.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addContextReference.d.ts","sourceRoot":"","sources":["../../src/context/addContextReference.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"addContextReference.d.ts","sourceRoot":"","sources":["../../src/context/addContextReference.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,mBAAmB,GAAG,YAAY,CA6DxG"}
|
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
-
import { areObjRefsEqual
|
|
2
|
+
import { areObjRefsEqual } from "@gooddata/sdk-model";
|
|
3
3
|
import { convertGenAiTypeToReferenceType } from "../utils.js";
|
|
4
|
-
import { mergeContexts } from "./build.js";
|
|
5
|
-
import { isReferenceChanged } from "./isReferenceChanged.js";
|
|
6
|
-
import { removeAmbientContribution, removeReferencesCoveredByAmbient } from "./removeContextReference.js";
|
|
7
4
|
export function addContextReference(context, reference) {
|
|
8
|
-
const {
|
|
5
|
+
const { active } = context;
|
|
9
6
|
if (!reference) {
|
|
10
7
|
return context;
|
|
11
8
|
}
|
|
12
|
-
if (reference.where === "view.dashboard"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
...
|
|
17
|
-
|
|
18
|
-
...active,
|
|
19
|
-
|
|
20
|
-
dashboard: ambientDashboard,
|
|
21
|
-
},
|
|
9
|
+
if (reference.where === "view.dashboard") {
|
|
10
|
+
return {
|
|
11
|
+
...context,
|
|
12
|
+
active: {
|
|
13
|
+
...active,
|
|
14
|
+
view: {
|
|
15
|
+
...active?.view,
|
|
16
|
+
dashboard: context.ambient?.view?.dashboard,
|
|
22
17
|
},
|
|
23
|
-
}
|
|
24
|
-
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
25
20
|
}
|
|
26
21
|
if (reference.where === "referencedObjects") {
|
|
27
22
|
const refContext = reference.context;
|
|
@@ -59,21 +54,3 @@ export function addContextReference(context, reference) {
|
|
|
59
54
|
}
|
|
60
55
|
return context;
|
|
61
56
|
}
|
|
62
|
-
function pruneForNewAmbient(active, previousAmbient, newAmbient) {
|
|
63
|
-
return removeReferencesCoveredByAmbient(removeAmbientContribution(active, previousAmbient), newAmbient);
|
|
64
|
-
}
|
|
65
|
-
export function addAmbientContextReferences(context, userContext) {
|
|
66
|
-
const referenceChanged = isReferenceChanged(context.ambient, userContext);
|
|
67
|
-
const updateActive = Boolean(!context.ambient || context.active?.view?.dashboard || referenceChanged);
|
|
68
|
-
return {
|
|
69
|
-
...context,
|
|
70
|
-
ambient: userContext,
|
|
71
|
-
...(updateActive
|
|
72
|
-
? {
|
|
73
|
-
active: mergeContexts(referenceChanged
|
|
74
|
-
? pruneForNewAmbient(context.active, context.ambient, userContext)
|
|
75
|
-
: context.active, userContext),
|
|
76
|
-
}
|
|
77
|
-
: {}),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IGenAIUserContext } from "@gooddata/sdk-model";
|
|
2
|
-
import { type IGenAIContextObject } from "../types.js";
|
|
3
|
-
export declare function collectContextReferences(
|
|
2
|
+
import { type IGenAIContextObject, type SelectedContext } from "../types.js";
|
|
3
|
+
export declare function collectContextReferences(userContext: IGenAIUserContext | undefined, selectedContext: SelectedContext | undefined, placeholderTitle?: string): IGenAIContextObject[];
|
|
4
4
|
export declare function collectAvailableReferences(context: IGenAIUserContext | undefined, placeholderTitle?: string): IGenAIContextObject[];
|
|
5
5
|
//# sourceMappingURL=collectContextReferences.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EAIzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAG7E,wBAAgB,wBAAwB,CACpC,WAAW,EAAE,iBAAiB,GAAG,SAAS,EAC1C,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CA0CvB;AAED,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAuFvB"}
|
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
-
import { isIdentifierRef, serializeObjRef, } from "@gooddata/sdk-model";
|
|
2
|
+
import { areObjRefsEqual, isIdentifierRef, serializeObjRef, } from "@gooddata/sdk-model";
|
|
3
3
|
import { convertReferenceTypeToGenAiType } from "../utils.js";
|
|
4
|
-
export function collectContextReferences(
|
|
5
|
-
|
|
6
|
-
return [];
|
|
7
|
-
}
|
|
8
|
-
const references = [];
|
|
4
|
+
export function collectContextReferences(userContext, selectedContext, placeholderTitle) {
|
|
5
|
+
const userReferences = [];
|
|
9
6
|
// dashboard
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
12
|
-
const ref =
|
|
7
|
+
const userDashboard = userContext?.view?.dashboard;
|
|
8
|
+
if (userDashboard) {
|
|
9
|
+
const ref = userDashboard.ref;
|
|
13
10
|
const id = isIdentifierRef(ref) ? ref.identifier : ref.uri;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
if (!areObjRefsEqual(ref, selectedContext?.dashboard?.ref)) {
|
|
12
|
+
userReferences.push({
|
|
13
|
+
id,
|
|
14
|
+
ref,
|
|
15
|
+
nesting: 0,
|
|
16
|
+
type: "dashboard",
|
|
17
|
+
where: "view.dashboard",
|
|
18
|
+
title: userDashboard.title || placeholderTitle || id,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
22
21
|
}
|
|
23
22
|
// references
|
|
24
|
-
|
|
23
|
+
userContext?.referencedObjects?.forEach((obj) => {
|
|
24
|
+
if (areObjRefsEqual(obj.context?.ref, selectedContext?.dashboard?.ref)) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
25
27
|
obj.objects.forEach((item) => {
|
|
26
28
|
const ref = item.ref;
|
|
27
29
|
const id = isIdentifierRef(ref) ? ref.identifier : ref.uri;
|
|
28
|
-
|
|
30
|
+
userReferences.push({
|
|
29
31
|
id,
|
|
30
32
|
ref,
|
|
31
33
|
nesting: 1,
|
|
@@ -35,7 +37,7 @@ export function collectContextReferences(context, placeholderTitle) {
|
|
|
35
37
|
});
|
|
36
38
|
});
|
|
37
39
|
});
|
|
38
|
-
return
|
|
40
|
+
return userReferences.sort((a, b) => a.nesting - b.nesting);
|
|
39
41
|
}
|
|
40
42
|
export function collectAvailableReferences(context, placeholderTitle) {
|
|
41
43
|
if (!context) {
|