@gooddata/sdk-ui-gen-ai 11.35.0-alpha.5 → 11.35.0-alpha.7
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 +8 -8
- package/esm/components/GenAIChatConversations.d.ts +2 -1
- package/esm/components/GenAIChatConversations.js +191 -42
- package/esm/components/GenAIChatWrapper.js +19 -6
- package/esm/components/Input.js +8 -3
- package/esm/components/messages/conversationContents/ConversationVisualizationContent.js +32 -46
- package/esm/components/utils/conversationGrouper.d.ts +1 -0
- package/esm/components/utils/conversationGrouper.js +7 -0
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/localization/bundles/de-DE.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/de-DE.localization-bundle.js +6 -1
- package/esm/localization/bundles/en-AU.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/en-AU.localization-bundle.js +6 -1
- package/esm/localization/bundles/en-GB.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/en-GB.localization-bundle.js +6 -1
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +21 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +23 -3
- package/esm/localization/bundles/es-419.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/es-419.localization-bundle.js +6 -1
- package/esm/localization/bundles/es-ES.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/es-ES.localization-bundle.js +6 -1
- package/esm/localization/bundles/fi-FI.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/fi-FI.localization-bundle.js +6 -1
- package/esm/localization/bundles/fr-CA.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/fr-CA.localization-bundle.js +6 -1
- package/esm/localization/bundles/fr-FR.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/fr-FR.localization-bundle.js +6 -1
- package/esm/localization/bundles/id-ID.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/id-ID.localization-bundle.js +6 -1
- package/esm/localization/bundles/it-IT.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/it-IT.localization-bundle.js +6 -1
- package/esm/localization/bundles/ja-JP.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/ja-JP.localization-bundle.js +6 -1
- package/esm/localization/bundles/ko-KR.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/ko-KR.localization-bundle.js +6 -1
- package/esm/localization/bundles/nl-NL.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/nl-NL.localization-bundle.js +6 -1
- package/esm/localization/bundles/pl-PL.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/pl-PL.localization-bundle.js +6 -1
- package/esm/localization/bundles/pt-BR.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/pt-BR.localization-bundle.js +6 -1
- package/esm/localization/bundles/pt-PT.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/pt-PT.localization-bundle.js +6 -1
- package/esm/localization/bundles/ru-RU.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/ru-RU.localization-bundle.js +6 -1
- package/esm/localization/bundles/sl-SI.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/sl-SI.localization-bundle.js +6 -1
- package/esm/localization/bundles/th-TH.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/th-TH.localization-bundle.js +6 -1
- package/esm/localization/bundles/tr-TR.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/tr-TR.localization-bundle.js +6 -1
- package/esm/localization/bundles/uk-UA.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/uk-UA.localization-bundle.js +6 -1
- package/esm/localization/bundles/vi-VN.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/vi-VN.localization-bundle.js +6 -1
- package/esm/localization/bundles/zh-HK.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/zh-HK.localization-bundle.js +6 -1
- package/esm/localization/bundles/zh-Hans.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/zh-Hans.localization-bundle.js +6 -1
- package/esm/localization/bundles/zh-Hant.localization-bundle.d.ts +6 -1
- package/esm/localization/bundles/zh-Hant.localization-bundle.js +6 -1
- package/esm/model.d.ts +2 -0
- package/esm/sdk-ui-gen-ai.d.ts +65 -1
- package/esm/store/events.d.ts +57 -1
- package/esm/store/events.js +28 -0
- package/esm/store/messages/messagesSelectors.d.ts +3 -3
- package/esm/store/messages/messagesSelectors.js +26 -4
- package/esm/store/messages/messagesSlice.d.ts +36 -20
- package/esm/store/messages/messagesSlice.js +212 -94
- package/esm/store/sideEffects/index.js +4 -2
- package/esm/store/sideEffects/onConversationDelete.d.ts +3 -1
- package/esm/store/sideEffects/onConversationDelete.js +1 -1
- package/esm/store/sideEffects/onConversationPin.d.ts +19 -0
- package/esm/store/sideEffects/onConversationPin.js +30 -0
- package/esm/store/sideEffects/onEvent.js +44 -1
- package/esm/store/sideEffects/onThreadLoad.js +15 -5
- package/esm/store/sideEffects/onUserFeedback.d.ts +3 -0
- package/esm/store/sideEffects/onUserFeedback.js +2 -1
- package/esm/store/sideEffects/onUserMessage.d.ts +9 -2
- package/esm/store/sideEffects/onUserMessage.js +42 -22
- package/esm/store/sideEffects/onUserMessageUpdate.d.ts +5 -3
- package/esm/store/sideEffects/onUserMessageUpdate.js +5 -2
- package/esm/store/sideEffects/onVisualisationRender.d.ts +2 -0
- package/esm/store/sideEffects/onVisualizationSave.d.ts +4 -0
- package/esm/store/sideEffects/onVisualizationSave.js +2 -0
- package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts +2 -0
- package/esm/store/sideEffects/utils.js +0 -3
- package/esm/store/utils.d.ts +6 -0
- package/esm/store/utils.js +30 -0
- package/esm/types.d.ts +26 -0
- package/esm/utils.d.ts +4 -0
- package/esm/utils.js +23 -0
- package/package.json +21 -21
- package/styles/css/conversations.css +82 -8
- package/styles/css/conversations.css.map +1 -1
- package/styles/css/main.css +85 -8
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +3 -0
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/conversations.scss +98 -11
- package/styles/scss/messages.scss +4 -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-5-
|
|
10
|
+
Date generated: 2026-5-12
|
|
11
11
|
|
|
12
|
-
Revision ID:
|
|
12
|
+
Revision ID: 52d6a5f81cbc391c8c918fe465fad2be3e3de86f
|
|
13
13
|
|
|
14
14
|
================================================================================
|
|
15
15
|
================================================================================
|
|
@@ -376,7 +376,7 @@ Revision ID: 0c39c460e837a54efedde9d37131feb930e4b8a1
|
|
|
376
376
|
- bail (2.0.2) [MIT]
|
|
377
377
|
- balanced-match (2.0.0) [MIT]
|
|
378
378
|
- base64-js (1.5.1) [MIT]
|
|
379
|
-
- baseline-browser-mapping (2.10.
|
|
379
|
+
- baseline-browser-mapping (2.10.29) [Apache-2.0]
|
|
380
380
|
- batch (0.6.1) [MIT]
|
|
381
381
|
- binary-extensions (2.3.0) [MIT]
|
|
382
382
|
- bl (4.1.0) [MIT]
|
|
@@ -710,7 +710,7 @@ Revision ID: 0c39c460e837a54efedde9d37131feb930e4b8a1
|
|
|
710
710
|
- magic-string (0.30.21) [MIT]
|
|
711
711
|
- make-dir (2.1.0) [MIT]
|
|
712
712
|
- mapbox-gl (2.15.0) [BSD-3-Clause, MIT]
|
|
713
|
-
- maplibre-gl (4.7.1) [MIT, BSD-3-Clause,
|
|
713
|
+
- maplibre-gl (4.7.1) [MIT, BSD-3-Clause, 0BSD, ISC]
|
|
714
714
|
- markdown-table (3.0.4) [MIT]
|
|
715
715
|
- matchmediaquery (0.4.2) [MIT]
|
|
716
716
|
- math-intrinsics (1.1.0) [MIT]
|
|
@@ -5367,9 +5367,9 @@ MIT
|
|
|
5367
5367
|
|
|
5368
5368
|
|
|
5369
5369
|
--------------------------------------------------------------------------------
|
|
5370
|
-
Package Title: baseline-browser-mapping (2.10.
|
|
5370
|
+
Package Title: baseline-browser-mapping (2.10.29)
|
|
5371
5371
|
|
|
5372
|
-
Package Locator: npm+baseline-browser-mapping$2.10.
|
|
5372
|
+
Package Locator: npm+baseline-browser-mapping$2.10.29
|
|
5373
5373
|
|
|
5374
5374
|
Package Depth: Transitive
|
|
5375
5375
|
--------------------------------------------------------------------------------
|
|
@@ -9407,7 +9407,7 @@ MIT, BSD-3-Clause
|
|
|
9407
9407
|
|
|
9408
9408
|
|
|
9409
9409
|
* Other Licenses *
|
|
9410
|
-
|
|
9410
|
+
0BSD, ISC
|
|
9411
9411
|
|
|
9412
9412
|
|
|
9413
9413
|
--------------------------------------------------------------------------------
|
|
@@ -38277,4 +38277,4 @@ POSSIBILITY OF SUCH DAMAGE.
|
|
|
38277
38277
|
--------------------------------------------------------------------------------
|
|
38278
38278
|
--------------------------------------------------------------------------------
|
|
38279
38279
|
|
|
38280
|
-
Report Generated by FOSSA on 2026-5-
|
|
38280
|
+
Report Generated by FOSSA on 2026-5-12
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type FC } from "react";
|
|
2
2
|
import { setHistoryAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
3
3
|
import { conversationSelector, conversationsSelector } from "../store/messages/messagesSelectors.js";
|
|
4
|
-
import { deleteConversationAction, setCurrentConversationAction } from "../store/messages/messagesSlice.js";
|
|
4
|
+
import { deleteConversationAction, pinConversationAction, setCurrentConversationAction } from "../store/messages/messagesSlice.js";
|
|
5
5
|
type GenAIChatConversationsStateProps = {
|
|
6
6
|
conversation: ReturnType<typeof conversationSelector>;
|
|
7
7
|
conversations: ReturnType<typeof conversationsSelector>;
|
|
@@ -10,6 +10,7 @@ type GenAIChatConversationsDispatchProps = {
|
|
|
10
10
|
setHistory: typeof setHistoryAction;
|
|
11
11
|
loadConversation: typeof setCurrentConversationAction;
|
|
12
12
|
deleteConversation: typeof deleteConversationAction;
|
|
13
|
+
pinConversation: typeof pinConversationAction;
|
|
13
14
|
};
|
|
14
15
|
export type GenAIChatConversationsProps = GenAIChatConversationsStateProps & GenAIChatConversationsDispatchProps;
|
|
15
16
|
export declare const GenAIChatConversations: FC;
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2026 GoodData Corporation
|
|
3
|
-
import { useCallback, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useCallback, useMemo, useRef, useState, } from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
6
6
|
import { connect, useSelector } from "react-redux";
|
|
7
|
-
import { DefaultUiMenuInteractiveItemWrapper, UiDrawer, UiIcon, UiIconButton, UiMenu, } from "@gooddata/sdk-ui-kit";
|
|
7
|
+
import { DefaultUiMenuInteractiveItemWrapper, Dropdown, UiDrawer, UiIcon, UiIconButton, UiMenu, } from "@gooddata/sdk-ui-kit";
|
|
8
8
|
import { catalogItemsSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
9
9
|
import { setHistoryAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
10
10
|
import { conversationSelector, conversationsSelector } from "../store/messages/messagesSelectors.js";
|
|
11
|
-
import { deleteConversationAction, setCurrentConversationAction } from "../store/messages/messagesSlice.js";
|
|
11
|
+
import { deleteConversationAction, pinConversationAction, setCurrentConversationAction, } from "../store/messages/messagesSlice.js";
|
|
12
|
+
import { isConversationWithLocalId } from "../store/utils.js";
|
|
12
13
|
import { generateTemporaryTitle } from "../utils.js";
|
|
13
14
|
import { collectReferences, replaceReferences } from "./completion/references.js";
|
|
14
15
|
import { ConversationDeleteDialog } from "./ConversationDeleteDialog.js";
|
|
15
16
|
import { useFullscreenCheck } from "./hooks/useFullscreenCheck.js";
|
|
16
17
|
import { useHistoryCheck } from "./hooks/useHistoryCheck.js";
|
|
17
18
|
import { ConversationDateGroup, groupConversationsByDate } from "./utils/conversationGrouper.js";
|
|
18
|
-
function GenAIChatConversationsComponent({ setHistory, deleteConversation, loadConversation, conversations, conversation: currentConversation, }) {
|
|
19
|
+
function GenAIChatConversationsComponent({ setHistory, deleteConversation, pinConversation, loadConversation, conversations, conversation: currentConversation, }) {
|
|
19
20
|
const ref = useRef(undefined);
|
|
20
21
|
const intl = useIntl();
|
|
21
22
|
const { isFullscreen, isSmallScreen } = useFullscreenCheck();
|
|
22
23
|
const { isHistory } = useHistoryCheck();
|
|
23
24
|
const [conversationToDelete, setConversationToDelete] = useState();
|
|
25
|
+
const [openedId, setOpenedId] = useState();
|
|
26
|
+
const [draggedConversationId, setDraggedConversationId] = useState();
|
|
27
|
+
const [activeDropZone, setActiveDropZone] = useState();
|
|
24
28
|
const catalogItems = useSelector(catalogItemsSelector);
|
|
25
29
|
const groupedConversations = useMemo(() => groupConversationsByDate(conversations), [conversations]);
|
|
26
30
|
const menuItems = useMemo(() => groupedConversations.map((group) => ({
|
|
@@ -30,19 +34,74 @@ function GenAIChatConversationsComponent({ setHistory, deleteConversation, loadC
|
|
|
30
34
|
data: group.group,
|
|
31
35
|
subItems: group.conversations.map((conversation) => ({
|
|
32
36
|
type: "interactive",
|
|
33
|
-
id: conversation.
|
|
37
|
+
id: conversation.localId,
|
|
34
38
|
stringTitle: replaceReferences(conversation.title ?? "", collectReferences(conversation.title ?? "", catalogItems)),
|
|
35
39
|
data: conversation,
|
|
36
|
-
iconRight: (_jsx("div", { className: "gd-gen-ai-chat__window__conversations__list__delete-button", children: _jsx(
|
|
37
|
-
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
iconRight: (_jsx("div", { className: "gd-gen-ai-chat__window__conversations__list__delete-button", children: _jsx(Dropdown, { onToggle: () => {
|
|
41
|
+
setOpenedId(openedId ? undefined : conversation.localId);
|
|
42
|
+
}, isOpen: openedId === conversation.localId, alignPoints: [{ align: "bl tl" }], renderButton: ({ toggleDropdown, buttonRef, ariaAttributes, accessibilityConfig, }) => (_jsx(UiIconButton, { ref: (element) => {
|
|
43
|
+
buttonRef.current = element;
|
|
44
|
+
}, size: "medium", variant: "tertiary", label: intl.formatMessage({
|
|
45
|
+
id: "gd.gen-ai.conversations.menu.aria-label",
|
|
46
|
+
}), onClick: (event) => {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
event.stopPropagation();
|
|
49
|
+
toggleDropdown();
|
|
50
|
+
}, accessibilityConfig: {
|
|
51
|
+
...accessibilityConfig,
|
|
52
|
+
ariaExpanded: ariaAttributes["aria-expanded"],
|
|
53
|
+
ariaHaspopup: ariaAttributes["aria-haspopup"],
|
|
54
|
+
ariaControls: ariaAttributes["aria-controls"],
|
|
55
|
+
}, tabIndex: -1, icon: "ellipsis" })), renderBody: ({ closeDropdown, ariaAttributes }) => (_jsx(UiMenu, { shouldCloseOnSelect: true, items: [
|
|
56
|
+
{
|
|
57
|
+
type: "interactive",
|
|
58
|
+
id: conversation.pinned ? "unpin" : "pin",
|
|
59
|
+
stringTitle: conversation.pinned
|
|
60
|
+
? intl.formatMessage({
|
|
61
|
+
id: "gd.gen-ai.conversations.menu.unpin",
|
|
62
|
+
})
|
|
63
|
+
: intl.formatMessage({
|
|
64
|
+
id: "gd.gen-ai.conversations.menu.pin",
|
|
65
|
+
}),
|
|
66
|
+
iconLeft: conversation.pinned ? (_jsx(UiIcon, { type: "unpin", size: 14 })) : (_jsx(UiIcon, { type: "pin", size: 14 })),
|
|
67
|
+
data: conversation,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: "static",
|
|
71
|
+
id: "delete-separator",
|
|
72
|
+
data: (_jsx("div", { className: "gd-gen-ai-chat__window__conversations__divider_menu" })),
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "interactive",
|
|
76
|
+
id: "delete",
|
|
77
|
+
stringTitle: intl.formatMessage({
|
|
78
|
+
id: "gd.gen-ai.conversations.delete-dialog.submit",
|
|
79
|
+
}),
|
|
80
|
+
isDestructive: true,
|
|
81
|
+
iconLeft: _jsx(UiIcon, { type: "trash", size: 14 }),
|
|
82
|
+
data: {
|
|
83
|
+
...conversation,
|
|
84
|
+
action: "delete",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
], onSelect: (item, event) => {
|
|
88
|
+
const selectedConversation = item.data;
|
|
89
|
+
if (selectedConversation.action === "delete") {
|
|
90
|
+
setConversationToDelete(conversation);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
pinConversation({
|
|
94
|
+
conversationId: selectedConversation.localId,
|
|
95
|
+
pinned: !selectedConversation.pinned,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
event.stopPropagation();
|
|
100
|
+
}, onClose: closeDropdown, ariaAttributes: ariaAttributes })), closeOnEscape: true, autofocusOnOpen: true }) })),
|
|
101
|
+
isSelected: isConversationWithLocalId(currentConversation, conversation.localId),
|
|
44
102
|
})),
|
|
45
|
-
})), [groupedConversations, intl, catalogItems, currentConversation]);
|
|
103
|
+
})), [groupedConversations, intl, catalogItems, openedId, currentConversation, pinConversation]);
|
|
104
|
+
const draggedConversation = useMemo(() => conversations?.find((conversation) => conversation.localId === draggedConversationId), [conversations, draggedConversationId]);
|
|
46
105
|
const handleDeleteCancel = useCallback(() => {
|
|
47
106
|
setConversationToDelete(undefined);
|
|
48
107
|
}, []);
|
|
@@ -52,43 +111,130 @@ function GenAIChatConversationsComponent({ setHistory, deleteConversation, loadC
|
|
|
52
111
|
}, [loadConversation, setHistory]);
|
|
53
112
|
const handleDeleteSubmit = useCallback(() => {
|
|
54
113
|
if (conversationToDelete) {
|
|
55
|
-
deleteConversation({ conversationId: conversationToDelete.
|
|
114
|
+
deleteConversation({ conversationId: conversationToDelete.localId });
|
|
56
115
|
}
|
|
57
116
|
setConversationToDelete(undefined);
|
|
58
117
|
}, [conversationToDelete, deleteConversation]);
|
|
118
|
+
const handleDragStart = useCallback((conversationId, event) => {
|
|
119
|
+
event.dataTransfer.effectAllowed = "move";
|
|
120
|
+
event.dataTransfer.setData("text/plain", conversationId);
|
|
121
|
+
setDraggedConversationId(conversationId);
|
|
122
|
+
setActiveDropZone("body");
|
|
123
|
+
}, []);
|
|
124
|
+
const handleDragEnd = useCallback(() => {
|
|
125
|
+
setDraggedConversationId(undefined);
|
|
126
|
+
setActiveDropZone(undefined);
|
|
127
|
+
}, []);
|
|
128
|
+
const handleDropZoneDragOver = useCallback((dropZone, event) => {
|
|
129
|
+
if (!draggedConversation) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const canDrop = dropZone === "pin" ? !draggedConversation.pinned : draggedConversation.pinned;
|
|
133
|
+
if (!canDrop) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
event.dataTransfer.dropEffect = "move";
|
|
138
|
+
setActiveDropZone(dropZone);
|
|
139
|
+
}, [draggedConversation]);
|
|
140
|
+
const handleDropZoneDragLeave = useCallback((event) => {
|
|
141
|
+
const nextTarget = event.relatedTarget;
|
|
142
|
+
if (nextTarget && event.currentTarget.contains(nextTarget)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
setActiveDropZone("body");
|
|
146
|
+
}, []);
|
|
147
|
+
const handleDropZoneDrop = useCallback((dropZone, event) => {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
if (!draggedConversation) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const shouldBePinned = dropZone === "pin";
|
|
153
|
+
if (draggedConversation.pinned !== shouldBePinned) {
|
|
154
|
+
pinConversation({
|
|
155
|
+
conversationId: draggedConversation.localId,
|
|
156
|
+
pinned: shouldBePinned,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
setDraggedConversationId(undefined);
|
|
160
|
+
setActiveDropZone(undefined);
|
|
161
|
+
}, [draggedConversation, pinConversation]);
|
|
162
|
+
const handleMenuUnhandledKeyDown = useCallback((event, { focusedItem }) => {
|
|
163
|
+
if (event.key === "Delete" && focusedItem) {
|
|
164
|
+
event.preventDefault();
|
|
165
|
+
event.stopPropagation();
|
|
166
|
+
setConversationToDelete(focusedItem.data);
|
|
167
|
+
}
|
|
168
|
+
}, []);
|
|
59
169
|
return (_jsxs(_Fragment, { children: [
|
|
60
170
|
_jsx("div", { className: "gd-gen-ai-chat__window__drawer", ref: ref }), _jsx(UiDrawer, { anchor: "left", showCloseButton: true, open: isHistory, node: ref.current, showBackdrop: false, header: _jsxs("div", { style: { width: "100%" }, children: [
|
|
61
171
|
_jsx("div", { className: "gd-gen-ai-chat__window__conversations__header", children: intl.formatMessage({ id: "gd.gen-ai.conversations.title" }) }), _jsx("div", { className: "gd-gen-ai-chat__window__conversations__divider" })
|
|
62
172
|
] }), closeLabel: intl.formatMessage({ id: "gd.gen-ai.conversations.close-label" }), onClickClose: () => setHistory({ isHistory: false }), onClickOutside: () => setHistory({ isHistory: false }), children: _jsx("div", { className: cx("gd-gen-ai-chat__window__conversations", {
|
|
63
173
|
"gd-gen-ai-chat__window__conversations--isFullscreen": isFullscreen,
|
|
64
174
|
"gd-gen-ai-chat__window__conversations--isSmallScreen": isSmallScreen,
|
|
65
|
-
}), children: (conversations ?? [])
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
}), children: _jsx(DrawerContent, { openedId: openedId, menuItems: menuItems, conversations: conversations ?? [], handleSelect: handleSelect, draggedConversation: draggedConversation, activeDropZone: activeDropZone, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDropZoneDragOver: handleDropZoneDragOver, onDropZoneDragLeave: handleDropZoneDragLeave, onDropZoneDrop: handleDropZoneDrop, onMenuUnhandledKeyDown: handleMenuUnhandledKeyDown }) }) }), conversationToDelete ? (_jsx(ConversationDeleteDialog, { conversation: conversationToDelete, onClose: handleDeleteCancel, onDelete: handleDeleteSubmit })) : null] }));
|
|
176
|
+
}
|
|
177
|
+
function DrawerContent({ openedId, conversations, menuItems, handleSelect, draggedConversation, activeDropZone, onDragStart, onDragEnd, onDropZoneDragOver, onDropZoneDragLeave, onDropZoneDrop, onMenuUnhandledKeyDown, }) {
|
|
178
|
+
const intl = useIntl();
|
|
179
|
+
const pinnedItems = useMemo(() => {
|
|
180
|
+
return menuItems.filter((item) => item.id === ConversationDateGroup.PINNED);
|
|
181
|
+
}, [menuItems]);
|
|
182
|
+
const restItems = useMemo(() => {
|
|
183
|
+
return menuItems.filter((item) => item.id !== ConversationDateGroup.PINNED);
|
|
184
|
+
}, [menuItems]);
|
|
185
|
+
return (_jsx(_Fragment, { children: (conversations ?? []).length === 0 ? (_jsxs("div", { className: "gd-gen-ai-chat__window__conversations__empty", children: [
|
|
186
|
+
_jsx(UiIcon, { type: "history2", size: 20, color: "complementary-6" }), _jsx("div", { className: "gd-gen-ai-chat__window__conversations__empty__text", children: _jsx(FormattedMessage, { id: "gd.gen-ai.conversations.empty", values: {
|
|
187
|
+
br: _jsx("br", {}),
|
|
188
|
+
} }) })
|
|
189
|
+
] })) : (_jsxs("div", { className: "gd-gen-ai-chat__window__conversations__list", children: [
|
|
190
|
+
_jsxs("div", { className: "gd-gen-ai-chat__window__conversations__drop-group", onDragLeave: onDropZoneDragLeave, onDragOver: (event) => onDropZoneDragOver("pin", event), onDrop: (event) => onDropZoneDrop("pin", event), children: [
|
|
191
|
+
_jsx("div", { className: cx("gd-gen-ai-chat__window__conversations__drop-placeholder", {
|
|
192
|
+
isDragging: activeDropZone === "body" && !draggedConversation?.pinned,
|
|
193
|
+
isDraggingOver: activeDropZone === "pin",
|
|
194
|
+
isEmpty: pinnedItems.length === 0,
|
|
195
|
+
}), children: _jsx("div", { className: "gd-gen-ai-chat__window__conversations__drop-placeholder__content", children: intl.formatMessage({
|
|
196
|
+
id: "gd.gen-ai.conversations.dnd.pin-placeholder",
|
|
197
|
+
}) }) }), _jsx(ConversationsList, { id: "gd-gen-ai-conversations-pinned", openedId: openedId, listItems: pinnedItems, onDragStart: onDragStart, onDragEnd: onDragEnd, onMenuUnhandledKeyDown: onMenuUnhandledKeyDown, handleSelect: handleSelect })
|
|
198
|
+
] }), _jsxs("div", { className: "gd-gen-ai-chat__window__conversations__drop-group", onDragOver: (event) => onDropZoneDragOver("unpin", event), onDragLeave: onDropZoneDragLeave, onDrop: (event) => onDropZoneDrop("unpin", event), children: [
|
|
199
|
+
_jsx("div", { className: cx("gd-gen-ai-chat__window__conversations__drop-placeholder", {
|
|
200
|
+
isDragging: activeDropZone === "body" && draggedConversation?.pinned,
|
|
201
|
+
isDraggingOver: activeDropZone === "unpin",
|
|
202
|
+
}), children: _jsx("div", { className: "gd-gen-ai-chat__window__conversations__drop-placeholder__content", children: intl.formatMessage({
|
|
203
|
+
id: "gd.gen-ai.conversations.dnd.unpin-placeholder",
|
|
204
|
+
}) }) }), _jsx(ConversationsList, { id: "gd-gen-ai-conversations-rest", openedId: openedId, listItems: restItems, onDragStart: onDragStart, onDragEnd: onDragEnd, onMenuUnhandledKeyDown: onMenuUnhandledKeyDown, handleSelect: handleSelect })
|
|
205
|
+
] }), draggedConversation ? (_jsx("div", { className: cx("gd-gen-ai-chat__window__conversations__drop-overlay", {
|
|
206
|
+
isDragging: !!activeDropZone,
|
|
207
|
+
}) })) : null] })) }));
|
|
208
|
+
}
|
|
209
|
+
function ConversationsList({ id, openedId, listItems, handleSelect, onDragStart, onDragEnd, onMenuUnhandledKeyDown, }) {
|
|
210
|
+
const intl = useIntl();
|
|
211
|
+
return useMemo(() => {
|
|
212
|
+
return (_jsx(UiMenu, { onUnhandledKeyDown: onMenuUnhandledKeyDown, InteractiveItemWrapper: (props) => (_jsx(DraggableConversationItem, { ...props, intl: intl, openedId: openedId, onDragStart: onDragStart, onDragEnd: onDragEnd })), items: listItems, onSelect: (item, event) => {
|
|
213
|
+
handleSelect(item.data);
|
|
214
|
+
event.stopPropagation();
|
|
215
|
+
event.preventDefault();
|
|
216
|
+
}, shouldCloseOnSelect: false, size: "small", ariaAttributes: {
|
|
217
|
+
id,
|
|
218
|
+
"aria-label": intl.formatMessage({ id: "gd.gen-ai.conversations.title" }),
|
|
219
|
+
} }));
|
|
220
|
+
}, [id, handleSelect, intl, listItems, onDragEnd, onDragStart, onMenuUnhandledKeyDown, openedId]);
|
|
221
|
+
}
|
|
222
|
+
function DraggableConversationItem(props) {
|
|
223
|
+
const data = props.item.data;
|
|
224
|
+
return (_jsx("div", { draggable: true, className: cx("gd-gen-ai-chat__window__conversations__list__item", {
|
|
225
|
+
generatingTitle: data.generatingTitle,
|
|
226
|
+
inProgress: data.inProgress,
|
|
227
|
+
openedMenu: props.openedId === props.item.id,
|
|
228
|
+
}), onDragStart: (event) => {
|
|
229
|
+
event.currentTarget.classList.add("dragging");
|
|
230
|
+
props.onDragStart(data.localId, event);
|
|
231
|
+
}, onDragEnd: (event) => {
|
|
232
|
+
event.currentTarget.classList.remove("dragging");
|
|
233
|
+
props.onDragEnd();
|
|
234
|
+
}, children: _jsx(DefaultUiMenuInteractiveItemWrapper, { ...props, item: {
|
|
235
|
+
...props.item,
|
|
236
|
+
stringTitle: props.item.stringTitle || generateTemporaryTitle(props.intl, data),
|
|
237
|
+
} }) }));
|
|
92
238
|
}
|
|
93
239
|
const mapStateToProps = (state) => ({
|
|
94
240
|
conversation: conversationSelector(state),
|
|
@@ -97,11 +243,14 @@ const mapStateToProps = (state) => ({
|
|
|
97
243
|
const mapDispatchToProps = {
|
|
98
244
|
setHistory: setHistoryAction,
|
|
99
245
|
deleteConversation: deleteConversationAction,
|
|
246
|
+
pinConversation: pinConversationAction,
|
|
100
247
|
loadConversation: setCurrentConversationAction,
|
|
101
248
|
};
|
|
102
249
|
export const GenAIChatConversations = connect(mapStateToProps, mapDispatchToProps)(GenAIChatConversationsComponent);
|
|
103
250
|
function getConversationGroupLabel(group, intl) {
|
|
104
251
|
switch (group) {
|
|
252
|
+
case ConversationDateGroup.PINNED:
|
|
253
|
+
return intl.formatMessage({ id: "gd.gen-ai.conversations.group.pinned" });
|
|
105
254
|
case ConversationDateGroup.TODAY:
|
|
106
255
|
return intl.formatMessage({ id: "gd.gen-ai.conversations.group.today" });
|
|
107
256
|
case ConversationDateGroup.LAST_7_DAYS:
|
|
@@ -11,7 +11,7 @@ import { settingsSelector } from "../store/chatWindow/chatWindowSelectors.js";
|
|
|
11
11
|
import { setAllowedRelationshipTypesAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
12
12
|
import { asyncProcessSelector } from "../store/messages/messagesSelectors.js";
|
|
13
13
|
import { cancelAsyncAction, clearThreadAction, loadThreadAction } from "../store/messages/messagesSlice.js";
|
|
14
|
-
import { getAbsoluteSettingHref, getAbsoluteWorkspaceSettingHref, getSettingHref, getWorkspaceSettingHref, } from "../utils.js";
|
|
14
|
+
import { getAbsoluteSettingHref, getAbsoluteShellAppOrgSettingHref, getAbsoluteShellAppWorkspaceSettingHref, getAbsoluteWorkspaceSettingHref, getSettingHref, getShellAppOrgSettingHref, getShellAppWorkspaceSettingHref, getWorkspaceSettingHref, } from "../utils.js";
|
|
15
15
|
import { useConfig } from "./ConfigContext.js";
|
|
16
16
|
import { useCustomization } from "./CustomizationProvider.js";
|
|
17
17
|
import { ErrorBoundary } from "./ErrorBoundary.js";
|
|
@@ -49,11 +49,18 @@ export function GenAIChatWrapperComponent({ loadThread, clearThread, cancelLoadi
|
|
|
49
49
|
navigationId: GEN_AI_INPUT_ANCHOR_ID,
|
|
50
50
|
tabIndex: -1,
|
|
51
51
|
});
|
|
52
|
+
// When the shell host is enabled, the standalone home-ui at `/settings` or
|
|
53
|
+
// `/workspaces/{id}/settings` is bounced to the host base path, dropping the
|
|
54
|
+
// workspaceId and hash. Switch to host-shaped URLs so the deep-link
|
|
55
|
+
// (e.g. `#/ai/change-llm-model`) reaches the settings page intact.
|
|
56
|
+
const useShellAppUrls = Boolean(settings?.enableShellApplication);
|
|
52
57
|
const onSettingClick = useCallback((type) => (e) => {
|
|
53
58
|
switch (type) {
|
|
54
59
|
case "change-model":
|
|
55
60
|
if (allowNativeLinks) {
|
|
56
|
-
window.location.href =
|
|
61
|
+
window.location.href = useShellAppUrls
|
|
62
|
+
? getAbsoluteShellAppWorkspaceSettingHref(workspaceId, GEN_AI_SECTION, CHANGE_LLM_MODEL_ACTION)
|
|
63
|
+
: getAbsoluteWorkspaceSettingHref(workspaceId, GEN_AI_SECTION, CHANGE_LLM_MODEL_ACTION);
|
|
57
64
|
}
|
|
58
65
|
else {
|
|
59
66
|
linkHandler?.({
|
|
@@ -63,14 +70,18 @@ export function GenAIChatWrapperComponent({ loadThread, clearThread, cancelLoadi
|
|
|
63
70
|
newTab: e.metaKey,
|
|
64
71
|
section: GEN_AI_SECTION,
|
|
65
72
|
preventDefault: e.preventDefault.bind(e),
|
|
66
|
-
itemUrl:
|
|
73
|
+
itemUrl: useShellAppUrls
|
|
74
|
+
? getShellAppWorkspaceSettingHref(workspaceId, GEN_AI_SECTION, CHANGE_LLM_MODEL_ACTION)
|
|
75
|
+
: getWorkspaceSettingHref(workspaceId, GEN_AI_SECTION, CHANGE_LLM_MODEL_ACTION),
|
|
67
76
|
});
|
|
68
77
|
e.stopPropagation();
|
|
69
78
|
}
|
|
70
79
|
break;
|
|
71
80
|
case "create":
|
|
72
81
|
if (allowNativeLinks) {
|
|
73
|
-
window.location.href =
|
|
82
|
+
window.location.href = useShellAppUrls
|
|
83
|
+
? getAbsoluteShellAppOrgSettingHref(GEN_AI_SECTION, CREATE_LLM_PROVIDER_ACTION)
|
|
84
|
+
: getAbsoluteSettingHref(GEN_AI_SECTION, CREATE_LLM_PROVIDER_ACTION);
|
|
74
85
|
}
|
|
75
86
|
else {
|
|
76
87
|
linkHandler?.({
|
|
@@ -80,13 +91,15 @@ export function GenAIChatWrapperComponent({ loadThread, clearThread, cancelLoadi
|
|
|
80
91
|
newTab: e.metaKey,
|
|
81
92
|
section: GEN_AI_SECTION,
|
|
82
93
|
preventDefault: e.preventDefault.bind(e),
|
|
83
|
-
itemUrl:
|
|
94
|
+
itemUrl: useShellAppUrls
|
|
95
|
+
? getShellAppOrgSettingHref(GEN_AI_SECTION, CREATE_LLM_PROVIDER_ACTION)
|
|
96
|
+
: getSettingHref(GEN_AI_SECTION, CREATE_LLM_PROVIDER_ACTION),
|
|
84
97
|
});
|
|
85
98
|
e.stopPropagation();
|
|
86
99
|
}
|
|
87
100
|
break;
|
|
88
101
|
}
|
|
89
|
-
}, [allowNativeLinks, linkHandler, workspaceId]);
|
|
102
|
+
}, [allowNativeLinks, linkHandler, workspaceId, useShellAppUrls]);
|
|
90
103
|
if (evaluated && hasUnsupportedOpenAiModel) {
|
|
91
104
|
return (_jsx(GlobalError, { errorMessage: intl.formatMessage({ id: "gd.gen-ai.global-unsupported-model" }), errorDescription: intl.formatMessage({
|
|
92
105
|
id: "gd.gen-ai.global-unsupported-model.description",
|
package/esm/components/Input.js
CHANGED
|
@@ -90,14 +90,19 @@ function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, c
|
|
|
90
90
|
setValue("");
|
|
91
91
|
};
|
|
92
92
|
const handleKeyDown = (e) => {
|
|
93
|
-
if (e.key === "Enter" && !e.shiftKey
|
|
93
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
94
|
+
const trimmed = value.trim();
|
|
95
|
+
if (isBusy || !trimmed) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
94
98
|
e.preventDefault();
|
|
99
|
+
e.stopPropagation();
|
|
95
100
|
handleSubmit();
|
|
96
101
|
return true;
|
|
97
102
|
}
|
|
98
103
|
return false;
|
|
99
104
|
};
|
|
100
|
-
const buttonDisabled = !value || isBusy || isEvaluating;
|
|
105
|
+
const buttonDisabled = !value.trim() || isBusy || isEvaluating;
|
|
101
106
|
const buttonClasses = cx("gd-gen-ai-chat__input__send_button", {
|
|
102
107
|
"gd-gen-ai-chat__input__send_button--disabled": buttonDisabled,
|
|
103
108
|
});
|
|
@@ -111,7 +116,7 @@ function InputComponent({ isBusy, isEvaluating, newMessage, autofocus = false, c
|
|
|
111
116
|
}), children: _jsxs("div", { className: "gd-gen-ai-chat__input__content", children: [
|
|
112
117
|
_jsx("div", { ref: targetRef, onFocus: () => {
|
|
113
118
|
editorApi?.focus();
|
|
114
|
-
} }), _jsx(HintText, { focused: focused, where: "top" }), _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,
|
|
119
|
+
} }), _jsx(HintText, { focused: focused, where: "top" }), _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: {
|
|
115
120
|
aboveCursor: true,
|
|
116
121
|
whenTyping: true,
|
|
117
122
|
whenTypingDelay: 300,
|
|
@@ -27,11 +27,7 @@ function ConversationVisualizationContentCore({ message, part, scenario, visuali
|
|
|
27
27
|
const [visError, setVisError] = useState(null);
|
|
28
28
|
const [isTable, setIsTable] = useState(false);
|
|
29
29
|
const moreButtonDescId = useId();
|
|
30
|
-
const
|
|
31
|
-
containerRef,
|
|
32
|
-
filters: [],
|
|
33
|
-
setKeyDriverAnalysis,
|
|
34
|
-
});
|
|
30
|
+
const [drillState, setDrillState] = useState(null);
|
|
35
31
|
const { setSaveDialogOpen, SaveDialog } = useSaveDialog({
|
|
36
32
|
message,
|
|
37
33
|
part,
|
|
@@ -55,8 +51,8 @@ function ConversationVisualizationContentCore({ message, part, scenario, visuali
|
|
|
55
51
|
}, [visError]);
|
|
56
52
|
const classNames = cx("gd-gen-ai-chat__conversation__item__content", "gd-gen-ai-chat__conversation__item__content--visualization", className);
|
|
57
53
|
return (_jsxs("div", { className: classNames, children: [
|
|
58
|
-
_jsx(
|
|
59
|
-
_jsx(VisualisationMenu, { visualization: visualization, scenario: scenario, isVisualisationSaved: visualisationSaved, isVisualisationCheckLoading: visualisationCheckLoading, isTable: isTable, onTable: setIsTable, hasError: hasVisFatal, moreButtonId: moreButtonDescId, onSave: onSave, onOpen: onOpen, onCopy: onCopy, isLoading: part.reporting ?? false }), _jsx(Title, { id: moreButtonDescId, visualization: visualization, scenario: scenario, useMarkdown: useMarkdown }), _jsx(VisualisationWrapper, { message: message, colorPalette: colorPalette, isTable: isTable, visualization: visualization, agGridToken: agGridToken, execConfig: scenario?.execConfig, enableChangeAnalysis: enableChangeAnalysis, enableNewPivotTable: enableNewPivotTable, enableAccessibleChartTooltip: enableAccessibleChartTooltip, enableDrilling: !scenario || scenario.isBaseline, onDrillFired: setDrillState, onVisualisationError: onVisualizationError }), _jsx(SaveDialog, {})
|
|
54
|
+
_jsx(DrillState, { drillState: drillState, setDrillState: setDrillState, containerRef: containerRef, setKeyDriverAnalysis: setKeyDriverAnalysis, children: _jsxs(Wrapper, { containerRef: containerRef, visualization: visualization, children: [
|
|
55
|
+
_jsx(VisualisationMenu, { visualization: visualization, scenario: scenario, isVisualisationSaved: visualisationSaved, isVisualisationCheckLoading: visualisationCheckLoading, isTable: isTable, onTable: setIsTable, hasError: hasVisFatal, moreButtonId: moreButtonDescId, onSave: onSave, onOpen: onOpen, onCopy: onCopy, isLoading: part.reporting ?? false }), _jsx(Title, { id: moreButtonDescId, visualization: visualization, scenario: scenario, useMarkdown: useMarkdown }), _jsx(VisualisationWrapper, { message: message, colorPalette: colorPalette, isTable: isTable, visualization: visualization, agGridToken: agGridToken, execConfig: scenario?.execConfig, enableChangeAnalysis: enableChangeAnalysis, enableNewPivotTable: enableNewPivotTable, enableAccessibleChartTooltip: enableAccessibleChartTooltip, enableDrilling: !scenario || scenario.isBaseline, onDrillFired: setDrillState, onVisualisationError: onVisualizationError }), _jsx(SaveDialog, {})
|
|
60
56
|
] }) }), _jsx(VisualizationErrorReport, { error: visError })
|
|
61
57
|
] }));
|
|
62
58
|
}
|
|
@@ -214,48 +210,38 @@ function VisualizationErrorReport({ error }) {
|
|
|
214
210
|
error: error.message,
|
|
215
211
|
} }) })) : null] }));
|
|
216
212
|
}
|
|
217
|
-
function
|
|
213
|
+
function DrillState({ containerRef, filters, setKeyDriverAnalysis, children, drillState, setDrillState, }) {
|
|
218
214
|
const intl = useIntl();
|
|
219
|
-
const [drillState, setDrillState] = useState(null);
|
|
220
215
|
const catalogItems = useSelector(catalogItemsSelector);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
216
|
+
return (_jsx(Dropdown, { enableAutoToggle: false, isOpen: Boolean(drillState), onToggle: (state) => {
|
|
217
|
+
if (!state) {
|
|
218
|
+
setDrillState(null);
|
|
219
|
+
}
|
|
220
|
+
}, closeOnEscape: true, closeOnParentScroll: true, alignPoints: [
|
|
221
|
+
{
|
|
222
|
+
align: "tl tl",
|
|
223
|
+
offset: calculateOffset(containerRef.current, drillState?.event),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
align: "tl tr",
|
|
227
|
+
offset: calculateOffset(containerRef.current, drillState?.event),
|
|
228
|
+
},
|
|
229
|
+
], renderBody: () => {
|
|
230
|
+
return (_jsx(DrillSelectDropdownMenu, { drillState: drillState, onSelect: (item) => {
|
|
231
|
+
const data = item.data.context;
|
|
232
|
+
const event = drillState?.event;
|
|
233
|
+
if (!event) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const allFilters = mergeFilters(convertIntersectionToAttributeFilters(event.drillContext.intersection ?? []), (filters?.map(getDashboardAttributeFilter).filter(Boolean) ??
|
|
237
|
+
[]));
|
|
238
|
+
const definition = createKdaDefinitionFromDrill(catalogItems, intl.locale, data, event, allFilters);
|
|
239
|
+
setKeyDriverAnalysis?.({ keyDriverAnalysis: definition });
|
|
240
|
+
}, onClose: () => {
|
|
224
241
|
setDrillState(null);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
align: "tl tl",
|
|
229
|
-
offset: calculateOffset(containerRef.current, drillState?.event),
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
align: "tl tr",
|
|
233
|
-
offset: calculateOffset(containerRef.current, drillState?.event),
|
|
234
|
-
},
|
|
235
|
-
], renderBody: () => {
|
|
236
|
-
return (_jsx(DrillSelectDropdownMenu, { drillState: drillState, onSelect: (item) => {
|
|
237
|
-
const data = item.data.context;
|
|
238
|
-
const event = drillState?.event;
|
|
239
|
-
if (!event) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const allFilters = mergeFilters(convertIntersectionToAttributeFilters(event.drillContext.intersection ?? []), filters
|
|
243
|
-
.map(getDashboardAttributeFilter)
|
|
244
|
-
.filter(Boolean));
|
|
245
|
-
const definition = createKdaDefinitionFromDrill(catalogItems, intl.locale, data, event, allFilters);
|
|
246
|
-
setKeyDriverAnalysis?.({ keyDriverAnalysis: definition });
|
|
247
|
-
}, onClose: () => {
|
|
248
|
-
setDrillState(null);
|
|
249
|
-
} }));
|
|
250
|
-
}, renderButton: () => _jsx(_Fragment, { children: children }) }));
|
|
251
|
-
}, [catalogItems, containerRef, drillState, filters, intl.locale, setKeyDriverAnalysis]);
|
|
252
|
-
const DrillOverlay = useCallback(() => (_jsx(_Fragment, { children: drillState ? (_jsx("div", { className: "gd-gen-ai-chat__conversation__visualization__drill_overlay" })) : null })), [drillState]);
|
|
253
|
-
return {
|
|
254
|
-
DrillOverlay,
|
|
255
|
-
DrillChooser,
|
|
256
|
-
setDrillState,
|
|
257
|
-
drillState,
|
|
258
|
-
};
|
|
242
|
+
} }));
|
|
243
|
+
}, renderButton: () => (_jsxs(_Fragment, { children: [children, _jsx(_Fragment, { children: drillState ? (_jsx("div", { className: "gd-gen-ai-chat__conversation__visualization__drill_overlay" })) : null })
|
|
244
|
+
] })) }));
|
|
259
245
|
}
|
|
260
246
|
function calculateOffset(container, drillEvent) {
|
|
261
247
|
const offest = getRelativeOffset(drillEvent?.target, container);
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
export { ConversationDateGroup };
|
|
3
3
|
var ConversationDateGroup;
|
|
4
4
|
(function (ConversationDateGroup) {
|
|
5
|
+
ConversationDateGroup["PINNED"] = "PINNED";
|
|
5
6
|
ConversationDateGroup["TODAY"] = "TODAY";
|
|
6
7
|
ConversationDateGroup["LAST_7_DAYS"] = "LAST_7_DAYS";
|
|
7
8
|
ConversationDateGroup["OLDER"] = "OLDER";
|
|
8
9
|
})(ConversationDateGroup || (ConversationDateGroup = {}));
|
|
9
10
|
export const DEFAULT_CONVERSATION_DATE_GROUPS = [
|
|
11
|
+
{ group: ConversationDateGroup.PINNED, maxAgeDays: Number.POSITIVE_INFINITY },
|
|
10
12
|
{ group: ConversationDateGroup.TODAY, maxAgeDays: 0 },
|
|
11
13
|
{ group: ConversationDateGroup.LAST_7_DAYS, maxAgeDays: 6 },
|
|
12
14
|
{ group: ConversationDateGroup.OLDER, maxAgeDays: Number.POSITIVE_INFINITY },
|
|
@@ -20,9 +22,14 @@ export function groupConversationsByDate(conversations = [], groups = DEFAULT_CO
|
|
|
20
22
|
.slice()
|
|
21
23
|
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
22
24
|
sorted.forEach((conversation) => {
|
|
25
|
+
if (conversation.pinned) {
|
|
26
|
+
conversationGroups.get(ConversationDateGroup.PINNED)?.push(conversation);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
23
29
|
const updatedAt = new Date(conversation.updatedAt);
|
|
24
30
|
const ageInDays = getAgeInDays(updatedAt, now);
|
|
25
31
|
const targetGroup = groups
|
|
32
|
+
.filter((group) => group.group !== ConversationDateGroup.PINNED)
|
|
26
33
|
.filter((group) => ageInDays <= group.maxAgeDays)
|
|
27
34
|
.sort((a, b) => a.maxAgeDays - b.maxAgeDays)[0]?.group ?? groups[groups.length - 1].group;
|
|
28
35
|
conversationGroups.get(targetGroup)?.push(conversation);
|
package/esm/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { GenAIChat, GenAIAssistant, type GenAIChatProps, type GenAIAssistantProps, } from "./components/GenAIChat.js";
|
|
7
7
|
export { makeUserMessage, makeTextContents, makeUserItem, makeAssistantItem, type Message, type BaseMessage, type UserMessage, type AssistantMessage, type Contents, type TextContents, type SearchContents, type SemanticSearchContents, type RoutingContents, type ReasoningContents, type ReasoningStep, type ReasoningThought, type VisualizationContents, type ChangeAnalysisContents, type ErrorContents, type TextContentObject, type IChatConversationLocalContent, type IChatConversationLocalItem, type IChatConversationErrorContent, type IChatConversationMultipartLocalPart, } from "./model.js";
|
|
8
|
-
export { type ChatEventHandler, type BaseEvent, type ChatAssistantMessageEvent, type ChatUserMessageEvent, type ChatClosedEvent, type ChatOpenedEvent, type ChatResetEvent, type ChatFeedbackEvent, type ChatFeedbackErrorEvent, type ChatEvent, type ChatVisualizationErrorEvent, type ChatSaveVisualizationErrorEvent, type ChatSaveVisualizationSuccessEvent, type ChatCopyToClipboardEvent, isChatAssistantMessageEvent, isChatUserMessageEvent, isChatClosedEvent, isChatOpenedEvent, isChatResetEvent, isChatFeedbackEvent, isChatFeedbackErrorEvent, isChatVisualizationErrorEvent, isChatSaveVisualizationErrorEvent, isChatSaveVisualizationSuccessEvent, isChatCopyToClipboardEvent, } from "./store/events.js";
|
|
8
|
+
export { type ChatEventHandler, type BaseEvent, type ChatAssistantMessageEvent, type ChatUserMessageEvent, type ChatClosedEvent, type ChatOpenedEvent, type ChatResetEvent, type ChatFeedbackEvent, type ChatFeedbackErrorEvent, type ChatEvent, type ChatVisualizationErrorEvent, type ChatSaveVisualizationErrorEvent, type ChatSaveVisualizationSuccessEvent, type ChatCopyToClipboardEvent, type ChatConversationPinnedEvent, type ChatConversationDeletedEvent, type ChatConversationPinErrorEvent, type ChatConversationDeletedErrorEvent, isChatAssistantMessageEvent, isChatUserMessageEvent, isChatClosedEvent, isChatOpenedEvent, isChatResetEvent, isChatFeedbackEvent, isChatFeedbackErrorEvent, isChatVisualizationErrorEvent, isChatSaveVisualizationErrorEvent, isChatSaveVisualizationSuccessEvent, isChatCopyToClipboardEvent, isChatConversationDeletedEvent, isChatConversationPinnedEvent, isChatConversationPinErrorEvent, isChatConversationDeletedErrorEvent, } from "./store/events.js";
|
|
9
9
|
export { clearThreadAction, newMessageAction } from "./store/messages/messagesSlice.js";
|
|
10
10
|
export { type LinkHandlerEvent } from "./components/ConfigContext.js";
|
|
11
11
|
export { useGenAiChatAvailability } from "./hooks/useGenAiChatAvailability.js";
|