@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.0.1 → 5.1.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 (121) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/alpha.d.ts +1 -9
  3. package/dist/components/Attachment.esm.js +10 -12
  4. package/dist/components/Attachment.esm.js.map +1 -1
  5. package/dist/components/CollapsedHistoryStrip.esm.js +46 -51
  6. package/dist/components/CollapsedHistoryStrip.esm.js.map +1 -1
  7. package/dist/components/FilePreview.esm.js +3 -2
  8. package/dist/components/FilePreview.esm.js.map +1 -1
  9. package/dist/components/LightSpeedChat.esm.js +655 -787
  10. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  11. package/dist/components/LightspeedChatBox.esm.js +2 -3
  12. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatBoxHeader.esm.js +40 -35
  14. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  15. package/dist/components/LightspeedChatContainer.esm.js +43 -67
  16. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  17. package/dist/components/LightspeedChatModelsState.esm.js +67 -73
  18. package/dist/components/LightspeedChatModelsState.esm.js.map +1 -1
  19. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  20. package/dist/components/LightspeedDrawerProvider.esm.js +13 -16
  21. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  22. package/dist/components/LightspeedFABContent.esm.js +49 -9
  23. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  24. package/dist/components/LightspeedPage.esm.js +12 -12
  25. package/dist/components/LightspeedPage.esm.js.map +1 -1
  26. package/dist/components/McpConfigureServerModal.esm.js +81 -89
  27. package/dist/components/McpConfigureServerModal.esm.js.map +1 -1
  28. package/dist/components/McpServersSettings.esm.js +259 -239
  29. package/dist/components/McpServersSettings.esm.js.map +1 -1
  30. package/dist/components/MessageBarModelSelector.esm.js +29 -33
  31. package/dist/components/MessageBarModelSelector.esm.js.map +1 -1
  32. package/dist/components/RenameConversationModal.esm.js +38 -31
  33. package/dist/components/RenameConversationModal.esm.js.map +1 -1
  34. package/dist/components/Router.esm.js +4 -13
  35. package/dist/components/Router.esm.js.map +1 -1
  36. package/dist/components/ToastAlertGroup.esm.js +24 -40
  37. package/dist/components/ToastAlertGroup.esm.js.map +1 -1
  38. package/dist/components/ToolCallContent.esm.js +8 -11
  39. package/dist/components/ToolCallContent.esm.js.map +1 -1
  40. package/dist/components/notebooks/AddDocumentModal.esm.js +232 -252
  41. package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
  42. package/dist/components/notebooks/DeleteDocumentModal.esm.js +35 -77
  43. package/dist/components/notebooks/DeleteDocumentModal.esm.js.map +1 -1
  44. package/dist/components/notebooks/DeleteNotebookModal.esm.js +46 -81
  45. package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -1
  46. package/dist/components/notebooks/DocumentSidebar.esm.js +172 -196
  47. package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
  48. package/dist/components/notebooks/FileListItem.esm.js +69 -57
  49. package/dist/components/notebooks/FileListItem.esm.js.map +1 -1
  50. package/dist/components/notebooks/FileTypeIcon.esm.js +17 -27
  51. package/dist/components/notebooks/FileTypeIcon.esm.js.map +1 -1
  52. package/dist/components/notebooks/NotebookCard.esm.js +86 -25
  53. package/dist/components/notebooks/NotebookCard.esm.js.map +1 -1
  54. package/dist/components/notebooks/NotebookView.esm.js +367 -380
  55. package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
  56. package/dist/components/notebooks/NotebooksTab.esm.js +93 -30
  57. package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -1
  58. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +142 -184
  59. package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
  60. package/dist/components/notebooks/UploadResourceScreen.esm.js +58 -50
  61. package/dist/components/notebooks/UploadResourceScreen.esm.js.map +1 -1
  62. package/dist/components/notebooks/notebookDialogStyles.esm.js +33 -37
  63. package/dist/components/notebooks/notebookDialogStyles.esm.js.map +1 -1
  64. package/dist/const.esm.js +15 -2
  65. package/dist/const.esm.js.map +1 -1
  66. package/dist/hooks/useAllModels.esm.js +2 -1
  67. package/dist/hooks/useAllModels.esm.js.map +1 -1
  68. package/dist/hooks/useAutoScroll.esm.js +11 -11
  69. package/dist/hooks/useAutoScroll.esm.js.map +1 -1
  70. package/dist/hooks/useBufferedMessages.esm.js +5 -5
  71. package/dist/hooks/useBufferedMessages.esm.js.map +1 -1
  72. package/dist/hooks/useConversations.esm.js +2 -1
  73. package/dist/hooks/useConversations.esm.js.map +1 -1
  74. package/dist/hooks/useIaChatPermission.esm.js +15 -0
  75. package/dist/hooks/useIaChatPermission.esm.js.map +1 -0
  76. package/dist/hooks/useIaMcpToolsPermission.esm.js +15 -0
  77. package/dist/hooks/useIaMcpToolsPermission.esm.js.map +1 -0
  78. package/dist/hooks/{notebooks/useLightspeedNotebooksPermission.esm.js → useIaNotebooksPermission.esm.js} +4 -5
  79. package/dist/hooks/useIaNotebooksPermission.esm.js.map +1 -0
  80. package/dist/hooks/useIsMobile.esm.js +3 -3
  81. package/dist/hooks/useIsMobile.esm.js.map +1 -1
  82. package/dist/hooks/useMcpConfigureModal.esm.js +5 -9
  83. package/dist/hooks/useMcpConfigureModal.esm.js.map +1 -1
  84. package/dist/hooks/useNotebookConversationIds.esm.js +2 -1
  85. package/dist/hooks/useNotebookConversationIds.esm.js.map +1 -1
  86. package/dist/hooks/useQuestionValidation.esm.js +3 -2
  87. package/dist/hooks/useQuestionValidation.esm.js.map +1 -1
  88. package/dist/hooks/useWelcomePrompts.esm.js +2 -2
  89. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  90. package/dist/translations/de.esm.js +1 -9
  91. package/dist/translations/de.esm.js.map +1 -1
  92. package/dist/translations/es.esm.js +1 -9
  93. package/dist/translations/es.esm.js.map +1 -1
  94. package/dist/translations/fr.esm.js +1 -9
  95. package/dist/translations/fr.esm.js.map +1 -1
  96. package/dist/translations/it.esm.js +1 -9
  97. package/dist/translations/it.esm.js.map +1 -1
  98. package/dist/translations/ja.esm.js +1 -9
  99. package/dist/translations/ja.esm.js.map +1 -1
  100. package/dist/translations/ref.esm.js +1 -10
  101. package/dist/translations/ref.esm.js.map +1 -1
  102. package/dist/types.esm.js.map +1 -1
  103. package/dist/utils/fab-anchor-utils.esm.js +41 -0
  104. package/dist/utils/fab-anchor-utils.esm.js.map +1 -0
  105. package/dist/utils/scoped-dialog-utils.esm.js +6 -3
  106. package/dist/utils/scoped-dialog-utils.esm.js.map +1 -1
  107. package/package.json +5 -8
  108. package/dist/components/PermissionRequiredIcon.esm.js +0 -18
  109. package/dist/components/PermissionRequiredIcon.esm.js.map +0 -1
  110. package/dist/components/PermissionRequiredState.esm.js +0 -88
  111. package/dist/components/PermissionRequiredState.esm.js.map +0 -1
  112. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +0 -1
  113. package/dist/hooks/useLightspeedDeletePermission.esm.js +0 -12
  114. package/dist/hooks/useLightspeedDeletePermission.esm.js.map +0 -1
  115. package/dist/hooks/useLightspeedUpdatePermission.esm.js +0 -12
  116. package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +0 -1
  117. package/dist/hooks/useLightspeedViewPermission.esm.js +0 -16
  118. package/dist/hooks/useLightspeedViewPermission.esm.js.map +0 -1
  119. package/dist/images/permission-required.svg +0 -319
  120. package/dist/utils/generateClassName.esm.js +0 -12
  121. package/dist/utils/generateClassName.esm.js.map +0 -1
@@ -2,13 +2,13 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { useState, useEffect, useRef, useLayoutEffect, useCallback, useMemo } from 'react';
3
3
  import { useNavigate, useMatch, useLocation } from 'react-router-dom';
4
4
  import { useApi, configApiRef } from '@backstage/core-plugin-api';
5
- import { makeStyles, Button as Button$1 } from '@material-ui/core';
5
+ import { styled } from '@mui/material/styles';
6
6
  import Tab from '@mui/material/Tab';
7
7
  import Tabs from '@mui/material/Tabs';
8
- import { ChatbotDisplayMode, ChatbotContent, ChatbotFooter, MessageBar, Settings, Chatbot, ChatbotHeader, ChatbotHeaderMain, ChatbotHeaderTitle, FileDropZone, ChatbotAlert } from '@patternfly/chatbot';
8
+ import { Chatbot, ChatbotHeader, ChatbotHeaderTitle, ChatbotFooter, MessageBar, ChatbotContent, Settings, ChatbotDisplayMode, ChatbotHeaderMain, ChatbotAlert, FileDropZone } from '@patternfly/chatbot';
9
9
  import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
