@red-hat-developer-hub/backstage-plugin-intelligent-assistant 4.0.0 → 4.2.0

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +23 -3
  3. package/config.schema.json +117 -0
  4. package/dist/api/NotebooksApiClient.esm.js +3 -2
  5. package/dist/api/NotebooksApiClient.esm.js.map +1 -1
  6. package/dist/api/notebooksApi.esm.js.map +1 -1
  7. package/dist/components/LightSpeedChat.esm.js +280 -118
  8. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  9. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  10. package/dist/components/LightspeedDrawerProvider.esm.js +5 -4
  11. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  12. package/dist/components/ToastAlertGroup.esm.js +56 -0
  13. package/dist/components/ToastAlertGroup.esm.js.map +1 -0
  14. package/dist/components/notebooks/AddDocumentModal.esm.js +165 -144
  15. package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
  16. package/dist/components/notebooks/DeleteDocumentModal.esm.js +73 -38
  17. package/dist/components/notebooks/DeleteDocumentModal.esm.js.map +1 -1
  18. package/dist/components/notebooks/DeleteNotebookModal.esm.js +80 -40
  19. package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -1
  20. package/dist/components/notebooks/NotebookHeaderActions.esm.js +78 -0
  21. package/dist/components/notebooks/NotebookHeaderActions.esm.js.map +1 -0
  22. package/dist/components/notebooks/NotebookStreamProvider.esm.js +47 -0
  23. package/dist/components/notebooks/NotebookStreamProvider.esm.js.map +1 -0
  24. package/dist/components/notebooks/NotebookView.esm.js +284 -349
  25. package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
  26. package/dist/components/notebooks/NotebooksTab.esm.js +2 -2
  27. package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -1
  28. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +126 -82
  29. package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
  30. package/dist/components/notebooks/SidebarCollapseIcon.esm.js +8 -6
  31. package/dist/components/notebooks/SidebarCollapseIcon.esm.js.map +1 -1
  32. package/dist/components/notebooks/UploadResourceScreen.esm.js +1 -0
  33. package/dist/components/notebooks/UploadResourceScreen.esm.js.map +1 -1
  34. package/dist/components/notebooks/notebookDialogStyles.esm.js +40 -0
  35. package/dist/components/notebooks/notebookDialogStyles.esm.js.map +1 -0
  36. package/dist/components/notebooks/notebookStreamStore.esm.js +282 -0
  37. package/dist/components/notebooks/notebookStreamStore.esm.js.map +1 -0
  38. package/dist/hooks/notebooks/useCreateNotebookMessage.esm.js +3 -2
  39. package/dist/hooks/notebooks/useCreateNotebookMessage.esm.js.map +1 -1
  40. package/dist/hooks/useConversationMessages.esm.js +31 -108
  41. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  42. package/dist/hooks/useLightspeedProviderState.esm.js +14 -5
  43. package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -1
  44. package/dist/index.esm.js +2 -2
  45. package/dist/index.esm.js.map +1 -1
  46. package/dist/utils/dom-extractor.esm.js +816 -0
  47. package/dist/utils/dom-extractor.esm.js.map +1 -0
  48. package/dist/utils/dom-selectors.esm.js +91 -0
  49. package/dist/utils/dom-selectors.esm.js.map +1 -0
  50. package/dist/utils/scoped-dialog-utils.esm.js +35 -0
  51. package/dist/utils/scoped-dialog-utils.esm.js.map +1 -0
  52. package/dist/utils/sensitive-data-redactor.esm.js +66 -0
  53. package/dist/utils/sensitive-data-redactor.esm.js.map +1 -0
  54. package/dist/utils/stream-event-helpers.esm.js +105 -0
  55. package/dist/utils/stream-event-helpers.esm.js.map +1 -0
  56. package/package.json +14 -14
  57. package/config.d.ts +0 -99
@@ -1,9 +1,10 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useState, useRef, useCallback, useEffect } from 'react';
2
+ import { useState, useCallback, useEffect, useRef } from 'react';
3
3
  import { useApi, configApiRef } from '@backstage/core-plugin-api';
4
4
  import { makeStyles, Typography } from '@material-ui/core';
5
+ import { useTheme } from '@material-ui/core/styles';
5
6
  import { ChatbotFooter, MessageBar, ChatbotContent } from '@patternfly/chatbot';
6
- import { DrawerPanelContent, AlertGroup, Alert, AlertVariant, AlertActionCloseButton, Drawer, DrawerContent, DrawerContentBody, Tooltip, Button } from '@patternfly/react-core';
7
+ import { DrawerPanelContent, Drawer, DrawerContent, DrawerContentBody, Tooltip, Button, Alert } from '@patternfly/react-core';
7
8
  import { TimesIcon, PlusIcon } from '@patternfly/react-icons';
8
9
  import { useQueryClient } from '@tanstack/react-query';
9
10
  import { notebooksApiRef } from '../../api/notebooksApi.esm.js';
@@ -17,12 +18,17 @@ import { useConversationMessages } from '../../hooks/useConversationMessages.esm
17
18
  import { useNotebookWelcomePrompts } from '../../hooks/useNotebookWelcomePrompts.esm.js';
18
19
  import { useStopConversation } from '../../hooks/useStopConversation.esm.js';
19
20
  import { useTranslation } from '../../hooks/useTranslation.esm.js';
21
+ import botAvatarDark from '../../images/bot-avatar-dark.svg';
22
+ import botAvatarLight from '../../images/bot-avatar.svg';
23
+ import userAvatar from '../../images/user-avatar.svg';
20
24
  import { ChatbotFootnoteWithIcon } from '../../utils/lightspeed-chatbox-utils.esm.js';
21
25
  import { runFileUploads } from '../../utils/notebook-upload-runner.esm.js';
22
26
  import { LightspeedChatBox } from '../LightspeedChatBox.esm.js';
27
+ import { ToastAlertGroup } from '../ToastAlertGroup.esm.js';
23
28
  import { AddDocumentModal } from './AddDocumentModal.esm.js';
24
29
  import { DeleteDocumentModal } from './DeleteDocumentModal.esm.js';
25
30
  import { DocumentSidebar } from './DocumentSidebar.esm.js';
31
+ import { useNotebookStream } from './NotebookStreamProvider.esm.js';
26
32
  import { OverwriteConfirmModal } from './OverwriteConfirmModal.esm.js';
27
33
  import { SidebarExpandIcon, AddCircleFilledIcon } from './SidebarCollapseIcon.esm.js';
28
34
  import { UploadResourceScreen } from './UploadResourceScreen.esm.js';