10
- import { DropdownItem, Tooltip, MenuToggle, Select, SelectList, SelectOption, Button, Title, Label } from '@patternfly/react-core';
11
- import { PenIcon, ThumbtackIcon, TrashIcon, SortAmountDownAltIcon, SortAmountDownIcon, PlusIcon, SearchIcon } from '@patternfly/react-icons';
10
+ import { SelectList, DropdownItem, Tooltip, MenuToggle, Select, SelectOption, Button, Title, Label } from '@patternfly/react-core';
11
+ import { PenIcon, ThumbtackIcon, TrashIcon, SearchIcon, SortAmountDownAltIcon, SortAmountDownIcon, PlusIcon } from '@patternfly/react-icons';
12
12
  import { RhUiAiExperienceIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-ai-experience-icon';
13
13
  import { useQueryClient } from '@tanstack/react-query';
14
14
  import { LIGHTSPEED_PATH, UNTITLED_NOTEBOOK_NAME, TEMP_CONVERSATION_ID, supportedFileTypes } from '../const.esm.js';
@@ -19,8 +19,9 @@ import { useConversations } from '../hooks/useConversations.esm.js';
19
19
  import { useDeleteNotebook } from '../hooks/notebooks/useDeleteNotebook.esm.js';
20
20
  import { useIsMobile } from '../hooks/useIsMobile.esm.js';
21
21
  import { useLastOpenedConversation } from '../hooks/useLastOpenedConversation.esm.js';
22
- import { useLightspeedDeletePermission } from '../hooks/useLightspeedDeletePermission.esm.js';
23
- import { useLightspeedNotebooksPermission } from '../hooks/notebooks/useLightspeedNotebooksPermission.esm.js';
22
+ import { useIaChatPermission } from '../hooks/useIaChatPermission.esm.js';
23
+ import { useIaMcpToolsPermission } from '../hooks/useIaMcpToolsPermission.esm.js';
24
+ import { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission.esm.js';
24
25
  import '@backstage/plugin-permission-react';
25
26
  import '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-common';
26
27
  import { useTranslation } from '../hooks/useTranslation.esm.js';
@@ -35,7 +36,6 @@ import { useStopConversation } from '../hooks/useStopConversation.esm.js';
35
36
  import { useCreateNotebook } from '../hooks/notebooks/useCreateNotebook.esm.js';
36
37
  import { useNotebookDocuments } from '../hooks/notebooks/useNotebookDocuments.esm.js';
37
38
  import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
38
- import { useLightspeedUpdatePermission } from '../hooks/useLightspeedUpdatePermission.esm.js';
39
39
  import { useWelcomePrompts } from '../hooks/useWelcomePrompts.esm.js';
40
40
  import { getAttachments } from '../utils/attachment-utils.esm.js';
41
41
  import { extractPageContext } from '../utils/dom-extractor.esm.js';
@@ -55,7 +55,6 @@ import { NotebooksTab } from './notebooks/NotebooksTab.esm.js';
55
55
  import { useNotebookStreamStore } from './notebooks/NotebookStreamProvider.esm.js';
56
56
  import { NotebookView } from './notebooks/NotebookView.esm.js';
57
57
  import { SidebarCollapseIcon, SidebarExpandIcon } from './notebooks/SidebarCollapseIcon.esm.js';
58
- import PermissionRequiredState from './PermissionRequiredState.esm.js';
59
58
  import { RenameConversationModal } from './RenameConversationModal.esm.js';
60
59
  import { ToastAlertGroup } from './ToastAlertGroup.esm.js';
61
60
 
@@ -65,37 +64,70 @@ const ConditionalWrapper = ({
65
64
  wrapper,
66
65
  children
67
66
  }) => condition ? wrapper(children) : children;
68
- const useStyles = makeStyles((theme) => ({
69
- body: {
70
- "& h1, & h2, & h3, & h4, & h5, & h6, & p, & li": {
71
- margin: 0,
72
- padding: 0
73
- },
74
- "& .pf-chatbot__content": {
75
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
76
- },
77
- "& .pf-v6-svg > .pf-v6-icon-rh-ui": {
78
- display: "none !important",
79
- width: 0,
80
- height: 0,
81
- overflow: "hidden"
82
- }
67
+ const floatingBg = "var(--pf-t--global--background--color--floating--default)";
68
+ const StyledChatbot = styled(Chatbot, {
69
+ shouldForwardProp: (prop) => prop !== "isCompact" && prop !== "mcpDrawerFix" && prop !== "compactDrawerOpen"
70
+ })(({ isCompact, mcpDrawerFix, compactDrawerOpen }) => ({
71
+ "& h1, & h2, & h3, & h4, & h5, & h6, & p, & li": {
72
+ margin: 0,
73
+ padding: 0
83
74
  },
84
- bodyCompact: {
85
- height: "100% !important",
86
- minHeight: "0 !important",
75
+ "& .pf-chatbot__content": {
76
+ backgroundColor: `${floatingBg} !important`
77
+ },
78
+ "& .pf-v6-svg > .pf-v6-icon-rh-ui": {
79
+ display: "none !important",
80
+ width: 0,
81
+ height: 0,
87
82
  overflow: "hidden"
88
83
  },
89
- header: {
90
- padding: `${theme.spacing(3)}px ${theme.spacing(3)}px 0 ${theme.spacing(
91
- 3
92
- )}px !important`,
93
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
84
+ "& .pf-chatbot-container": {
85
+ minHeight: 0
94
86
  },
95
- errorContainer: {
96
- padding: theme.spacing(3)
87
+ "& .pf-chatbot__header-container": {
88
+ flexShrink: 0
97
89
  },
98
- drawerFileDropZone: {
90
+ ...isCompact ? {
91
+ height: "100% !important",
92
+ minHeight: "0 !important",
93
+ overflow: "hidden"
94
+ } : {},
95
+ // Match the previous compactDrawerPanel class: only expand the history
96
+ // panel when it is actually open. Applying 100% width while collapsed
97
+ // lets the z-index: 1300 panel cover the Chat/Notebooks tab bar.
98
+ ...isCompact && compactDrawerOpen ? {
99
+ "& .pf-v6-c-drawer__panel": {
100
+ width: "100%",
101
+ minWidth: "100%",
102
+ maxWidth: "100%",
103
+ flexBasis: "100%"
104
+ }
105
+ } : {},
106
+ ...mcpDrawerFix ? {
107
+ "& .pf-v6-c-drawer.pf-m-panel-left > .pf-v6-c-drawer__main > .pf-v6-c-drawer__content, & .pf-v5-c-drawer.pf-m-panel-left > .pf-v5-c-drawer__main > .pf-v5-c-drawer__content": {
108
+ order: "unset"
109
+ },
110
+ "& .pf-v6-c-drawer:not(.pf-m-expanded) > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel, & .pf-v5-c-drawer:not(.pf-m-expanded) > .pf-v5-c-drawer__main > .pf-v5-c-drawer__panel": {
111
+ visibility: "hidden",
112
+ opacity: 0,
113
+ transition: "none !important"
114
+ }
115
+ } : {}
116
+ }));
117
+ const StyledChatbotHeader = styled(ChatbotHeader)(({ theme }) => ({
118
+ padding: `${theme.spacing(3)} ${theme.spacing(3)} 0 ${theme.spacing(3)} !important`,
119
+ backgroundColor: `${floatingBg} !important`
120
+ }));
121
+ const ErrorContainer = styled("div")(({ theme }) => ({
122
+ padding: theme.spacing(3)
123
+ }));
124
+ const FileDropZoneShell = styled("div")({
125
+ flex: 1,
126
+ minWidth: 0,
127
+ minHeight: 0,
128
+ display: "flex",
129
+ flexDirection: "column",
130
+ "& > .pf-chatbot__dropzone": {
99
131
  gap: 0,
100
132
  rowGap: 0,
101
133
  columnGap: 0,
@@ -103,443 +135,262 @@ const useStyles = makeStyles((theme) => ({
103
135
  "--pf-v5-c-multiple-file-upload--Gap": "0",
104
136
  flex: 1,
105
137
  minWidth: 0,
106
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
107
- },
108
- chatHeaderActions: {
109
- display: "flex",
110
- alignItems: "center",
111
- gap: theme.spacing(0.5)
112
- },
113
- compactDrawerPanel: {
114
- "&.pf-v6-c-drawer__panel": {
115
- width: "100%",
116
- minWidth: "100%",
117
- maxWidth: "100%",
118
- flexBasis: "100%"
119
- }
120
- },
121
- notebookHeaderActions: {
122
- display: "flex",
123
- alignItems: "center",
124
- gap: theme.spacing(0.5)
125
- },
126
- headerLogo: {
127
- width: 48,
128
- height: 48,
129
- marginRight: theme.spacing(1.5),
130
- flexShrink: 0
131
- },
132
- headerTitle: {
133
- justifyContent: "left !important"
134
- },
135
- headerDivider: {
136
- paddingTop: 8,
137
- borderBottom: "1px solid var(--pf-t--global--border--color--default)",
138
- backgroundColor: "var(--pf-t--global--background--color--floating--default)"
139
- },
140
- notebooksContainer: {
141
- padding: theme.spacing(3),
142
- height: "100%",
143
- display: "flex",
144
- flexDirection: "column",
138
+ backgroundColor: `${floatingBg} !important`
139
+ }
140
+ });
141
+ const ChatFileDropZone = (props) => /* @__PURE__ */ jsx(FileDropZoneShell, { children: /* @__PURE__ */ jsx(
142
+ FileDropZone,
143
+ {
144
+ ...{ ...props, noClick: true }
145
+ }
146
+ ) });
147
+ const HeaderActions = styled("div")(({ theme }) => ({
148
+ display: "flex",
149
+ alignItems: "center",
150
+ gap: theme.spacing(0.5)
151
+ }));
152
+ const HeaderLogo = styled(RhUiAiExperienceIcon)(({ theme }) => ({
153
+ width: 48,
154
+ height: 48,
155
+ marginRight: theme.spacing(1.5),
156
+ flexShrink: 0
157
+ }));
158
+ const StyledChatbotHeaderTitle = styled(ChatbotHeaderTitle)({
159
+ justifyContent: "left !important"
160
+ });
161
+ const HeaderDivider = styled("div")({
162
+ flexShrink: 0,
163
+ paddingTop: 8,
164
+ borderBottom: "1px solid var(--pf-t--global--border--color--default)",
165
+ backgroundColor: floatingBg
166
+ });
167
+ const ChatMain = styled("div")({
168
+ flex: 1,
169
+ minHeight: 0,
170
+ minWidth: 0,
171
+ display: "flex",
172
+ flexDirection: "column",
173
+ overflow: "hidden",
174
+ "& .pf-chatbot__history": {
145
175
  flex: 1,
146
176
  minHeight: 0,
147
- overflowY: "auto",
148
- backgroundColor: "var(--pf-t--global--background--color--floating--default)"
177
+ height: "100%"
178
+ }
179
+ });
180
+ const NotebooksTabLabel = styled("span", {
181
+ shouldForwardProp: (prop) => prop !== "isCompact"
182
+ })(({ theme, isCompact }) => ({
183
+ display: "inline-flex",
184
+ alignItems: "center",
185
+ gap: isCompact ? theme.spacing(0.5) : theme.spacing(1),
186
+ minWidth: 0,
187
+ maxWidth: "100%"
188
+ }));
189
+ const StyledChatbotFooter = styled(ChatbotFooter)(({ theme }) => ({
190
+ "&.pf-chatbot__footer": {
191
+ backgroundColor: `${floatingBg} !important`
149
192
  },
150
- notebooksHeader: {
151
- display: "flex",
152
- alignItems: "center",
153
- justifyContent: "space-between",
154
- flexWrap: "wrap",
155
- gap: theme.spacing(1),
156
- marginBottom: theme.spacing(4)
193
+ "&>.pf-chatbot__footer-container": {
194
+ width: "100% !important",
195
+ padding: `${theme.spacing(1.5)} !important`,
196
+ maxWidth: "unset !important",
197
+ margin: "0 auto"
157
198
  },
158
- notebooksHeading: {
159
- marginBottom: 0,
160
- whiteSpace: "nowrap",
161
- fontSize: "1.25rem"
199
+ "& .pf-chatbot__message-bar": {
200
+ backgroundColor: theme.palette.mode === "light" ? theme.palette.grey[100] : "var(--pf-t--global--background--color--secondary--default)"
162
201
  },
163
- notebooksHeadingEmpty: {
164
- "&&": {
165
- marginBottom: theme.spacing(1),
166
- paddingBottom: theme.spacing(1)
167
- }
202
+ "& .pf-chatbot__button--stop, & .pf-chatbot__button--attach, & .pf-chatbot__button--send, & .pf-chatbot__button--microphone": {
203
+ borderRadius: "var(--pf-t--global--border--radius--pill) !important"
204
+ }
205
+ }));
206
+ const StyledMessageBar = styled(MessageBar)(({ theme }) => ({
207
+ border: "1px solid var(--pf-t--global--border--color--default)",
208
+ borderRadius: 24,
209
+ padding: theme.spacing(0.5),
210
+ "&::after": {
211
+ display: "none"
212
+ }
213
+ }));
214
+ const StyledSelectList = styled(SelectList)({
215
+ padding: 0,
216
+ margin: 0
217
+ });
218
+ const StyledChatbotContent = styled(ChatbotContent, {
219
+ shouldForwardProp: (prop) => prop !== "hasOverflow"
220
+ })(({ hasOverflow }) => ({
221
+ minHeight: 0,
222
+ display: "flex",
223
+ flexDirection: "column",
224
+ flex: 1,
225
+ "& .pf-chatbot__jump": {
226
+ left: "50% !important",
227
+ right: "auto !important",
228
+ transform: "translateX(-50%)",
229
+ visibility: hasOverflow ? "visible" : "hidden",
230
+ pointerEvents: hasOverflow ? "auto" : "none"
168
231
  },
169
- notebooksEmptyState: {
232
+ "& .pf-chatbot__message-contents": {
233
+ overflowX: "hidden",
234
+ overflowWrap: "break-word",
235
+ wordBreak: "break-word"
236
+ }
237
+ }));
238
+ const ContentScroll = styled("div", {
239
+ shouldForwardProp: (prop) => prop !== "isNewChat"
240
+ })(({ isNewChat }) => ({
241
+ minHeight: 0,
242
+ flex: 1,
243
+ display: "flex",
244
+ flexDirection: "column",
245
+ overflowY: "auto",
246
+ WebkitOverflowScrolling: "touch",
247
+ ...isNewChat ? { backgroundColor: `${floatingBg} !important` } : {}
248
+ }));
249
+ const ContentSpacer = styled("div")({
250
+ flex: 1,
251
+ minHeight: 0
252
+ });
253
+ const FlatSettings = styled(Settings)({
254
+ height: "100%",
255
+ width: "100%",
256
+ flex: 1,
257
+ minHeight: 0,
258
+ "&.pf-chatbot__settings-form-container": {
259
+ background: floatingBg,
260
+ padding: 0,
261
+ margin: 0,
262
+ minHeight: 0,
170
263
  flex: 1,
171
264
  display: "flex",
172
265
  flexDirection: "column",
173
- alignItems: "center",
174
- justifyContent: "center",
175
- textAlign: "center"
176
- },
177
- notebooksIcon: {
178
- fontSize: 48,
179
- color: "var(--pf-t--global--icon--color--subtle)",
180
- marginBottom: theme.spacing(1.5),
181
- "& > .pf-v6-icon-rh-ui": {
182
- display: "none !important"
183
- }
184
- },
185
- notebooksDescription: {
186
- marginTop: theme.spacing(1),
187
- marginBottom: theme.spacing(3),
188
- maxWidth: 420
189
- },
190
- notebooksAction: {
191
- textTransform: "none",
192
- borderRadius: 999,
193
- paddingLeft: theme.spacing(3),
194
- paddingRight: theme.spacing(3)
195
- },
196
- notebooksActionEmpty: {
197
- textTransform: "none",
198
- borderRadius: 999,
199
- paddingLeft: theme.spacing(3),
200
- paddingRight: theme.spacing(3),
201
- marginTop: theme.spacing(3)
202
- },
203
- notebooksGrid: {
204
- display: "grid",
205
- gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
206
- gap: theme.spacing(2),
207
- width: "100%",
208
- maxWidth: "100%",
209
- paddingBottom: theme.spacing(3),
210
- [theme.breakpoints.down("md")]: {
211
- gridTemplateColumns: "repeat(2, minmax(0, 1fr))"
212
- },
213
- [theme.breakpoints.down("sm")]: {
214
- gridTemplateColumns: "repeat(1, minmax(0, 1fr))"
215
- }
216
- },
217
- notebooksGridCompact: {
218
- display: "grid",
219
- gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
220
- gap: theme.spacing(2),
266
+ justifyContent: "flex-start",
221
267
  width: "100%",
222
- maxWidth: "100%",
223
- paddingBottom: theme.spacing(6)
224
- },
225
- notebookCard: {
226
- borderRadius: theme.spacing(1.5),
227
- display: "flex",
228
- flexDirection: "column",
229
- "&:hover": {
230
- borderColor: "var(--pf-t--global--border--color--hover)",
231
- borderWidth: "1px",
232
- borderStyle: "solid",
233
- cursor: "pointer"
234
- }
235
- },
236
- notebookCardHeader: {
237
- padding: theme.spacing(3),
238
- paddingBottom: 0,
239
- alignItems: "center"
240
- },
241
- notebookCardDivider: {
242
- borderTop: "1px solid var(--pf-t--global--border--color--default)",
243
- marginTop: theme.spacing(1)
244
- },
245
- notebookCardBody: {
246
- padding: theme.spacing(3),
247
- paddingTop: theme.spacing(2)
248
- },
249
- notebookDocuments: {
250
- paddingTop: theme.spacing(1)
251
- },
252
- notebookUpdated: {
253
- paddingBottom: theme.spacing(3),
254
- paddingTop: theme.spacing(2),
255
- fontStyle: "italic"
256
- },
257
- notebookTitle: {
258
- display: "flex",
259
- alignItems: "center",
260
- gap: theme.spacing(1),
261
- minWidth: 0,
262
- flex: 1
263
- },
264
- notebookCardHeaderActions: {
265
- marginLeft: theme.spacing(1)
266
- },
267
- notebookTitleText: {
268
+ maxWidth: "none",
268
269
  overflow: "hidden",
269
- textOverflow: "ellipsis",
270
- whiteSpace: "nowrap",
271
- cursor: "pointer",
272
- borderRadius: 4,
273
- padding: "2px 6px",
274
- "&:hover": {
275
- backgroundColor: "var(--pf-t--global--background--color--action--plain--hover)"
276
- }
277
- },
278
- notebookMenuButton: {
279
- color: theme.palette.text.secondary
280
- },
281
- notebookDropdownList: {
282
- paddingTop: 0,
283
- paddingBottom: 0,
284
- paddingInlineStart: 0
285
- },
286
- notebookDropdownMenu: {
287
- "--pf-v6-c-menu--PaddingBlockStart": "0",
288
- "--pf-v6-c-menu--PaddingBlockEnd": "0"
289
- },
290
- notebookDropdownItem: {
291
- justifyContent: "flex-start",
292
- textAlign: "left",
293
- paddingLeft: theme.spacing(0.5),
294
- paddingRight: theme.spacing(0.5)
270
+ border: "none"
295
271
  },
296
- footer: {
297
- "&.pf-chatbot__footer": {
298
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
299
- },
300
- "&>.pf-chatbot__footer-container": {
301
- width: "95% !important",
302
- maxWidth: "unset !important"
303
- },
304
- "& .pf-chatbot__message-bar": {
305
- backgroundColor: theme.palette.type === "light" ? theme.palette.grey[100] : "var(--pf-t--global--background--color--secondary--default)"
306
- },
307
- "& .pf-chatbot__button--stop, & .pf-chatbot__button--attach, & .pf-chatbot__button--send, & .pf-chatbot__button--microphone": {
308
- borderRadius: "var(--pf-t--global--border--radius--pill) !important"
309
- }
310
- },
311
- fullscreenFooter: {
312
- "&>.pf-chatbot__footer-container": {
313
- width: "100% !important",
314
- padding: `${theme.spacing(1.5)}px !important`,
315
- maxWidth: "unset !important",
316
- margin: "0 auto"
317
- }
318
- },
319
- messageBar: {
320
- border: "1px solid var(--pf-t--global--border--color--default)",
321
- borderRadius: 24,
322
- padding: theme.spacing(0.5),
323
- "&::after": {
324
- display: "none"
325
- }
326
- },
327
- sortDropdown: {
272
+ "& .pf-chatbot__settings-form": {
273
+ margin: 0,
328
274
  padding: 0,
329
- margin: 0
330
- },
331
- // Outer content wrapper (library may override overflow; we rely on inner scroll wrapper).
332
- chatbotContent: {
275
+ background: floatingBg,
333
276
  minHeight: 0,
277
+ flex: 1,
334
278
  display: "flex",
335
279
  flexDirection: "column",
336
- flex: 1,
337
- "& .pf-chatbot__jump": {
338
- left: "50% !important",
339
- right: "auto !important",
340
- transform: "translateX(-50%)",
341
- visibility: "hidden",
342
- pointerEvents: "none"
343
- },
344
- "& .pf-chatbot__message-contents": {
345
- overflowX: "hidden",
346
- overflowWrap: "break-word",
347
- wordBreak: "break-word"
348
- }
349
- },
350
- chatbotContentHasOverflow: {
351
- "& .pf-chatbot__jump": {
352
- visibility: "visible",
353
- pointerEvents: "auto"
354
- }
280
+ width: "100%",
281
+ maxWidth: "none",
282
+ border: "none"
355
283
  },
356
- // Inner scroll container we control: always scrollable so zoomed-in users see full content.
357
- chatbotContentScroll: {
284
+ "& .pf-chatbot__settings-form-row": {
285
+ background: floatingBg,
286
+ border: "none",
287
+ margin: 0,
288
+ padding: 0,
358
289
  minHeight: 0,
359
290
  flex: 1,
360
291
  display: "flex",
361
292
  flexDirection: "column",
362
- overflowY: "auto",
363
- WebkitOverflowScrolling: "touch"
364
- },
365
- chatbotContentScrollNewChat: {
366
- backgroundColor: "var(--pf-t--global--background--color--floating--default) !important"
293
+ width: "100%",
294
+ maxWidth: "none"
367
295
  },
368
- // When present, pushes welcome content to bottom (zoom out). Scroll up to see important box (zoom in).
369
- chatbotContentSpacer: {
296
+ "& .pf-chatbot__settings-label": {
297
+ display: "none"
298
+ }
299
+ });
300
+ const McpFullscreenLayout = styled("div")({
301
+ display: "grid",
302
+ gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1fr)",
303
+ minHeight: 0,
304
+ height: "100%",
305
+ flex: 1,
306
+ width: "100%",
307
+ minWidth: 0,
308
+ overflow: "hidden"
309
+ });
310
+ const McpChatPane = styled("div")({
311
+ display: "flex",
312
+ flexDirection: "column",
313
+ minHeight: 0,
314
+ width: "100%",
315
+ minWidth: 0,
316
+ whiteSpace: "normal",
317
+ wordBreak: "break-word",
318
+ overflowWrap: "break-word"
319
+ });
320
+ const McpSettingsPane = styled("div")(({ theme }) => ({
321
+ width: "100%",
322
+ minWidth: 0,
323
+ borderLeft: `1px solid ${theme.palette.divider}`,
324
+ backgroundColor: floatingBg,
325
+ display: "flex",
326
+ flexDirection: "column",
327
+ minHeight: 0,
328
+ overflow: "auto"
329
+ }));
330
+ const FullscreenChatLayout = styled("div")({
331
+ display: "flex",
332
+ flexDirection: "row",
333
+ flex: 1,
334
+ minHeight: 0,
335
+ height: "100%",
336
+ width: "100%",
337
+ "& .pf-v6-c-drawer, & .pf-v5-c-drawer": {
370
338
  flex: 1,
371
- minHeight: 0
339
+ minWidth: 0
372
340
  },
373
- settingsFlat: {
374
- height: "100%",
375
- width: "100%",
341
+ "& .pf-v6-c-drawer__content, & .pf-v5-c-drawer__content": {
376
342
  flex: 1,
377
- minHeight: 0,
378
- "&.pf-chatbot__settings-form-container": {
379
- background: "var(--pf-t--global--background--color--floating--default)",
380
- padding: 0,
381
- margin: 0,
382
- minHeight: 0,
383
- flex: 1,
384
- display: "flex",
385
- flexDirection: "column",
386
- justifyContent: "flex-start",
387
- width: "100%",
388
- maxWidth: "none",
389
- overflow: "hidden",
390
- border: "none"
391
- },
392
- "& .pf-chatbot__settings-form": {
393
- margin: 0,
394
- padding: 0,
395
- background: "var(--pf-t--global--background--color--floating--default)",
396
- minHeight: 0,
397
- flex: 1,
398
- display: "flex",
399
- flexDirection: "column",
400
- width: "100%",
401
- maxWidth: "none",
402
- border: "none"
403
- },
404
- "& .pf-chatbot__settings-form-row": {
405
- background: "var(--pf-t--global--background--color--floating--default)",
406
- border: "none",
407
- margin: 0,
408
- padding: 0,
409
- minHeight: 0,
410
- flex: 1,
411
- display: "flex",
412
- flexDirection: "column",
413
- width: "100%",
414
- maxWidth: "none"
415
- },
416
- "& .pf-chatbot__settings-label": {
417
- display: "none"
418
- }
343
+ minWidth: 0
419
344
  },
420
- mcpFullscreenLayout: {
421
- display: "grid",
422
- gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1fr)",
423
- minHeight: 0,
424
- height: "100%",
425
- flex: 1,
426
- width: "100%",
427
- minWidth: 0,
428
- overflow: "hidden"
345
+ "& .pf-v6-c-drawer:not(.pf-m-expanded) > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel, & .pf-v5-c-drawer:not(.pf-m-expanded) > .pf-v5-c-drawer__main > .pf-v5-c-drawer__panel": {
346
+ display: "none"
429
347
  },
430
- mcpChatPane: {
431
- display: "flex",
432
- flexDirection: "column",
433
- minHeight: 0,
434
- width: "100%",
435
- minWidth: 0,
436
- whiteSpace: "normal",
437
- wordBreak: "break-word",
438
- overflowWrap: "break-word"
348
+ "& .pf-v6-c-drawer__close, & .pf-v5-c-drawer__close": {
349
+ marginTop: 0,
350
+ marginRight: 0
439
351
  },
440
- mcpSettingsPane: {
441
- width: "100%",
442
- minWidth: 0,
443
- borderLeft: `1px solid ${theme.palette.divider}`,
444
- backgroundColor: "var(--pf-t--global--background--color--floating--default)",
445
- display: "flex",
446
- flexDirection: "column",
447
- minHeight: 0,
448
- overflow: "auto"
352
+ "& .pf-v6-c-drawer__head, & .pf-v5-c-drawer__head": {
353
+ paddingInlineStart: "var(--pf-t--global--spacer--lg)",
354
+ paddingInlineEnd: "var(--pf-t--global--spacer--lg)"
449
355
  },
450
- mcpCollapsedDrawerOrderFix: {
451
- "& .pf-v6-c-drawer.pf-m-panel-left > .pf-v6-c-drawer__main > .pf-v6-c-drawer__content, & .pf-v5-c-drawer.pf-m-panel-left > .pf-v5-c-drawer__main > .pf-v5-c-drawer__content": {
452
- order: "unset"
453
- },
454
- "& .pf-v6-c-drawer:not(.pf-m-expanded) > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel, & .pf-v5-c-drawer:not(.pf-m-expanded) > .pf-v5-c-drawer__main > .pf-v5-c-drawer__panel": {
455
- visibility: "hidden",
456
- opacity: 0,
457
- transition: "none !important"
458
- }
356
+ "& .pf-v6-c-drawer__close .pf-v6-c-button svg, & .pf-v5-c-drawer__close .pf-v5-c-button svg": {
357
+ display: "none"
459
358
  },
460
- // TODO: These PF Chatbot overrides are fragile (version-specific class names).
461
- // Remove once the upstream issues are addressed:
462
- // - https://github.com/patternfly/chatbot/issues/834 (custom close/collapse icon & positioning)
463
- // - https://github.com/patternfly/chatbot/issues/848 (sidebar padding & spacing customization)
464
- fullscreenChatLayout: {
359
+ "& .pf-v6-c-drawer__close .pf-v6-c-button, & .pf-v5-c-drawer__close .pf-v5-c-button": {
465
360
  display: "flex",
466
- flexDirection: "row",
467
- flex: 1,
468
- minHeight: 0,
469
- height: "100%",
470
- width: "100%",
471
- "& .pf-v6-c-drawer, & .pf-v5-c-drawer": {
472
- flex: 1,
473
- minWidth: 0
474
- },
475
- "& .pf-v6-c-drawer__content, & .pf-v5-c-drawer__content": {
476
- flex: 1,
477
- minWidth: 0
478
- },
479
- "& .pf-v6-c-drawer:not(.pf-m-expanded) > .pf-v6-c-drawer__main > .pf-v6-c-drawer__panel, & .pf-v5-c-drawer:not(.pf-m-expanded) > .pf-v5-c-drawer__main > .pf-v5-c-drawer__panel": {
480
- display: "none"
481
- },
482
- // TODO(#834): Remove close button overrides once PF supports custom icon/positioning
483
- "& .pf-v6-c-drawer__close, & .pf-v5-c-drawer__close": {
484
- marginTop: 0,
485
- marginRight: 0
486
- },
487
- // TODO(#848): Remove drawer head padding overrides once PF exposes drawerHeadProps
488
- "& .pf-v6-c-drawer__head, & .pf-v5-c-drawer__head": {
489
- paddingInlineStart: "var(--pf-t--global--spacer--lg)",
490
- paddingInlineEnd: "var(--pf-t--global--spacer--lg)"
491
- },
492
- // TODO(#834): Remove icon replacement hack once PF supports drawerCloseButtonProps.icon
493
- "& .pf-v6-c-drawer__close .pf-v6-c-button svg, & .pf-v5-c-drawer__close .pf-v5-c-button svg": {
494
- display: "none"
495
- },
496
- "& .pf-v6-c-drawer__close .pf-v6-c-button, & .pf-v5-c-drawer__close .pf-v5-c-button": {
497
- display: "flex",
498
- alignItems: "center",
499
- justifyContent: "center",
500
- "&::before": {
501
- content: '""',
502
- display: "block",
503
- width: 24,
504
- height: 24,
505
- mask: COLLAPSE_PANEL_ICON_SVG,
506
- WebkitMask: COLLAPSE_PANEL_ICON_SVG,
507
- backgroundColor: "currentColor"
508
- }
509
- },
510
- // TODO(#848): Remove heading padding overrides once PF exposes drawerHeadProps
511
- "& .pf-chatbot__heading-container": {
512
- paddingInlineStart: "var(--pf-t--global--spacer--lg)",
513
- paddingInlineEnd: "var(--pf-t--global--spacer--lg)"
514
- },
515
- // TODO(#848): Remove menu item padding overrides once PF exposes menuItemPaddingInline
516
- "& .pf-chatbot__menu-item-header > .pf-v6-c-menu__group-title": {
517
- "--pf-v6-c-menu__group-title--PaddingInlineStart": "var(--pf-t--global--spacer--md)",
518
- "--pf-v6-c-menu__group-title--PaddingInlineEnd": "var(--pf-t--global--spacer--md)"
519
- },
520
- "& .pf-chatbot__menu-item": {
521
- cursor: "pointer",
522
- "--pf-v6-c-menu__item--PaddingInlineStart": "var(--pf-t--global--spacer--md)",
523
- "--pf-v6-c-menu__item--PaddingInlineEnd": "var(--pf-t--global--spacer--md)"
524
- },
525
- // TODO(#848): Remove menu toggle hover hack once PF supports menuToggleVisibility
526
- "& .pf-chatbot__menu-item .pf-v6-c-menu-toggle, & .pf-chatbot__menu-item .pf-v5-c-menu-toggle": {
527
- opacity: 0,
528
- transition: "opacity 0.15s ease-in-out"
529
- },
530
- "& .pf-chatbot__menu-item:hover .pf-v6-c-menu-toggle, & .pf-chatbot__menu-item:hover .pf-v5-c-menu-toggle": {
531
- opacity: 1
361
+ alignItems: "center",
362
+ justifyContent: "center",
363
+ "&::before": {
364
+ content: '""',
365
+ display: "block",
366
+ width: 24,
367
+ height: 24,
368
+ mask: COLLAPSE_PANEL_ICON_SVG,
369
+ WebkitMask: COLLAPSE_PANEL_ICON_SVG,
370
+ backgroundColor: "currentColor"
532
371
  }
533
372
  },
534
- fullscreenMainContent: {
535
- display: "flex",
536
- flexDirection: "column",
537
- flex: 1,
538
- minHeight: 0,
539
- minWidth: 0,
540
- overflow: "hidden"
373
+ "& .pf-chatbot__heading-container": {
374
+ paddingInlineStart: "var(--pf-t--global--spacer--lg)",
375
+ paddingInlineEnd: "var(--pf-t--global--spacer--lg)"
376
+ },
377
+ "& .pf-chatbot__menu-item-header > .pf-v6-c-menu__group-title": {
378
+ "--pf-v6-c-menu__group-title--PaddingInlineStart": "var(--pf-t--global--spacer--md)",
379
+ "--pf-v6-c-menu__group-title--PaddingInlineEnd": "var(--pf-t--global--spacer--md)"
380
+ },
381
+ "& .pf-chatbot__menu-item": {
382
+ cursor: "pointer",
383
+ "--pf-v6-c-menu__item--PaddingInlineStart": "var(--pf-t--global--spacer--md)",
384
+ "--pf-v6-c-menu__item--PaddingInlineEnd": "var(--pf-t--global--spacer--md)"
385
+ },
386
+ "& .pf-chatbot__menu-item .pf-v6-c-menu-toggle, & .pf-chatbot__menu-item .pf-v5-c-menu-toggle": {
387
+ opacity: 0,
388
+ transition: "opacity 0.15s ease-in-out"
389
+ },
390
+ "& .pf-chatbot__menu-item:hover .pf-v6-c-menu-toggle, & .pf-chatbot__menu-item:hover .pf-v5-c-menu-toggle": {
391
+ opacity: 1
541
392
  }
542
- }));
393
+ });
543
394
  const LightspeedChat = ({
544
395
  selectedModel,
545
396
  topicRestrictionEnabled,
@@ -551,7 +402,6 @@ const LightspeedChat = ({
551
402
  models
552
403
  }) => {
553
404
  const isMobile = useIsMobile();
554
- const classes = useStyles();
555
405
  const { t } = useTranslation();
556
406
  const navigate = useNavigate();
557
407
  const configApi = useApi(configApiRef);
@@ -573,7 +423,6 @@ const LightspeedChat = ({
573
423
  const isOnNotebookRoute = Boolean(
574
424
  notebooksRouteMatch || notebookViewRouteMatch
575
425
  );
576
- const shouldShowTabs = notebooksEnabled || isOnNotebookRoute;
577
426
  const {
578
427
  displayMode,
579
428
  setDisplayMode,
@@ -606,13 +455,21 @@ const LightspeedChat = ({
606
455
  }
607
456
  return 0;
608
457
  });
609
- const {
610
- allowed: hasNotebooksAccess,
611
- loading: notebooksPermissionLoading,
612
- iaNotebooksPermissionName
613
- } = useLightspeedNotebooksPermission();
458
+ const { allowed: hasChatAccess, loading: chatPermissionLoading } = useIaChatPermission();
459
+ const chatPermissionResolved = !chatPermissionLoading && hasChatAccess;
460
+ const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } = useIaNotebooksPermission();
614
461
  const notebooksPermissionResolved = !notebooksPermissionLoading && hasNotebooksAccess;
615
- const { data: notebookConversationIdsArray = [] } = useNotebookConversationIds();
462
+ const canShowNotebooks = notebooksPermissionResolved && (notebooksEnabled || isOnNotebookRoute);
463
+ const hasChatTab = chatPermissionResolved;
464
+ const hasNotebooksTab = canShowNotebooks;
465
+ const hasBothTabs = hasChatTab && hasNotebooksTab;
466
+ const shouldShowTabs = hasBothTabs;
467
+ const selectedTabIndex = hasBothTabs ? activeTab : 0;
468
+ const { allowed: hasMcpToolsAccess, loading: mcpToolsPermissionLoading } = useIaMcpToolsPermission();
469
+ const mcpToolsPermissionResolved = !mcpToolsPermissionLoading && hasMcpToolsAccess;
470
+ const { data: notebookConversationIdsArray = [] } = useNotebookConversationIds(
471
+ chatPermissionResolved || notebooksPermissionResolved
472
+ );
616
473
  const { data: notebooks = [], refetch: refetchNotebooks } = useNotebookSessions(notebooksPermissionResolved);
617
474
  const hasNotebooks = notebooks.length > 0;
618
475
  const [openNotebookMenuId, setOpenNotebookMenuId] = useState(
@@ -666,31 +523,79 @@ const LightspeedChat = ({
666
523
  const [hasChatContentOverflow, setHasChatContentOverflow] = useState(false);
667
524
  const wasStoppedByUserRef = useRef(false);
668
525
  const { isReady, lastOpenedId, setLastOpenedId, clearLastOpenedId } = useLastOpenedConversation(user);
669
- const showChatPanel = activeTab === 0;
670
- const showNotebooksPanel = (notebooksEnabled || isOnNotebookRoute) && activeTab !== 0;
526
+ const showChatPanel = hasChatTab && (activeTab === 0 || !hasNotebooksTab);
527
+ const showNotebooksPanel = hasNotebooksTab && (activeTab === 1 || !hasChatTab);
671
528
  const [isChatHistoryDrawerOpen, setIsChatHistoryDrawerOpen] = useState(!isMobile && isFullscreenMode);
672
529
  useLayoutEffect(() => {
673
- if (!isFullscreenMode) {
530
+ if (!isFullscreenMode || chatPermissionLoading || notebooksPermissionLoading) {
674
531
  return;
675
532
  }
676
533
  if (isNotebooksFullscreenPath) {
534
+ if (canShowNotebooks) {
535
+ setActiveTab(1);
536
+ setShellViewTab(1);
537
+ } else if (chatPermissionResolved) {
538
+ navigate(
539
+ routeConversationId ? `${LIGHTSPEED_PATH}/conversation/${routeConversationId}` : LIGHTSPEED_PATH,
540
+ { replace: true }
541
+ );
542
+ setActiveTab(0);
543
+ setShellViewTab(0);
544
+ }
545
+ return;
546
+ }
547
+ const isBaseLightspeedChatRoute = location.pathname === LIGHTSPEED_PATH || location.pathname === `${LIGHTSPEED_PATH}/`;
548
+ const isConversationRoute = location.pathname.startsWith(
549
+ `${LIGHTSPEED_PATH}/conversation/`
550
+ );
551
+ if (!chatPermissionResolved && canShowNotebooks && (isBaseLightspeedChatRoute || isConversationRoute)) {
552
+ navigate(
553
+ activeNotebookId ? `${LIGHTSPEED_PATH}/notebooks/${activeNotebookId}` : `${LIGHTSPEED_PATH}/notebooks`,
554
+ { replace: true }
555
+ );
677
556
  setActiveTab(1);
678
557
  setShellViewTab(1);
679
558
  return;
680
559
  }
681
- const isBaseLightspeedChatRoute = location.pathname === LIGHTSPEED_PATH || location.pathname === `${LIGHTSPEED_PATH}/`;
682
- if (shellViewTab === 1 && isBaseLightspeedChatRoute) {
560
+ if (shellViewTab === 1 && isBaseLightspeedChatRoute && canShowNotebooks) {
683
561
  navigate(`${LIGHTSPEED_PATH}/notebooks`, { replace: true });
684
562
  return;
685
563
  }
686
- setActiveTab(0);
687
- setShellViewTab(0);
564
+ if (chatPermissionResolved) {
565
+ setActiveTab(0);
566
+ setShellViewTab(0);
567
+ }
688
568
  }, [
689
569
  isFullscreenMode,
690
570
  isNotebooksFullscreenPath,
691
571
  shellViewTab,
692
572
  location.pathname,
693
573
  navigate,
574
+ setShellViewTab,
575
+ chatPermissionLoading,
576
+ notebooksPermissionLoading,
577
+ chatPermissionResolved,
578
+ canShowNotebooks,
579
+ activeNotebookId,
580
+ routeConversationId
581
+ ]);
582
+ useEffect(() => {
583
+ if (chatPermissionLoading || notebooksPermissionLoading) {
584
+ return;
585
+ }
586
+ if (!chatPermissionResolved && canShowNotebooks && activeTab === 0) {
587
+ setActiveTab(1);
588
+ setShellViewTab(1);
589
+ } else if (chatPermissionResolved && !canShowNotebooks && activeTab !== 0) {
590
+ setActiveTab(0);
591
+ setShellViewTab(0);
592
+ }
593
+ }, [
594
+ chatPermissionLoading,
595
+ notebooksPermissionLoading,
596
+ chatPermissionResolved,
597
+ canShowNotebooks,
598
+ activeTab,
694
599
  setShellViewTab
695
600
  ]);
696
601
  const maybeAutoDeleteScratchNotebook = useCallback(() => {
@@ -713,13 +618,19 @@ const LightspeedChat = ({
713
618
  deleteNotebook
714
619
  ]);
715
620
  const handleNotebookTabSelect = (_event, nextTab) => {
716
- if (nextTab === 0) {
621
+ let logicalTab = 0;
622
+ if (hasBothTabs) {
623
+ logicalTab = nextTab;
624
+ } else if (hasNotebooksTab) {
625
+ logicalTab = 1;
626
+ }
627
+ if (logicalTab === 0) {
717
628
  maybeAutoDeleteScratchNotebook();
718
629
  }
719
- setActiveTab(nextTab);
720
- setShellViewTab(nextTab);
630
+ setActiveTab(logicalTab);
631
+ setShellViewTab(logicalTab);
721
632
  if (isFullscreenMode) {
722
- if (nextTab === 1) {
633
+ if (logicalTab === 1) {
723
634
  navigate(
724
635
  activeNotebookId ? `${LIGHTSPEED_PATH}/notebooks/${activeNotebookId}` : `${LIGHTSPEED_PATH}/notebooks`
725
636
  );
@@ -729,7 +640,7 @@ const LightspeedChat = ({
729
640
  );
730
641
  }
731
642
  }
732
- if (nextTab === 1 && notebooksPermissionResolved) {
643
+ if (logicalTab === 1 && notebooksPermissionResolved) {
733
644
  refetchNotebooks();
734
645
  }
735
646
  };
@@ -826,6 +737,11 @@ const LightspeedChat = ({
826
737
  setChatHeaderBgColor(computedBg);
827
738
  }
828
739
  }, [displayMode, isMcpSettingsOpen]);
740
+ useEffect(() => {
741
+ if (!mcpToolsPermissionResolved && isMcpSettingsOpen) {
742
+ setIsMcpSettingsOpen(false);
743
+ }
744
+ }, [mcpToolsPermissionResolved, isMcpSettingsOpen]);
829
745
  const {
830
746
  isPinningChatsEnabled,
831
747
  pinnedChats,
@@ -886,10 +802,8 @@ const LightspeedChat = ({
886
802
  data: conversations = [],
887
803
  isLoading,
888
804
  isRefetching
889
- } = useConversations();
890
- const { allowed: hasDeleteAccess } = useLightspeedDeletePermission();
891
- const { allowed: hasUpdateAccess } = useLightspeedUpdatePermission();
892
- const samplePrompts = useWelcomePrompts();
805
+ } = useConversations(chatPermissionResolved);
806
+ const samplePrompts = useWelcomePrompts(chatPermissionResolved);
893
807
  useEffect(() => {
894
808
  if (!user || !isReady) return;
895
809
  const onOverlayLikeSurface = isFullscreenMode || !routeConversationId;
@@ -1087,7 +1001,6 @@ const LightspeedChat = ({
1087
1001
  /* @__PURE__ */ jsx(
1088
1002
  DropdownItem,
1089
1003
  {
1090
- isDisabled: !hasUpdateAccess,
1091
1004
  icon: /* @__PURE__ */ jsx(PenIcon, {}),
1092
1005
  onClick: () => openChatRenameModal(conversationSummary.conversation_id),
1093
1006
  children: t("conversation.rename")
@@ -1111,7 +1024,6 @@ const LightspeedChat = ({
1111
1024
  /* @__PURE__ */ jsx(
1112
1025
  DropdownItem,
1113
1026
  {
1114
- isDisabled: !hasDeleteAccess,
1115
1027
  icon: /* @__PURE__ */ jsx(TrashIcon, {}),
1116
1028
  onClick: () => openDeleteModal(conversationSummary.conversation_id),
1117
1029
  children: t("conversation.delete")
@@ -1120,15 +1032,7 @@ const LightspeedChat = ({
1120
1032
  ] })
1121
1033
  };
1122
1034
  },
1123
- [
1124
- pinnedChats,
1125
- hasDeleteAccess,
1126
- isPinningChatsEnabled,
1127
- hasUpdateAccess,
1128
- t,
1129
- pinChat,
1130
- unpinChat
1131
- ]
1035
+ [pinnedChats, isPinningChatsEnabled, t, pinChat, unpinChat]
1132
1036
  );
1133
1037
  const notebookConversationIds = useMemo(
1134
1038
  () => new Set(notebookConversationIdsArray),
@@ -1165,7 +1069,7 @@ const LightspeedChat = ({
1165
1069
  const pinnedChatsKey = t("conversation.category.pinnedChats") || "Pinned chats";
1166
1070
  let isNoPinnedChatsSearchResults = false;
1167
1071
  let isNoRecentChatsSearchResults = false;
1168
- const filteredConversations = Object.entries(categorizedMessages).reduce(
1072
+ const filteredConversations2 = Object.entries(categorizedMessages).reduce(
1169
1073
  (acc, [key, items]) => {
1170
1074
  const filteredItems = items.filter(
1171
1075
  (item) => (item.text ?? "").toLocaleLowerCase("en-US").includes(targetValue.toLocaleLowerCase("en-US"))
@@ -1219,7 +1123,7 @@ const LightspeedChat = ({
1219
1123
  if (isNoPinnedChatsSearchResults && isNoRecentChatsSearchResults) {
1220
1124
  return {};
1221
1125
  }
1222
- return filteredConversations;
1126
+ return filteredConversations2;
1223
1127
  },
1224
1128
  [categorizedMessages, isPinningChatsEnabled, t]
1225
1129
  );
@@ -1410,6 +1314,30 @@ const LightspeedChat = ({
1410
1314
  const handleFilter = useCallback((value) => {
1411
1315
  setFilterValue(value);
1412
1316
  }, []);
1317
+ const onClearFilter = useCallback(() => {
1318
+ setFilterValue("");
1319
+ }, []);
1320
+ const searchInputProps = useMemo(
1321
+ () => ({
1322
+ value: filterValue,
1323
+ onClear: onClearFilter
1324
+ }),
1325
+ [filterValue, onClearFilter]
1326
+ );
1327
+ const filteredConversations = useMemo(
1328
+ () => filterConversations(filterValue),
1329
+ [filterConversations, filterValue]
1330
+ );
1331
+ const noResultsState = useMemo(() => {
1332
+ if (!filterValue || Object.keys(filteredConversations).length > 0) {
1333
+ return void 0;
1334
+ }
1335
+ return {
1336
+ bodyText: t("chatbox.emptyState.noResults.body"),
1337
+ titleText: t("chatbox.emptyState.noResults.title"),
1338
+ icon: SearchIcon
1339
+ };
1340
+ }, [filterValue, filteredConversations, t]);
1413
1341
  const onChatHistoryDrawerToggle = useCallback(() => {
1414
1342
  setIsChatHistoryDrawerOpen((isOpen) => !isOpen);
1415
1343
  }, []);
@@ -1461,7 +1389,7 @@ const LightspeedChat = ({
1461
1389
  popperProps: { position: "end" },
1462
1390
  toggle: sortToggle,
1463
1391
  shouldFocusToggleOnSelect: true,
1464
- children: /* @__PURE__ */ jsxs(SelectList, { className: classes.sortDropdown, children: [
1392
+ children: /* @__PURE__ */ jsxs(StyledSelectList, { children: [
1465
1393
  /* @__PURE__ */ jsx(SelectOption, { value: "newest", children: t("sort.newest") }),
1466
1394
  /* @__PURE__ */ jsx(SelectOption, { value: "oldest", children: t("sort.oldest") }),
1467
1395
  /* @__PURE__ */ jsx(SelectOption, { value: "alphabeticalAsc", children: t("sort.alphabeticalAsc") }),
@@ -1469,14 +1397,7 @@ const LightspeedChat = ({
1469
1397
  ] })
1470
1398
  }
1471
1399
  ),
1472
- [
1473
- isSortSelectOpen,
1474
- selectedSort,
1475
- onSortSelect,
1476
- sortToggle,
1477
- t,
1478
- classes.sortDropdown
1479
- ]
1400
+ [isSortSelectOpen, selectedSort, onSortSelect, sortToggle, t]
1480
1401
  );
1481
1402
  const handleAttach = (data, event) => {
1482
1403
  if ("preventDefault" in event && typeof event.preventDefault === "function") {
@@ -1515,103 +1436,90 @@ const LightspeedChat = ({
1515
1436
  });
1516
1437
  };
1517
1438
  const chatMainContent = /* @__PURE__ */ jsxs(Fragment, { children: [
1518
- /* @__PURE__ */ jsx(
1519
- ChatbotContent,
1439
+ /* @__PURE__ */ jsx(StyledChatbotContent, { hasOverflow: hasChatContentOverflow, children: /* @__PURE__ */ jsxs(
1440
+ ContentScroll,
1520
1441
  {
1521
- className: `${classes.chatbotContent} ${hasChatContentOverflow ? classes.chatbotContentHasOverflow : ""}`,
1522
- children: /* @__PURE__ */ jsxs(
1523
- "div",
1524
- {
1525
- ref: contentScrollRef,
1526
- className: `${classes.chatbotContentScroll}${welcomePrompts.length > 0 ? ` ${classes.chatbotContentScrollNewChat}` : ""}`,
1527
- children: [
1528
- welcomePrompts.length > 0 && /* @__PURE__ */ jsx("div", { className: classes.chatbotContentSpacer, "aria-hidden": true }),
1529
- /* @__PURE__ */ jsx(
1530
- LightspeedChatBox,
1531
- {
1532
- userName,
1533
- messages,
1534
- profileLoading,
1535
- announcement,
1536
- ref: scrollToBottomRef,
1537
- welcomePrompts,
1538
- conversationId,
1539
- isStreaming: streamingUiMatchesView,
1540
- topicRestrictionEnabled,
1541
- displayMode
1542
- }
1543
- ),
1544
- welcomePrompts.length > 0 && /* @__PURE__ */ jsx(
1545
- "div",
1546
- {
1547
- ref: bottomSentinelRef,
1548
- "aria-hidden": true,
1549
- style: { height: 0, flexShrink: 0 }
1550
- }
1551
- )
1552
- ]
1553
- }
1554
- )
1555
- }
1556
- ),
1557
- /* @__PURE__ */ jsxs(
1558
- ChatbotFooter,
1559
- {
1560
- className: `${classes.footer} ${classes.fullscreenFooter}`,
1442
+ ref: contentScrollRef,
1443
+ isNewChat: welcomePrompts.length > 0,
1561
1444
  children: [
1562
- /* @__PURE__ */ jsx(FilePreview, {}),
1445
+ welcomePrompts.length > 0 && /* @__PURE__ */ jsx(ContentSpacer, { "aria-hidden": true }),
1563
1446
  /* @__PURE__ */ jsx(
1564
- MessageBar,
1447
+ LightspeedChatBox,
1565
1448
  {
1566
- className: classes.messageBar,
1567
- onSendMessage: sendMessage,
1568
- isSendButtonDisabled,
1569
- hasAttachButton: true,
1570
- attachButtonPosition: "start",
1571
- handleAttach,
1572
- hasMicrophoneButton: true,
1573
- value: draftMessage,
1574
- onChange: handleDraftMessage,
1575
- hasStopButton: streamingUiMatchesView,
1576
- handleStopButton: streamingUiMatchesView ? handleStopButton : void 0,
1577
- buttonProps: {
1578
- attach: {
1579
- inputTestId: "attachment-input",
1580
- tooltipContent: t("tooltip.attach"),
1581
- "aria-label": t("tooltip.attach"),
1582
- icon: /* @__PURE__ */ jsx(PlusIcon, {})
1583
- },
1584
- microphone: {
1585
- tooltipContent: {
1586
- active: t("tooltip.microphone.active"),
1587
- inactive: t("tooltip.microphone.inactive")
1588
- }
1589
- },
1590
- send: {
1591
- tooltipContent: t("tooltip.send")
1592
- }
1593
- },
1594
- additionalActions: /* @__PURE__ */ jsx(
1595
- MessageBarModelSelector,
1596
- {
1597
- selectedModel,
1598
- models,
1599
- onSelect: handleSelectedModel,
1600
- disabled: isSendButtonDisabled || messages.length > 0,
1601
- disabledTooltip: t("modelSelector.disabledTooltip")
1602
- }
1603
- ),
1604
- forceMultilineLayout: true,
1605
- allowedFileTypes: supportedFileTypes,
1606
- onAttachRejected,
1607
- placeholder: t("chatbox.message.placeholder")
1608
- },
1609
- messageBarKey
1449
+ userName,
1450
+ messages,
1451
+ profileLoading,
1452
+ announcement,
1453
+ ref: scrollToBottomRef,
1454
+ welcomePrompts,
1455
+ conversationId,
1456
+ isStreaming: streamingUiMatchesView,
1457
+ topicRestrictionEnabled,
1458
+ displayMode
1459
+ }
1610
1460
  ),
1611
- /* @__PURE__ */ jsx(ChatbotFootnoteWithIcon, { ...getFootnoteProps(t) })
1461
+ welcomePrompts.length > 0 && /* @__PURE__ */ jsx(
1462
+ "div",
1463
+ {
1464
+ ref: bottomSentinelRef,
1465
+ "aria-hidden": true,
1466
+ style: { height: 0, flexShrink: 0 }
1467
+ }
1468
+ )
1612
1469
  ]
1613
1470
  }
1614
- )
1471
+ ) }),
1472
+ /* @__PURE__ */ jsxs(StyledChatbotFooter, { children: [
1473
+ /* @__PURE__ */ jsx(FilePreview, {}),
1474
+ /* @__PURE__ */ jsx(
1475
+ StyledMessageBar,
1476
+ {
1477
+ onSendMessage: sendMessage,
1478
+ isSendButtonDisabled,
1479
+ hasAttachButton: true,
1480
+ attachButtonPosition: "start",
1481
+ handleAttach,
1482
+ hasMicrophoneButton: true,
1483
+ value: draftMessage,
1484
+ onChange: handleDraftMessage,
1485
+ hasStopButton: streamingUiMatchesView,
1486
+ handleStopButton: streamingUiMatchesView ? handleStopButton : void 0,
1487
+ buttonProps: {
1488
+ attach: {
1489
+ inputTestId: "attachment-input",
1490
+ tooltipContent: t("tooltip.attach"),
1491
+ "aria-label": t("tooltip.attach"),
1492
+ icon: /* @__PURE__ */ jsx(PlusIcon, {})
1493
+ },
1494
+ microphone: {
1495
+ tooltipContent: {
1496
+ active: t("tooltip.microphone.active"),
1497
+ inactive: t("tooltip.microphone.inactive")
1498
+ }
1499
+ },
1500
+ send: {
1501
+ tooltipContent: t("tooltip.send")
1502
+ }
1503
+ },
1504
+ additionalActions: /* @__PURE__ */ jsx(
1505
+ MessageBarModelSelector,
1506
+ {
1507
+ selectedModel,
1508
+ models,
1509
+ onSelect: handleSelectedModel,
1510
+ disabled: isSendButtonDisabled || messages.length > 0,
1511
+ disabledTooltip: t("modelSelector.disabledTooltip")
1512
+ }
1513
+ ),
1514
+ forceMultilineLayout: true,
1515
+ allowedFileTypes: supportedFileTypes,
1516
+ onAttachRejected,
1517
+ placeholder: t("chatbox.message.placeholder")
1518
+ },
1519
+ messageBarKey
1520
+ ),
1521
+ /* @__PURE__ */ jsx(ChatbotFootnoteWithIcon, { ...getFootnoteProps(t) })
1522
+ ] })
1615
1523
  ] });
1616
1524
  const mcpSettingsPanel = /* @__PURE__ */ jsx(
1617
1525
  McpServersSettings,
@@ -1621,19 +1529,18 @@ const LightspeedChat = ({
1621
1529
  }
1622
1530
  );
1623
1531
  const mainPanelContent = (() => {
1624
- if (!isMcpSettingsOpen) {
1532
+ if (!isMcpSettingsOpen || !mcpToolsPermissionResolved) {
1625
1533
  return /* @__PURE__ */ jsx(Fragment, { children: chatMainContent });
1626
1534
  }
1627
1535
  if (isFullscreenMode) {
1628
- return /* @__PURE__ */ jsxs("div", { className: classes.mcpFullscreenLayout, children: [
1629
- /* @__PURE__ */ jsx("div", { className: classes.mcpChatPane, children: chatMainContent }),
1630
- /* @__PURE__ */ jsx("div", { className: classes.mcpSettingsPane, children: mcpSettingsPanel })
1536
+ return /* @__PURE__ */ jsxs(McpFullscreenLayout, { children: [
1537
+ /* @__PURE__ */ jsx(McpChatPane, { children: chatMainContent }),
1538
+ /* @__PURE__ */ jsx(McpSettingsPane, { children: mcpSettingsPanel })
1631
1539
  ] });
1632
1540
  }
1633
1541
  return /* @__PURE__ */ jsx(
1634
- Settings,
1542
+ FlatSettings,
1635
1543
  {
1636
- className: classes.settingsFlat,
1637
1544
  fields: [
1638
1545
  {
1639
1546
  id: "mcp-servers-settings",
@@ -1690,14 +1597,16 @@ const LightspeedChat = ({
1690
1597
  }
1691
1598
  ),
1692
1599
  /* @__PURE__ */ jsxs(
1693
- Chatbot,
1600
+ StyledChatbot,
1694
1601
  {
1695
1602
  displayMode: ChatbotDisplayMode.embedded,
1696
- className: `${classes.body} ${!isFullscreenMode ? classes.bodyCompact : ""} ${isMcpSettingsOpen && !isChatHistoryDrawerOpen ? classes.mcpCollapsedDrawerOrderFix : ""}`,
1603
+ isCompact: !isFullscreenMode,
1604
+ compactDrawerOpen: !isFullscreenMode && isChatHistoryDrawerOpen,
1605
+ mcpDrawerFix: isMcpSettingsOpen && !isChatHistoryDrawerOpen,
1697
1606
  children: [
1698
- /* @__PURE__ */ jsxs(ChatbotHeader, { className: classes.header, children: [
1607
+ /* @__PURE__ */ jsxs(StyledChatbotHeader, { children: [
1699
1608
  /* @__PURE__ */ jsxs(ChatbotHeaderMain, { children: [
1700
- showChatPanel && !isFullscreenMode && /* @__PURE__ */ jsxs("div", { className: classes.chatHeaderActions, children: [
1609
+ showChatPanel && !isFullscreenMode && /* @__PURE__ */ jsxs(HeaderActions, { children: [
1701
1610
  /* @__PURE__ */ jsx(
1702
1611
  Tooltip,
1703
1612
  {
@@ -1744,10 +1653,9 @@ const LightspeedChat = ({
1744
1653
  }
1745
1654
  )
1746
1655
  ] }),
1747
- !isFullscreenMode && showNotebooksPanel && activeNotebook && /* @__PURE__ */ jsx(
1656
+ !isFullscreenMode && showNotebooksPanel && activeNotebook && /* @__PURE__ */ jsx(HeaderActions, { children: /* @__PURE__ */ jsx(
1748
1657
  NotebookHeaderActions,
1749
1658
  {
1750
- className: classes.notebookHeaderActions,
1751
1659
  onClose: handleCloseNotebook,
1752
1660
  onOpenUploadModal: () => setNotebookUploadModalOpen(true),
1753
1661
  uploadsInProgress: notebookUploadsInProgress,
@@ -1755,17 +1663,16 @@ const LightspeedChat = ({
1755
1663
  sidebarCollapsed: notebookSidebarCollapsed,
1756
1664
  onSidebarCollapsedChange: setNotebookSidebarCollapsed
1757
1665
  }
1758
- ),
1666
+ ) }),
1759
1667
  isFullscreenMode && /* @__PURE__ */ jsxs(Fragment, { children: [
1760
1668
  /* @__PURE__ */ jsx(
1761
- RhUiAiExperienceIcon,
1669
+ HeaderLogo,
1762
1670
  {
1763
1671
  style: { width: "24px", height: "24px" },
1764
- "aria-label": t("icon.lightspeed.alt"),
1765
- className: classes.headerLogo
1672
+ "aria-label": t("icon.lightspeed.alt")
1766
1673
  }
1767
1674
  ),
1768
- /* @__PURE__ */ jsx(ChatbotHeaderTitle, { className: classes.headerTitle, children: /* @__PURE__ */ jsx(
1675
+ /* @__PURE__ */ jsx(StyledChatbotHeaderTitle, { children: /* @__PURE__ */ jsx(
1769
1676
  Title,
1770
1677
  {
1771
1678
  headingLevel: "h1",
@@ -1785,6 +1692,7 @@ const LightspeedChat = ({
1785
1692
  isPinningChatsEnabled,
1786
1693
  hideModelSelector: true,
1787
1694
  showChatTabOptions: !showNotebooksPanel,
1695
+ showMcpSettings: mcpToolsPermissionResolved,
1788
1696
  setDisplayMode: setDisplayModeFromHeader,
1789
1697
  displayMode,
1790
1698
  onPinnedChatsToggle: handlePinningChatsToggle,
@@ -1792,16 +1700,17 @@ const LightspeedChat = ({
1792
1700
  }
1793
1701
  )
1794
1702
  ] }),
1795
- (isFullscreenMode || shouldShowTabs) && /* @__PURE__ */ jsx("div", { className: classes.headerDivider }),
1703
+ /* @__PURE__ */ jsx(HeaderDivider, { "data-testid": "lightspeed-header-divider" }),
1796
1704
  shouldShowTabs && /* @__PURE__ */ jsxs(
1797
1705
  Tabs,
1798
1706
  {
1799
- value: activeTab,
1707
+ value: selectedTabIndex,
1800
1708
  onChange: handleNotebookTabSelect,
1801
1709
  "aria-label": t("tabs.ariaLabel"),
1802
1710
  variant: "standard",
1803
1711
  textColor: "primary",
1804
1712
  sx: (theme) => ({
1713
+ flexShrink: 0,
1805
1714
  backgroundColor: "var(--pf-t--global--background--color--floating--default)",
1806
1715
  borderBottom: "1px solid var(--pf-t--global--border--color--default)",
1807
1716
  minHeight: theme.spacing(6),
@@ -1811,6 +1720,7 @@ const LightspeedChat = ({
1811
1720
  gap: theme.spacing(2)
1812
1721
  },
1813
1722
  '& [role="tab"]': {
1723
+ minWidth: "auto",
1814
1724
  fontWeight: 700,
1815
1725
  textTransform: "none",
1816
1726
  opacity: 1,
@@ -1836,7 +1746,7 @@ const LightspeedChat = ({
1836
1746
  }
1837
1747
  }),
1838
1748
  children: [
1839
- /* @__PURE__ */ jsx(
1749
+ hasChatTab && /* @__PURE__ */ jsx(
1840
1750
  Tab,
1841
1751
  {
1842
1752
  disableRipple: true,
@@ -1844,213 +1754,171 @@ const LightspeedChat = ({
1844
1754
  "aria-label": t("tabs.chat")
1845
1755
  }
1846
1756
  ),
1847
- /* @__PURE__ */ jsx(
1757
+ hasNotebooksTab && /* @__PURE__ */ jsx(
1848
1758
  Tab,
1849
1759
  {
1850
1760
  disableRipple: true,
1851
- label: /* @__PURE__ */ jsxs(
1852
- "span",
1761
+ label: /* @__PURE__ */ jsxs(NotebooksTabLabel, { isCompact: !isFullscreenMode, children: [
1762
+ t("tabs.notebooks"),
1763
+ /* @__PURE__ */ jsx(
1764
+ Label,
1765
+ {
1766
+ color: "purple",
1767
+ isCompact: !isFullscreenMode,
1768
+ style: {
1769
+ alignSelf: "center",
1770
+ margin: 0,
1771
+ lineHeight: 1,
1772
+ flexShrink: 0
1773
+ },
1774
+ children: t("tabs.notebooks.devPreview")
1775
+ }
1776
+ )
1777
+ ] }),
1778
+ "aria-label": t("tabs.notebooks")
1779
+ }
1780
+ )
1781
+ ]
1782
+ }
1783
+ ),
1784
+ /* @__PURE__ */ jsxs(ChatMain, { children: [
1785
+ showChatPanel && chatPermissionResolved && /* @__PURE__ */ jsx(
1786
+ ConditionalWrapper,
1787
+ {
1788
+ condition: isFullscreenMode,
1789
+ wrapper: (children) => /* @__PURE__ */ jsxs(FullscreenChatLayout, { children: [
1790
+ !isChatHistoryDrawerOpen && /* @__PURE__ */ jsx(
1791
+ CollapsedHistoryStrip,
1792
+ {
1793
+ onExpand: () => setIsChatHistoryDrawerOpen(true),
1794
+ onNewChat,
1795
+ newChatDisabled: newChatCreated
1796
+ }
1797
+ ),
1798
+ children
1799
+ ] }),
1800
+ children: /* @__PURE__ */ jsx(
1801
+ ChatbotConversationHistoryNav,
1802
+ {
1803
+ drawerPanelContentProps: {
1804
+ isResizable: isFullscreenMode,
1805
+ hasNoBorder: !isFullscreenMode,
1806
+ style: drawerPanelStyle
1807
+ },
1808
+ reverseButtonOrder: true,
1809
+ displayMode: ChatbotDisplayMode.embedded,
1810
+ onDrawerToggle: onChatHistoryDrawerToggle,
1811
+ title: "",
1812
+ navTitleIcon: null,
1813
+ isDrawerOpen: isChatHistoryDrawerOpen,
1814
+ drawerCloseButtonProps: {
1815
+ "aria-label": t("aria.closeDrawerPanel")
1816
+ },
1817
+ setIsDrawerOpen: setIsChatHistoryDrawerOpen,
1818
+ activeItemId: viewConversationId,
1819
+ onSelectActiveItem,
1820
+ conversations: filteredConversations,
1821
+ onNewChat,
1822
+ newChatButtonText: t("button.newChat"),
1823
+ newChatButtonProps: {
1824
+ icon: /* @__PURE__ */ jsx(PenIcon, {}),
1825
+ isDisabled: newChatCreated
1826
+ },
1827
+ handleTextInputChange: handleFilter,
1828
+ searchInputPlaceholder: t("chatbox.search.placeholder"),
1829
+ searchInputAriaLabel: t("aria.search.placeholder"),
1830
+ searchInputProps,
1831
+ searchActionEnd: sortDropdown,
1832
+ noResultsState,
1833
+ drawerContent: /* @__PURE__ */ jsxs(
1834
+ ChatFileDropZone,
1853
1835
  {
1854
- style: {
1855
- display: "inline-flex",
1856
- alignItems: "center",
1857
- gap: 8
1858
- },
1836
+ onFileDrop: (e, data) => handleAttach(data, e),
1837
+ displayMode: ChatbotDisplayMode.embedded,
1838
+ infoText: t("chatbox.fileUpload.infoText"),
1839
+ allowedFileTypes: supportedFileTypes,
1840
+ onAttachRejected,
1859
1841
  children: [
1860
- t("tabs.notebooks"),
1861
- /* @__PURE__ */ jsx(
1862
- Label,
1842
+ showAlert && uploadError.message && /* @__PURE__ */ jsx(ErrorContainer, { children: /* @__PURE__ */ jsx(
1843
+ ChatbotAlert,
1863
1844
  {
1864
- color: "purple",
1865
- style: {
1866
- alignSelf: "center",
1867
- margin: 0,
1868
- lineHeight: 1
1869
- },
1870
- children: t("tabs.notebooks.devPreview")
1845
+ component: "h4",
1846
+ title: t("chatbox.fileUpload.failed"),
1847
+ variant: uploadError.type ?? "danger",
1848
+ isInline: true,
1849
+ onClose: () => setUploadError({ message: null }),
1850
+ children: uploadError.message
1871
1851
  }
1872
- )
1852
+ ) }),
1853
+ mainPanelContent
1873
1854
  ]
1874
1855
  }
1875
- ),
1876
- "aria-label": t("tabs.notebooks")
1856
+ )
1877
1857
  }
1878
1858
  )
1879
- ]
1880
- }
1881
- ),
1882
- showChatPanel && /* @__PURE__ */ jsx(
1883
- ConditionalWrapper,
1884
- {
1885
- condition: isFullscreenMode,
1886
- wrapper: (children) => /* @__PURE__ */ jsxs("div", { className: classes.fullscreenChatLayout, children: [
1887
- !isChatHistoryDrawerOpen && /* @__PURE__ */ jsx(
1888
- CollapsedHistoryStrip,
1859
+ }
1860
+ ),
1861
+ showNotebooksPanel && canShowNotebooks && activeNotebook && /* @__PURE__ */ jsx(
1862
+ NotebookView,
1863
+ {
1864
+ sessionId: activeNotebook.session_id,
1865
+ notebookName: activeNotebook.name,
1866
+ documents: notebookDocuments,
1867
+ isDocumentsFetching,
1868
+ metadata: activeNotebook.metadata,
1869
+ topicSummary: conversations.find(
1870
+ (c) => c.conversation_id === activeNotebook.metadata?.conversation_id
1871
+ )?.topic_summary ?? void 0,
1872
+ userName,
1873
+ avatar,
1874
+ profileLoading,
1875
+ topicRestrictionEnabled,
1876
+ onClose: handleCloseNotebook,
1877
+ isCompact: !isFullscreenMode,
1878
+ sidebarCollapsed: notebookSidebarCollapsed,
1879
+ onSidebarCollapsedChange: setNotebookSidebarCollapsed,
1880
+ isUploadModalOpen: notebookUploadModalOpen,
1881
+ onUploadModalOpenChange: setNotebookUploadModalOpen,
1882
+ onUploadsInProgressChange: setNotebookUploadsInProgress
1883
+ }
1884
+ ),
1885
+ showNotebooksPanel && canShowNotebooks && !activeNotebook && /* @__PURE__ */ jsx(
1886
+ "div",
1887
+ {
1888
+ style: {
1889
+ position: "relative",
1890
+ display: "flex",
1891
+ flexDirection: "column",
1892
+ flex: 1,
1893
+ minHeight: 0,
1894
+ overflow: "hidden"
1895
+ },
1896
+ children: /* @__PURE__ */ jsx(
1897
+ NotebooksTab,
1889
1898
  {
1890
- onExpand: () => setIsChatHistoryDrawerOpen(true),
1891
- onNewChat,
1892
- newChatDisabled: newChatCreated
1899
+ notebooks,
1900
+ hasNotebooks,
1901
+ isCompact: !isFullscreenMode,
1902
+ openNotebookMenuId,
1903
+ setOpenNotebookMenuId,
1904
+ onSelectNotebook: (notebook) => {
1905
+ maybeAutoDeleteScratchNotebook();
1906
+ setActiveNotebookId(notebook.session_id);
1907
+ if (isFullscreenMode) {
1908
+ navigate(
1909
+ `${LIGHTSPEED_PATH}/notebooks/${notebook.session_id}`
1910
+ );
1911
+ }
1912
+ },
1913
+ onRename: handleRenameNotebook,
1914
+ onDelete: setDeleteNotebookId,
1915
+ onCreateNotebook: handleCreateNotebook,
1916
+ t
1893
1917
  }
1894
- ),
1895
- children
1896
- ] }),
1897
- children: /* @__PURE__ */ jsx(
1898
- ChatbotConversationHistoryNav,
1899
- {
1900
- drawerPanelContentProps: {
1901
- isResizable: isFullscreenMode,
1902
- hasNoBorder: !isFullscreenMode,
1903
- style: drawerPanelStyle,
1904
- ...!isFullscreenMode && isChatHistoryDrawerOpen && {
1905
- className: classes.compactDrawerPanel
1906
- }
1907
- },
1908
- reverseButtonOrder: true,
1909
- displayMode: ChatbotDisplayMode.embedded,
1910
- onDrawerToggle: onChatHistoryDrawerToggle,
1911
- title: "",
1912
- navTitleIcon: null,
1913
- isDrawerOpen: isChatHistoryDrawerOpen,
1914
- drawerCloseButtonProps: {
1915
- "aria-label": t("aria.closeDrawerPanel")
1916
- },
1917
- setIsDrawerOpen: setIsChatHistoryDrawerOpen,
1918
- activeItemId: viewConversationId,
1919
- onSelectActiveItem,
1920
- conversations: filterConversations(filterValue),
1921
- onNewChat,
1922
- newChatButtonText: t("button.newChat"),
1923
- newChatButtonProps: {
1924
- icon: /* @__PURE__ */ jsx(PenIcon, {}),
1925
- isDisabled: newChatCreated
1926
- },
1927
- handleTextInputChange: handleFilter,
1928
- searchInputPlaceholder: t("chatbox.search.placeholder"),
1929
- searchInputAriaLabel: t("aria.search.placeholder"),
1930
- searchInputProps: {
1931
- value: filterValue,
1932
- onClear: () => {
1933
- setFilterValue("");
1934
- }
1935
- },
1936
- searchActionEnd: sortDropdown,
1937
- noResultsState: filterValue && Object.keys(filterConversations(filterValue)).length === 0 ? {
1938
- bodyText: t("chatbox.emptyState.noResults.body"),
1939
- titleText: t("chatbox.emptyState.noResults.title"),
1940
- icon: SearchIcon
1941
- } : void 0,
1942
- drawerContent: /* @__PURE__ */ jsxs(
1943
- FileDropZone,
1944
- {
1945
- className: classes.drawerFileDropZone,
1946
- onFileDrop: (e, data) => handleAttach(data, e),
1947
- displayMode: ChatbotDisplayMode.embedded,
1948
- infoText: t("chatbox.fileUpload.infoText"),
1949
- allowedFileTypes: supportedFileTypes,
1950
- onAttachRejected,
1951
- children: [
1952
- showAlert && uploadError.message && /* @__PURE__ */ jsx("div", { className: classes.errorContainer, children: /* @__PURE__ */ jsx(
1953
- ChatbotAlert,
1954
- {
1955
- component: "h4",
1956
- title: t("chatbox.fileUpload.failed"),
1957
- variant: uploadError.type ?? "danger",
1958
- isInline: true,
1959
- onClose: () => setUploadError({ message: null }),
1960
- children: uploadError.message
1961
- }
1962
- ) }),
1963
- mainPanelContent
1964
- ]
1965
- }
1966
- )
1967
- }
1968
- )
1969
- }
1970
- ),
1971
- showNotebooksPanel && !notebooksPermissionLoading && hasNotebooksAccess && activeNotebook && /* @__PURE__ */ jsx(
1972
- NotebookView,
1973
- {
1974
- sessionId: activeNotebook.session_id,
1975
- notebookName: activeNotebook.name,
1976
- documents: notebookDocuments,
1977
- isDocumentsFetching,
1978
- metadata: activeNotebook.metadata,
1979
- topicSummary: conversations.find(
1980
- (c) => c.conversation_id === activeNotebook.metadata?.conversation_id
1981
- )?.topic_summary ?? void 0,
1982
- userName,
1983
- avatar,
1984
- profileLoading,
1985
- topicRestrictionEnabled,
1986
- onClose: handleCloseNotebook,
1987
- isCompact: !isFullscreenMode,
1988
- sidebarCollapsed: notebookSidebarCollapsed,
1989
- onSidebarCollapsedChange: setNotebookSidebarCollapsed,
1990
- isUploadModalOpen: notebookUploadModalOpen,
1991
- onUploadModalOpenChange: setNotebookUploadModalOpen,
1992
- onUploadsInProgressChange: setNotebookUploadsInProgress
1993
- }
1994
- ),
1995
- showNotebooksPanel && !notebooksPermissionLoading && hasNotebooksAccess && !activeNotebook && /* @__PURE__ */ jsx(
1996
- "div",
1997
- {
1998
- style: {
1999
- position: "relative",
2000
- display: "flex",
2001
- flexDirection: "column",
2002
- flex: 1,
2003
- minHeight: 0,
2004
- overflow: "hidden"
2005
- },
2006
- children: /* @__PURE__ */ jsx(
2007
- NotebooksTab,
2008
- {
2009
- notebooks,
2010
- hasNotebooks,
2011
- classes: isFullscreenMode ? classes : {
2012
- ...classes,
2013
- notebooksGrid: classes.notebooksGridCompact
2014
- },
2015
- openNotebookMenuId,
2016
- setOpenNotebookMenuId,
2017
- onSelectNotebook: (notebook) => {
2018
- maybeAutoDeleteScratchNotebook();
2019
- setActiveNotebookId(notebook.session_id);
2020
- if (isFullscreenMode) {
2021
- navigate(
2022
- `${LIGHTSPEED_PATH}/notebooks/${notebook.session_id}`
2023
- );
2024
- }
2025
- },
2026
- onRename: handleRenameNotebook,
2027
- onDelete: setDeleteNotebookId,
2028
- onCreateNotebook: handleCreateNotebook,
2029
- t
2030
- }
2031
- )
2032
- }
2033
- ),
2034
- showNotebooksPanel && !notebooksPermissionLoading && !hasNotebooksAccess && /* @__PURE__ */ jsx(
2035
- PermissionRequiredState,
2036
- {
2037
- subject: t("permission.subject.notebooks"),
2038
- permissions: [iaNotebooksPermissionName],
2039
- action: /* @__PURE__ */ jsx(
2040
- Button$1,
2041
- {
2042
- variant: "outlined",
2043
- color: "primary",
2044
- style: { borderRadius: "20px" },
2045
- onClick: () => {
2046
- setActiveTab(0);
2047
- setShellViewTab(0);
2048
- },
2049
- children: t("permission.notebooks.goBack")
2050
- }
2051
- )
2052
- }
2053
- )
1918
+ )
1919
+ }
1920
+ )
1921
+ ] })
2054
1922
  ]
2055
1923
  }
2056
1924
  ),