@@ -33,22 +39,21 @@ const useStyles = makeStyles((theme) => ({
33
39
  flexDirection: "column",
34
40
  flex: 1,
35
41
  minHeight: 0,
36
- height: "100%",
37
- backgroundColor: "var(--pf-t--global--background--color--primary--default)"
42
+ minWidth: 0,
43
+ width: "100%",
44
+ overflow: "hidden",
45
+ backgroundColor: "var(--pf-t--global--background--color--floating--default)"
46
+ },
47
+ drawerContent: {
48
+ display: "flex",
49
+ flexDirection: "column",
50
+ overflow: "hidden"
38
51
  },
39
52
  drawerContainer: {
40
53
  flex: 1,
41
54
  minHeight: 0,
55
+ minWidth: 0,
42
56
  "& .pf-v6-c-drawer__panel, & .pf-v5-c-drawer__panel": {
43
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
44
- },
45
- "& .pf-v6-c-drawer__panel-main, & .pf-v5-c-drawer__panel-main": {
46
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
47
- },
48
- "& .pf-v6-c-drawer__panel-body, & .pf-v5-c-drawer__panel-body": {
49
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
50
- },
51
- "& .pf-v6-c-drawer__splitter, & .pf-v5-c-drawer__splitter": {
52
57
  backgroundColor: "var(--pf-t--global--background--color--floating--default)"
53
58
  }
54
59
  },
@@ -69,7 +74,8 @@ const useStyles = makeStyles((theme) => ({
69
74
  mainArea: {
70
75
  display: "flex",
71
76
  flexDirection: "row",
72
- height: "100%",
77
+ flex: 1,
78
+ minHeight: 0,
73
79
  minWidth: 0
74
80
  },
75
81
  topBar: {
@@ -85,11 +91,16 @@ const useStyles = makeStyles((theme) => ({
85
91
  display: "flex",
86
92
  flexDirection: "column",
87
93
  flex: 1,
88
- minHeight: 0
94
+ minHeight: 0,
95
+ minWidth: 0
89
96
  },
90
97
  drawerContentBody: {
91
- backgroundColor: "var(--pf-t--global--background--color--primary--default)",
92
- height: "100%"
98
+ backgroundColor: "var(--pf-t--global--background--color--floating--default)",
99
+ display: "flex",
100
+ flexDirection: "column",
101
+ flex: 1,
102
+ minHeight: 0,
103
+ minWidth: 0
93
104
  },
94
105
  contentColumn: {
95
106
  display: "flex",
@@ -105,37 +116,13 @@ const useStyles = makeStyles((theme) => ({
105
116
  margin: 0,
106
117
  padding: `0 0 ${theme.spacing(1)}px`,
107
118
  boxSizing: "border-box",
108
- backgroundColor: "var(--pf-t--global--background--color--floating--default)",
109
- "& .pf-v6-c-alert, & .pf-v5-c-alert": {
110
- backgroundColor: "var(--pf-t--global--background--color--secondary--default) !important"
111
- },
112
- "& .pf-v6-c-alert__content, & .pf-v5-c-alert__content": {
113
- backgroundColor: "transparent !important"
114
- },
115
- "& .pf-v6-c-alert__body, & .pf-v5-c-alert__body": {
116
- backgroundColor: "transparent !important"
117
- },
118
- "& .pf-v6-c-alert__description, & .pf-v5-c-alert__description": {
119
- backgroundColor: "transparent !important"
120
- }
119
+ backgroundColor: "var(--pf-t--global--background--color--floating--default)"
121
120
  },
122
121
  notebookDisclaimerInner: {
123
122
  width: "95%",
124
123
  maxWidth: "unset",
125
124
  margin: "0 auto"
126
125
  },
127
- toastAlertGroup: {
128
- "--pf-v6-c-alert-group--m-toast--InsetInlineEnd": `${theme.spacing(2.5)}px`,
129
- "--pf-v6-c-alert-group--m-toast--InsetBlockStart": `${theme.spacing(2.5)}px`,
130
- "--pf-v6-c-alert-group--m-toast--MaxWidth": "350px",
131
- "--pf-v6-c-alert-group--m-toast--ZIndex": "9999"
132
- },
133
- toastAlert: {
134
- maxWidth: "350px",
135
- "& .pf-v6-c-alert__title": {
136
- margin: 0
137
- }
138
- },
139
126
  welcomeContainer: {
140
127
  display: "flex",
141
128
  flexDirection: "column",
@@ -149,6 +136,7 @@ const useStyles = makeStyles((theme) => ({
149
136
  display: "flex",
150
137
  flexDirection: "column",
151
138
  minHeight: 0,
139
+ minWidth: 0,
152
140
  backgroundColor: "var(--pf-t--global--background--color--floating--default)"
153
141
  },
154
142
  notebookContentArea: {
@@ -201,40 +189,20 @@ const useStyles = makeStyles((theme) => ({
201
189
  },
202
190
  "& .pf-chatbot__message-bar": {
203
191
  backgroundColor: theme.palette.type === "light" ? theme.palette.grey[100] : "var(--pf-t--global--background--color--secondary--default)"
204
- },
205
- "& .pf-chatbot__button--stop, & .pf-chatbot__button--attach, & .pf-chatbot__button--send, & .pf-chatbot__button--microphone": {
206
- "--pf-v6-c-button--BorderRadius": "var(--pf-t--global--border--radius--pill)",
207
- borderRadius: "var(--pf-t--global--border--radius--pill) !important"
208
- }
209
- },
210
- messageBar: {
211
- border: "1px solid var(--pf-t--global--border--color--default)",
212
- borderRadius: 24,
213
- padding: theme.spacing(0.5),
214
- "&::after": {
215
- display: "none"
216
192
  }
217
193
  },
218
- addResourceButton: {
219
- background: "none",
220
- border: "none",
221
- cursor: "pointer",
222
- padding: 4,
223
- display: "inline-flex",
224
- alignItems: "center",
225
- color: "inherit",
226
- "&:focus-visible": {
227
- outline: "2px solid var(--pf-t--global--border--color--brand--default)",
228
- outlineOffset: 2
229
- },
230
- marginLeft: theme.spacing(2)
231
- },
232
194
  chatContent: {
233
195
  minHeight: 0,
234
196
  display: "flex",
235
197
  flexDirection: "column",
236
198
  flex: 1,
237
- overflow: "auto"
199
+ overflow: "auto",
200
+ backgroundColor: "var(--pf-t--global--background--color--floating--default)",
201
+ "& .pf-chatbot__message-contents": {
202
+ overflowX: "hidden",
203
+ overflowWrap: "break-word",
204
+ wordBreak: "break-word"
205
+ }
238
206
  }
239
207
  }));
240
208
  const NotebookView = ({
@@ -248,9 +216,17 @@ const NotebookView = ({
248
216
  avatar,
249
217
  profileLoading,
250
218
  topicRestrictionEnabled,
251
- onClose
219
+ onClose,
220
+ isCompact = false,
221
+ sidebarCollapsed,
222
+ onSidebarCollapsedChange,
223
+ isUploadModalOpen,
224
+ onUploadModalOpenChange,
225
+ onUploadsInProgressChange
252
226
  }) => {
253
227
  const classes = useStyles();
228
+ const theme = useTheme();
229
+ const botAvatar = theme.palette.type === "dark" ? botAvatarDark : botAvatarLight;
254
230
  const { t } = useTranslation();
255
231
  const queryClient = useQueryClient();
256
232
  const configApi = useApi(configApiRef);
@@ -262,17 +238,15 @@ const NotebookView = ({
262
238
  const [conversationId, setConversationId] = useState(
263
239
  metadata?.conversation_id ?? TEMP_CONVERSATION_ID
264
240
  );
265
- const [isSendButtonDisabled, setIsSendButtonDisabled] = useState(false);
266
- const [requestId, setRequestId] = useState("");
267
241
  const { mutate: stopConversation } = useStopConversation();
268
- const wasStoppedByUserRef = useRef(false);
269
- const autoDeleteRef = useRef({
270
- isUntitled: false,
271
- isEmpty: true,
272
- noPending: true,
273
- noUploading: true,
274
- noChat: true
275
- });
242
+ const {
243
+ messages: streamMessages,
244
+ status: streamStatus,
245
+ requestId,
246
+ send: sendNotebookStream,
247
+ stop: stopNotebookStream
248
+ } = useNotebookStream(sessionId);
249
+ const isStreaming = streamStatus === "streaming";
276
250
  const [announcement, setAnnouncement] = useState(
277
251
  void 0
278
252
  );
@@ -284,79 +258,73 @@ const NotebookView = ({
284
258
  setDeleteDocumentTarget({ id: documentId, name: documentId });
285
259
  }, []);
286
260
  const { mutateAsync: renameDocument } = useRenameDocument();
287
- const onComplete = useCallback(
288
- (message) => {
289
- setIsSendButtonDisabled(false);
290
- if (!wasStoppedByUserRef.current) {
291
- setAnnouncement(`Message from Bot: ${message}`);
292
- }
293
- wasStoppedByUserRef.current = false;
294
- queryClient.invalidateQueries({
295
- queryKey: ["conversationMessages", conversationId]
296
- });
297
- },
298
- [queryClient, conversationId]
299
- );
300
- const onStart = useCallback((conv_id) => {
301
- setConversationId(conv_id);
302
- }, []);
303
- const createMessageAdapter = useCallback(
304
- async (vars) => {
305
- return notebookCreateMessage({
306
- prompt: vars.prompt,
307
- sessionId
308
- });
309
- },
310
- [notebookCreateMessage, sessionId]
311
- );
312
- const onRequestIdReady = useCallback((rid) => {
313
- setRequestId(rid);
314
- }, []);
315
- const { conversationMessages, handleInputPrompt, scrollToBottomRef } = useConversationMessages(
261
+ const { conversationMessages, scrollToBottomRef } = useConversationMessages(
316
262
  conversationId,
317
263
  userName,
318
264
  notebookModel,
319
265
  "",
320
- avatar,
321
- onComplete,
322
- onStart,
323
- createMessageAdapter,
324
- onRequestIdReady
266
+ avatar
325
267
  );
326
- const [messages, setMessages] = useState(conversationMessages);
268
+ const messages = streamStatus === "idle" ? conversationMessages : streamMessages;
269
+ useEffect(() => {
270
+ if (metadata?.conversation_id && metadata.conversation_id !== conversationId) {
271
+ setConversationId(metadata.conversation_id);
272
+ }
273
+ }, [metadata?.conversation_id, conversationId]);
274
+ const prevStatusRef = useRef(streamStatus);
327
275
  useEffect(() => {
328
- setMessages(conversationMessages);
329
- }, [conversationMessages]);
276
+ if (prevStatusRef.current === "streaming" && streamStatus === "complete") {
277
+ const last = streamMessages[streamMessages.length - 1];
278
+ if (last?.role === "bot" && last.content) {
279
+ setAnnouncement(`Message from Bot: ${last.content}`);
280
+ }
281
+ }
282
+ prevStatusRef.current = streamStatus;
283
+ }, [streamStatus, streamMessages]);
330
284
  const sendMessage = useCallback(
331
285
  (message) => {
332
- wasStoppedByUserRef.current = false;
286
+ const text = message.toString();
287
+ if (!text.trim()) return;
333
288
  setAnnouncement(
334
- t("conversation.announcement.userMessage", {
335
- prompt: message.toString()
336
- })
289
+ t("conversation.announcement.userMessage", { prompt: text })
337
290
  );
338
- handleInputPrompt(message.toString(), []);
339
- setIsSendButtonDisabled(true);
291
+ sendNotebookStream({
292
+ prompt: text,
293
+ seedMessages: messages,
294
+ conversationId,
295
+ userName,
296
+ avatar: avatar || userAvatar,
297
+ botAvatar,
298
+ selectedModel: notebookModel,
299
+ createMessage: (prompt, options) => notebookCreateMessage({ prompt, sessionId, signal: options?.signal })
300
+ });
340
301
  },
341
- [handleInputPrompt, t]
302
+ [
303
+ sendNotebookStream,
304
+ messages,
305
+ conversationId,
306
+ userName,
307
+ avatar,
308
+ botAvatar,
309
+ notebookModel,
310
+ notebookCreateMessage,
311
+ sessionId,
312
+ t
313
+ ]
342
314
  );
343
315
  const handleStopButton = useCallback(() => {
344
- wasStoppedByUserRef.current = true;
345
316
  if (requestId) {
346
317
  stopConversation(requestId);
347
- setRequestId("");
348
318
  }
349
- setIsSendButtonDisabled(false);
319
+ stopNotebookStream();
350
320
  setAnnouncement(t("conversation.announcement.responseStopped"));
351
- }, [requestId, stopConversation, t]);
321
+ }, [requestId, stopConversation, stopNotebookStream, t]);
352
322
  const notebookPrompts = useNotebookWelcomePrompts();
353
323
  const welcomePrompts = notebookPrompts.map((title) => ({
354
324
  title,
355
325
  onClick: () => sendMessage(title)
356
326
  }));
357
327
  const uploadMutation = useUploadDocument();
358
- const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
359
- const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
360
328
  const [uploadingFileNames, setUploadingFileNames] = useState([]);
361
329
  const [pendingUploads, setPendingUploads] = useState([]);
362
330
  const [toastAlerts, setToastAlerts] = useState([]);
@@ -368,30 +336,6 @@ const NotebookView = ({
368
336
  const [allFilesForOverwrite, setAllFilesForOverwrite] = useState([]);
369
337
  const [isOverwriteModalOpen, setIsOverwriteModalOpen] = useState(false);
370
338
  const [filesToAddToModal, setFilesToAddToModal] = useState([]);
371
- autoDeleteRef.current = {
372
- isUntitled: notebookName === UNTITLED_NOTEBOOK_NAME,
373
- isEmpty: documents.length === 0 && completedFileNames.size === 0,
374
- noPending: !pendingUploads.length,
375
- noUploading: !uploadingFileNames.length,
376
- noChat: conversationId === TEMP_CONVERSATION_ID
377
- };
378
- useEffect(() => {
379
- return () => {
380
- const currentNotebook = autoDeleteRef.current;
381
- if (currentNotebook.isUntitled && currentNotebook.isEmpty && currentNotebook.noPending && currentNotebook.noUploading && currentNotebook.noChat) {
382
- notebooksApi.deleteSession(sessionId).then(() => {
383
- queryClient.invalidateQueries({
384
- queryKey: ["notebooks", "sessions"]
385
- });
386
- }).catch(() => {
387
- });
388
- } else {
389
- queryClient.invalidateQueries({
390
- queryKey: ["notebooks", "sessions"]
391
- });
392
- }
393
- };
394
- }, [notebooksApi, sessionId, queryClient]);
395
339
  const handleRenameDocument = useCallback(
396
340
  async (documentId, newTitle) => {
397
341
  try {
@@ -443,8 +387,8 @@ const NotebookView = ({
443
387
  });
444
388
  }
445
389
  }, [deleteDocumentTarget, notebooksApi, sessionId, queryClient, t]);
446
- const handleOpenUploadModal = () => setIsUploadModalOpen(true);
447
- const handleCloseUploadModal = () => setIsUploadModalOpen(false);
390
+ const handleOpenUploadModal = () => onUploadModalOpenChange(true);
391
+ const handleCloseUploadModal = () => onUploadModalOpenChange(false);
448
392
  const handleCloseNotebook = () => {
449
393
  onClose();
450
394
  };
@@ -477,7 +421,7 @@ const NotebookView = ({
477
421
  const handleDuplicatesFound = (duplicateFiles, allFiles) => {
478
422
  setFilesToOverwrite(duplicateFiles);
479
423
  setAllFilesForOverwrite(allFiles);
480
- setIsUploadModalOpen(false);
424
+ onUploadModalOpenChange(false);
481
425
  setIsOverwriteModalOpen(true);
482
426
  };
483
427
  const handleOverwriteConfirm = (filesToUpload) => {
@@ -499,7 +443,7 @@ const NotebookView = ({
499
443
  setFilesToAddToModal(allFilesForOverwrite);
500
444
  setFilesToOverwrite([]);
501
445
  setAllFilesForOverwrite([]);
502
- setIsUploadModalOpen(true);
446
+ onUploadModalOpenChange(true);
503
447
  };
504
448
  const handleOverwriteCancel = () => {
505
449
  setIsOverwriteModalOpen(false);
@@ -553,13 +497,16 @@ const NotebookView = ({
553
497
  const hasUploadsInProgress = pendingUploads.length > 0 || isDocumentsFetching;
554
498
  const hasNoDocuments = documents.length === 0;
555
499
  const isAddDisabled = totalDocumentCount >= NOTEBOOK_MAX_FILES || hasUploadsInProgress;
500
+ useEffect(() => {
501
+ onUploadsInProgressChange?.(hasUploadsInProgress);
502
+ }, [hasUploadsInProgress, onUploadsInProgressChange]);
556
503
  const panelContent = /* @__PURE__ */ jsx(
557
504
  DrawerPanelContent,
558
505
  {
559
- isResizable: true,
560
- defaultSize: "310px",
561
- minSize: "232px",
562
- maxSize: "50%",
506
+ isResizable: !isCompact,
507
+ defaultSize: isCompact ? "100%" : "310px",
508
+ minSize: isCompact ? "100%" : "232px",
509
+ maxSize: isCompact ? "100%" : "50%",
563
510
  resizeAriaLabel: t("notebook.view.sidebar.resize"),
564
511
  children: /* @__PURE__ */ jsx(
565
512
  DocumentSidebar,
@@ -571,7 +518,7 @@ const NotebookView = ({
571
518
  deletingDocumentIds,
572
519
  collapsed: sidebarCollapsed,
573
520
  hasUploadsInProgress,
574
- onToggleCollapse: () => setSidebarCollapsed((prev) => !prev),
521
+ onToggleCollapse: () => onSidebarCollapsedChange(!sidebarCollapsed),
575
522
  onAddDocument: handleOpenUploadModal,
576
523
  onDeleteDocument: handleDeleteDocument,
577
524
  onRenameDocument: handleRenameDocument,
@@ -602,7 +549,7 @@ const NotebookView = ({
602
549
  ref: scrollToBottomRef,
603
550
  welcomePrompts: [],
604
551
  conversationId,
605
- isStreaming: isSendButtonDisabled,
552
+ isStreaming,
606
553
  topicRestrictionEnabled,
607
554
  showSourcesChipPopover: true
608
555
  }
@@ -627,214 +574,202 @@ const NotebookView = ({
627
574
  )) })
628
575
  ] });
629
576
  };
630
- return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
631
- toastAlerts.length > 0 && /* @__PURE__ */ jsx(
632
- AlertGroup,
633
- {
634
- hasAnimations: true,
635
- isToast: true,
636
- isLiveRegion: true,
637
- className: classes.toastAlertGroup,
638
- children: toastAlerts.map(({ key, title, variant }) => /* @__PURE__ */ jsx(
639
- Alert,
577
+ return /* @__PURE__ */ jsxs(
578
+ "div",
579
+ {
580
+ className: classes.root,
581
+ style: isCompact ? { position: "relative" } : void 0,
582
+ children: [
583
+ /* @__PURE__ */ jsx(
584
+ ToastAlertGroup,
640
585
  {
641
- variant: AlertVariant[variant ?? "success"],
642
- title,
643
- className: classes.toastAlert,
644
- timeout: 2e3,
645
- onTimeout: () => handleRemoveToastAlert(key),
646
- actionClose: /* @__PURE__ */ jsx(
647
- AlertActionCloseButton,
648
- {
649
- title,
650
- variantLabel: `${variant ?? "success"} alert`,
651
- onClose: () => handleRemoveToastAlert(key)
652
- }
653
- )
654
- },
655
- key
656
- ))
657
- }
658
- ),
659
- /* @__PURE__ */ jsx(
660
- Drawer,
661
- {
662
- isExpanded: !sidebarCollapsed,
663
- isInline: true,
664
- position: "start",
665
- className: classes.drawerContainer,
666
- children: /* @__PURE__ */ jsx(
667
- DrawerContent,
586
+ alerts: toastAlerts,
587
+ onRemoveAlert: handleRemoveToastAlert
588
+ }
589
+ ),
590
+ /* @__PURE__ */ jsx(
591
+ Drawer,
668
592
  {
669
- panelContent: !sidebarCollapsed ? panelContent : void 0,
670
- children: /* @__PURE__ */ jsx(DrawerContentBody, { className: classes.drawerContentBody, children: /* @__PURE__ */ jsxs("div", { className: classes.mainArea, children: [
671
- sidebarCollapsed && /* @__PURE__ */ jsxs("div", { className: classes.expandStrip, children: [
672
- /* @__PURE__ */ jsx(
673
- Tooltip,
674
- {
675
- content: t("notebook.view.sidebar.expand"),
676
- position: "right",
677
- children: /* @__PURE__ */ jsx(
678
- Button,
593
+ isExpanded: !sidebarCollapsed,
594
+ isInline: true,
595
+ position: "start",
596
+ className: classes.drawerContainer,
597
+ children: /* @__PURE__ */ jsx(
598
+ DrawerContent,
599
+ {
600
+ panelContent: !sidebarCollapsed ? panelContent : void 0,
601
+ className: classes.drawerContent,
602
+ children: /* @__PURE__ */ jsx(DrawerContentBody, { className: classes.drawerContentBody, children: /* @__PURE__ */ jsxs("div", { className: classes.mainArea, children: [
603
+ sidebarCollapsed && !isCompact && /* @__PURE__ */ jsxs("div", { className: classes.expandStrip, children: [
604
+ /* @__PURE__ */ jsx(
605
+ Tooltip,
679
606
  {
680
- variant: "plain",
681
- onClick: () => setSidebarCollapsed(false),
682
- "aria-label": t("notebook.view.sidebar.expand"),
683
- size: "sm",
684
- children: /* @__PURE__ */ jsx(SidebarExpandIcon, {})
607
+ content: t("notebook.view.sidebar.expand"),
608
+ position: "right",
609
+ children: /* @__PURE__ */ jsx(
610
+ Button,
611
+ {
612
+ variant: "plain",
613
+ onClick: () => onSidebarCollapsedChange(false),
614
+ "aria-label": t("notebook.view.sidebar.expand"),
615
+ size: "sm",
616
+ children: /* @__PURE__ */ jsx(SidebarExpandIcon, {})
617
+ }
618
+ )
685
619
  }
686
- )
687
- }
688
- ),
689
- /* @__PURE__ */ jsx(
690
- Tooltip,
691
- {
692
- content: (() => {
693
- if (hasUploadsInProgress)
694
- return t("notebook.view.documents.uploadsInProgress");
695
- if (isAddDisabled)
696
- return t("notebook.view.documents.maxReached");
697
- return t("notebook.view.documents.add");
698
- })(),
699
- position: "right",
700
- children: /* @__PURE__ */ jsx(Typography, { component: "span", children: /* @__PURE__ */ jsx(
701
- Button,
620
+ ),
621
+ /* @__PURE__ */ jsx(
622
+ Tooltip,
702
623
  {
703
- variant: "plain",
704
- className: classes.addIconButton,
705
- onClick: isAddDisabled ? void 0 : handleOpenUploadModal,
706
- "aria-label": t("notebook.view.documents.add"),
707
- isDisabled: isAddDisabled,
708
- children: /* @__PURE__ */ jsx(AddCircleFilledIcon, { disabled: isAddDisabled })
624
+ content: (() => {
625
+ if (hasUploadsInProgress)
626
+ return t("notebook.view.documents.uploadsInProgress");
627
+ if (isAddDisabled)
628
+ return t("notebook.view.documents.maxReached");
629
+ return t("notebook.view.documents.add");
630
+ })(),
631
+ position: "right",
632
+ children: /* @__PURE__ */ jsx(Typography, { component: "span", children: /* @__PURE__ */ jsx(
633
+ Button,
634
+ {
635
+ variant: "plain",
636
+ className: classes.addIconButton,
637
+ onClick: isAddDisabled ? void 0 : handleOpenUploadModal,
638
+ "aria-label": t("notebook.view.documents.add"),
639
+ isDisabled: isAddDisabled,
640
+ children: /* @__PURE__ */ jsx(AddCircleFilledIcon, { disabled: isAddDisabled })
641
+ }
642
+ ) })
709
643
  }
710
- ) })
711
- }
712
- )
713
- ] }),
714
- /* @__PURE__ */ jsxs("div", { className: classes.contentColumn, children: [
715
- /* @__PURE__ */ jsx("div", { className: classes.topBar, children: /* @__PURE__ */ jsx(
716
- Button,
717
- {
718
- variant: "link",
719
- className: classes.closeButton,
720
- onClick: handleCloseNotebook,
721
- icon: /* @__PURE__ */ jsx(TimesIcon, {}),
722
- iconPosition: "end",
723
- children: t("notebook.view.close")
724
- }
725
- ) }),
726
- /* @__PURE__ */ jsx("div", { className: classes.mainContent, children: renderMainContent() }),
727
- hasNoDocuments && messages.length === 0 && renderNotebookDisclaimerAlert(),
728
- /* @__PURE__ */ jsxs(ChatbotFooter, { className: classes.footer, children: [
729
- (() => {
730
- const addResourceAction = /* @__PURE__ */ jsx(
731
- "button",
644
+ )
645
+ ] }),
646
+ /* @__PURE__ */ jsxs("div", { className: classes.contentColumn, children: [
647
+ !isCompact && /* @__PURE__ */ jsx("div", { className: classes.topBar, children: /* @__PURE__ */ jsx(
648
+ Button,
732
649
  {
733
- type: "button",
734
- onClick: () => handleOpenUploadModal(),
735
- "aria-label": t("notebook.view.documents.add"),
736
- className: classes.addResourceButton,
737
- children: /* @__PURE__ */ jsx(PlusIcon, { style: { width: 16, height: 16 } })
650
+ variant: "link",
651
+ className: classes.closeButton,
652
+ onClick: handleCloseNotebook,
653
+ icon: /* @__PURE__ */ jsx(TimesIcon, {}),
654
+ iconPosition: "end",
655
+ children: t("notebook.view.close")
738
656
  }
739
- );
740
- return hasNoDocuments ? /* @__PURE__ */ jsx(
741
- Tooltip,
742
- {
743
- content: t("notebook.view.input.disabledTooltip"),
744
- position: "top",
745
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
657
+ ) }),
658
+ /* @__PURE__ */ jsx("div", { className: classes.mainContent, children: renderMainContent() }),
659
+ hasNoDocuments && messages.length === 0 && renderNotebookDisclaimerAlert(),
660
+ /* @__PURE__ */ jsxs(ChatbotFooter, { className: classes.footer, children: [
661
+ (() => {
662
+ const addResourceAction = /* @__PURE__ */ jsx(
663
+ Button,
664
+ {
665
+ variant: "plain",
666
+ onClick: handleOpenUploadModal,
667
+ "aria-label": t("notebook.view.documents.add"),
668
+ size: "sm",
669
+ children: /* @__PURE__ */ jsx(PlusIcon, {})
670
+ }
671
+ );
672
+ return hasNoDocuments ? /* @__PURE__ */ jsx(
673
+ Tooltip,
674
+ {
675
+ content: t("notebook.view.input.disabledTooltip"),
676
+ position: "top",
677
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
678
+ MessageBar,
679
+ {
680
+ hasAttachButton: false,
681
+ hasMicrophoneButton: false,
682
+ hasStopButton: false,
683
+ isSendButtonDisabled: true,
684
+ isDisabled: true,
685
+ onSendMessage: sendMessage,
686
+ placeholder: t("notebook.view.input.placeholder"),
687
+ forceMultilineLayout: true,
688
+ additionalActions: addResourceAction,
689
+ buttonProps: {
690
+ send: {
691
+ tooltipContent: t("tooltip.send")
692
+ }
693
+ }
694
+ }
695
+ ) })
696
+ }
697
+ ) : /* @__PURE__ */ jsx(
746
698
  MessageBar,
747
699
  {
748
- className: classes.messageBar,
749
700
  hasAttachButton: false,
750
- hasMicrophoneButton: false,
751
- hasStopButton: false,
752
- isSendButtonDisabled: true,
753
- isDisabled: true,
701
+ hasMicrophoneButton: true,
702
+ hasStopButton: isStreaming,
703
+ handleStopButton: isStreaming ? handleStopButton : void 0,
704
+ isSendButtonDisabled: isStreaming,
754
705
  onSendMessage: sendMessage,
755
706
  placeholder: t("notebook.view.input.placeholder"),
756
707
  forceMultilineLayout: true,
757
708
  additionalActions: addResourceAction,
758
709
  buttonProps: {
710
+ microphone: {
711
+ tooltipContent: {
712
+ active: t("tooltip.microphone.active"),
713
+ inactive: t("tooltip.microphone.inactive")
714
+ }
715
+ },
759
716
  send: {
760
717
  tooltipContent: t("tooltip.send")
761
718
  }
762
719
  }
763
720
  }
764
- ) })
765
- }
766
- ) : /* @__PURE__ */ jsx(
767
- MessageBar,
768
- {
769
- className: classes.messageBar,
770
- hasAttachButton: false,
771
- hasMicrophoneButton: true,
772
- hasStopButton: isSendButtonDisabled,
773
- handleStopButton: isSendButtonDisabled ? handleStopButton : void 0,
774
- isSendButtonDisabled,
775
- onSendMessage: sendMessage,
776
- placeholder: t("notebook.view.input.placeholder"),
777
- forceMultilineLayout: true,
778
- additionalActions: addResourceAction,
779
- buttonProps: {
780
- microphone: {
781
- tooltipContent: {
782
- active: t("tooltip.microphone.active"),
783
- inactive: t("tooltip.microphone.inactive")
784
- }
785
- },
786
- send: {
787
- tooltipContent: t("tooltip.send")
788
- }
789
- }
790
- }
791
- );
792
- })(),
793
- /* @__PURE__ */ jsx(ChatbotFootnoteWithIcon, { label: t("footer.accuracy.label") })
794
- ] })
795
- ] })
796
- ] }) })
721
+ );
722
+ })(),
723
+ /* @__PURE__ */ jsx(ChatbotFootnoteWithIcon, { label: t("footer.accuracy.label") })
724
+ ] })
725
+ ] })
726
+ ] }) })
727
+ }
728
+ )
729
+ }
730
+ ),
731
+ /* @__PURE__ */ jsx(
732
+ AddDocumentModal,
733
+ {
734
+ isOpen: isUploadModalOpen,
735
+ onClose: handleCloseUploadModal,
736
+ sessionId,
737
+ existingDocumentNames: documents.map((d) => d.title),
738
+ hasUploadsInProgress,
739
+ onFilesUploading: handleFilesUploading,
740
+ onUploadStarted: handleUploadStarted,
741
+ onUploadFailed: handleUploadFailed,
742
+ onDuplicatesFound: handleDuplicatesFound,
743
+ filesToAdd: filesToAddToModal,
744
+ onFilesAdded: handleFilesAddedToModal,
745
+ isCompact
746
+ }
747
+ ),
748
+ /* @__PURE__ */ jsx(
749
+ OverwriteConfirmModal,
750
+ {
751
+ isOpen: isOverwriteModalOpen,
752
+ onClose: handleOverwriteCancel,
753
+ onConfirm: handleOverwriteConfirm,
754
+ onBack: handleOverwriteBack,
755
+ allFiles: allFilesForOverwrite,
756
+ duplicateFileNames: filesToOverwrite.map((f) => f.name),
757
+ isCompact
758
+ }
759
+ ),
760
+ /* @__PURE__ */ jsx(
761
+ DeleteDocumentModal,
762
+ {
763
+ isOpen: deleteDocumentTarget !== null,
764
+ onClose: () => setDeleteDocumentTarget(null),
765
+ onConfirm: confirmDeleteDocument,
766
+ documentName: deleteDocumentTarget?.name ?? "",
767
+ isCompact
797
768
  }
798
769
  )
799
- }
800
- ),
801
- /* @__PURE__ */ jsx(
802
- AddDocumentModal,
803
- {
804
- isOpen: isUploadModalOpen,
805
- onClose: handleCloseUploadModal,
806
- sessionId,
807
- existingDocumentNames: documents.map((d) => d.title),
808
- hasUploadsInProgress,
809
- onFilesUploading: handleFilesUploading,
810
- onUploadStarted: handleUploadStarted,
811
- onUploadFailed: handleUploadFailed,
812
- onDuplicatesFound: handleDuplicatesFound,
813
- filesToAdd: filesToAddToModal,
814
- onFilesAdded: handleFilesAddedToModal
815
- }
816
- ),
817
- /* @__PURE__ */ jsx(
818
- OverwriteConfirmModal,
819
- {
820
- isOpen: isOverwriteModalOpen,
821
- onClose: handleOverwriteCancel,
822
- onConfirm: handleOverwriteConfirm,
823
- onBack: handleOverwriteBack,
824
- allFiles: allFilesForOverwrite,
825
- duplicateFileNames: filesToOverwrite.map((f) => f.name)
826
- }
827
- ),
828
- /* @__PURE__ */ jsx(
829
- DeleteDocumentModal,
830
- {
831
- isOpen: deleteDocumentTarget !== null,
832
- onClose: () => setDeleteDocumentTarget(null),
833
- onConfirm: confirmDeleteDocument,
834
- documentName: deleteDocumentTarget?.name ?? ""
835
- }
836
- )
837
- ] });
770
+ ]
771
+ }
772
+ );
838
773
  };
839
774
 
840
775
  export { NotebookView };