@red-hat-developer-hub/backstage-plugin-lightspeed 1.4.0 → 2.0.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 (92) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +59 -0
  3. package/dist/alpha/LightspeedFAB.esm.js +69 -0
  4. package/dist/alpha/LightspeedFAB.esm.js.map +1 -0
  5. package/dist/alpha/LightspeedProvider.esm.js +6 -0
  6. package/dist/alpha/LightspeedProvider.esm.js.map +1 -0
  7. package/dist/alpha.d.ts +170 -1
  8. package/dist/alpha.esm.js +97 -1
  9. package/dist/alpha.esm.js.map +1 -1
  10. package/dist/api/LightspeedApiClient.esm.js +19 -0
  11. package/dist/api/LightspeedApiClient.esm.js.map +1 -1
  12. package/dist/api/NotebooksApiClient.esm.js +72 -0
  13. package/dist/api/NotebooksApiClient.esm.js.map +1 -0
  14. package/dist/api/api.esm.js.map +1 -1
  15. package/dist/api/notebooksApi.esm.js +10 -0
  16. package/dist/api/notebooksApi.esm.js.map +1 -0
  17. package/dist/components/DeleteModal.esm.js +2 -0
  18. package/dist/components/DeleteModal.esm.js.map +1 -1
  19. package/dist/components/LightSpeedChat.esm.js +714 -66
  20. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  21. package/dist/components/LightspeedChatBox.esm.js +18 -4
  22. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  23. package/dist/components/LightspeedChatBoxHeader.esm.js +59 -50
  24. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  25. package/dist/components/LightspeedChatContainer.esm.js +26 -2
  26. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  27. package/dist/components/LightspeedDrawerProvider.esm.js +12 -157
  28. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  29. package/dist/components/LightspeedFAB.esm.js +5 -4
  30. package/dist/components/LightspeedFAB.esm.js.map +1 -1
  31. package/dist/components/McpServersSettings.esm.js +932 -0
  32. package/dist/components/McpServersSettings.esm.js.map +1 -0
  33. package/dist/components/McpSettingsIcon.esm.js +26 -0
  34. package/dist/components/McpSettingsIcon.esm.js.map +1 -0
  35. package/dist/components/PermissionRequiredState.esm.js +18 -22
  36. package/dist/components/PermissionRequiredState.esm.js.map +1 -1
  37. package/dist/components/RenameConversationModal.esm.js +2 -2
  38. package/dist/components/RenameConversationModal.esm.js.map +1 -1
  39. package/dist/components/ToolCallContent.esm.js +14 -4
  40. package/dist/components/ToolCallContent.esm.js.map +1 -1
  41. package/dist/components/notebooks/DeleteNotebookModal.esm.js +143 -0
  42. package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -0
  43. package/dist/components/notebooks/NotebookCard.esm.js +96 -0
  44. package/dist/components/notebooks/NotebookCard.esm.js.map +1 -0
  45. package/dist/components/notebooks/NotebooksTab.esm.js +61 -0
  46. package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -0
  47. package/dist/components/notebooks/RenameNotebookModal.esm.js +187 -0
  48. package/dist/components/notebooks/RenameNotebookModal.esm.js.map +1 -0
  49. package/dist/const.esm.js +3 -1
  50. package/dist/const.esm.js.map +1 -1
  51. package/dist/hooks/notebooks/useDeleteNotebook.esm.js +19 -0
  52. package/dist/hooks/notebooks/useDeleteNotebook.esm.js.map +1 -0
  53. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js +15 -0
  54. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +1 -0
  55. package/dist/hooks/notebooks/useNotebookSessions.esm.js +18 -0
  56. package/dist/hooks/notebooks/useNotebookSessions.esm.js.map +1 -0
  57. package/dist/hooks/notebooks/useRenameNotebook.esm.js +19 -0
  58. package/dist/hooks/notebooks/useRenameNotebook.esm.js.map +1 -0
  59. package/dist/hooks/useConversationMessages.esm.js +136 -36
  60. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  61. package/dist/hooks/useConversations.esm.js +6 -0
  62. package/dist/hooks/useConversations.esm.js.map +1 -1
  63. package/dist/hooks/useCreateCoversationMessage.esm.js.map +1 -1
  64. package/dist/hooks/useLightspeedProviderState.esm.js +205 -0
  65. package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -0
  66. package/dist/hooks/useStopConversation.esm.js +18 -0
  67. package/dist/hooks/useStopConversation.esm.js.map +1 -0
  68. package/dist/hooks/useWelcomePrompts.esm.js +2 -2
  69. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  70. package/dist/index.d.ts +31 -31
  71. package/dist/plugin.esm.js +10 -0
  72. package/dist/plugin.esm.js.map +1 -1
  73. package/dist/translations/de.esm.js +78 -0
  74. package/dist/translations/de.esm.js.map +1 -1
  75. package/dist/translations/es.esm.js +78 -0
  76. package/dist/translations/es.esm.js.map +1 -1
  77. package/dist/translations/fr.esm.js +64 -1
  78. package/dist/translations/fr.esm.js.map +1 -1
  79. package/dist/translations/it.esm.js +66 -1
  80. package/dist/translations/it.esm.js.map +1 -1
  81. package/dist/translations/ja.esm.js +66 -1
  82. package/dist/translations/ja.esm.js.map +1 -1
  83. package/dist/translations/ref.esm.js +65 -1
  84. package/dist/translations/ref.esm.js.map +1 -1
  85. package/dist/types.esm.js.map +1 -1
  86. package/dist/utils/formatToolResponseForMarkdown.esm.js +46 -0
  87. package/dist/utils/formatToolResponseForMarkdown.esm.js.map +1 -0
  88. package/dist/utils/lightspeed-chatbox-utils.esm.js +7 -3
  89. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  90. package/dist/utils/notebooks-utils.esm.js +25 -0
  91. package/dist/utils/notebooks-utils.esm.js.map +1 -0
  92. package/package.json +20 -12
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useMemo, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n} from '@patternfly/react-icons';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype LightspeedChatBoxHeaderProps = {\n displayMode: ChatbotDisplayMode;\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string; provider: string }[];\n isPinningChatsEnabled: boolean;\n onPinnedChatsToggle: (state: boolean) => void;\n isModelSelectorDisabled?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst useStyles = makeStyles(theme =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n header: {\n backgroundColor: theme.palette.action.disabled,\n },\n optionsToggle: {\n '& svg': {\n transform: 'none !important',\n },\n },\n groupTitle: {\n fontWeight: 'bold',\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n isModelSelectorDisabled = false,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n // Group models by provider\n const groupedModels = useMemo(() => {\n const groups: {\n [key: string]: { label: string; value: string; provider: string }[];\n } = {};\n\n models.forEach(model => {\n const provider = model.provider || t('chatbox.provider.other');\n if (!groups[provider]) {\n groups[provider] = [];\n }\n groups[provider].push(model);\n });\n\n return groups;\n }, [models, t]);\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n className={isModelSelectorDisabled ? styles.header : ''}\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n isDisabled={isModelSelectorDisabled}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n const handlePinningChatsToggle = (state: boolean) => {\n onPinnedChatsToggle(state);\n };\n\n const handleDockedToWindow = () => {\n setDisplayMode(ChatbotDisplayMode.docked);\n };\n\n const handleFullscreen = () => {\n setDisplayMode(ChatbotDisplayMode.embedded);\n };\n\n const handleOverlay = () => {\n setDisplayMode(ChatbotDisplayMode.default);\n };\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n >\n <DropdownList>\n {Object.entries(groupedModels).map(\n ([provider, providerModels], index) => (\n <>\n <DropdownGroup\n className={styles.groupTitle}\n key={provider}\n label={provider}\n labelHeadingLevel=\"h1\"\n >\n {providerModels.map(model => (\n <DropdownItem value={model.value} key={model.value}>\n {model.label}\n </DropdownItem>\n ))}\n </DropdownGroup>\n {index < Object.entries(groupedModels).length - 1 && (\n <Divider component=\"li\" />\n )}\n </>\n ),\n )}\n </DropdownList>\n </Dropdown>\n <ChatbotHeaderOptionsDropdown\n isCompact\n toggleProps={{\n 'aria-label': t('aria.settings.label'),\n className: styles.optionsToggle,\n }}\n tooltipProps={{\n content: t('tooltip.settings'),\n }}\n >\n <DropdownGroup>\n <DropdownList>\n <DropdownItem key=\"displayModeLabel\" isDisabled>\n {t('settings.displayMode.label')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.default}\n key=\"switchDisplayOverlay\"\n icon={<OutlinedWindowRestoreIcon />}\n onClick={handleOverlay}\n isSelected={displayMode === ChatbotDisplayMode.default}\n >\n {t('settings.displayMode.overlay')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.docked}\n key=\"switchDisplayDock\"\n icon={<OpenDrawerRightIcon />}\n onClick={handleDockedToWindow}\n isSelected={displayMode === ChatbotDisplayMode.docked}\n >\n {t('settings.displayMode.docked')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.embedded}\n key=\"switchDisplayFullscreen\"\n icon={<ExpandIcon />}\n onClick={handleFullscreen}\n isSelected={displayMode === ChatbotDisplayMode.embedded}\n >\n {t('settings.displayMode.fullscreen')}\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n <Divider />\n <DropdownGroup>\n <DropdownList>\n {isPinningChatsEnabled ? (\n <DropdownItem\n value=\"disablePinningChats\"\n key=\"disablePinningChat\"\n icon={<ToggleOnOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.enabled.description')}\n onClick={() => handlePinningChatsToggle(false)}\n >\n {t('settings.pinned.disable')}\n </DropdownItem>\n ) : (\n <DropdownItem\n value=\"enablePinningChats\"\n key=\"enablePinningChats\"\n icon={<ToggleOffOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.disabled.description')}\n onClick={() => handlePinningChatsToggle(true)}\n >\n {t('settings.pinned.enable')}\n </DropdownItem>\n )}\n </DropdownList>\n </DropdownGroup>\n </ChatbotHeaderOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n} from '@patternfly/react-icons';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { McpSettingsIcon } from './McpSettingsIcon';\n\ntype LightspeedChatBoxHeaderProps = {\n displayMode: ChatbotDisplayMode;\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string; provider: string }[];\n isPinningChatsEnabled: boolean;\n onPinnedChatsToggle: (state: boolean) => void;\n onMcpSettingsClick: () => void;\n isModelSelectorDisabled?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst useStyles = makeStyles(theme =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n header: {\n backgroundColor: theme.palette.action.disabled,\n },\n optionsToggle: {\n '& svg': {\n transform: 'none !important',\n },\n },\n groupTitle: {\n fontWeight: 'bold',\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n onMcpSettingsClick,\n isModelSelectorDisabled = false,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n const maxLabelLength = Math.max(\n ...models.map(m => m.label.length),\n selectedModel.length,\n 1,\n );\n const toggleMinWidth = `${maxLabelLength + 4}ch`;\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n className={isModelSelectorDisabled ? styles.header : ''}\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n isDisabled={isModelSelectorDisabled}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n style={{ minWidth: toggleMinWidth }}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n const handlePinningChatsToggle = (state: boolean) => {\n onPinnedChatsToggle(state);\n };\n\n const handleDockedToWindow = () => {\n setDisplayMode(ChatbotDisplayMode.docked);\n };\n\n const handleFullscreen = () => {\n setDisplayMode(ChatbotDisplayMode.embedded);\n };\n\n const handleOverlay = () => {\n setDisplayMode(ChatbotDisplayMode.default);\n };\n\n const isOverlayMode = displayMode === ChatbotDisplayMode.default;\n const scrollThreshold = isOverlayMode ? 8 : 10;\n const isModelDropdownScrollable = models.length > scrollThreshold;\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n isScrollable={isModelDropdownScrollable}\n maxMenuHeight={isModelDropdownScrollable ? '240px' : undefined}\n >\n <DropdownList>\n {models.map(model => (\n <DropdownGroup className={styles.groupTitle} key={model.label}>\n <DropdownItem\n value={model.value}\n key={model.value}\n isSelected={selectedModel === model.value}\n >\n {model.label}\n </DropdownItem>\n </DropdownGroup>\n ))}\n </DropdownList>\n </Dropdown>\n <ChatbotHeaderOptionsDropdown\n isCompact\n toggleProps={{\n 'aria-label': t('aria.settings.label'),\n className: styles.optionsToggle,\n }}\n tooltipProps={{\n content: t('tooltip.settings'),\n }}\n >\n <DropdownGroup>\n <DropdownList>\n <DropdownItem key=\"displayModeLabel\" isDisabled>\n {t('settings.displayMode.label')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.default}\n key=\"switchDisplayOverlay\"\n icon={<OutlinedWindowRestoreIcon />}\n onClick={handleOverlay}\n isSelected={displayMode === ChatbotDisplayMode.default}\n >\n {t('settings.displayMode.overlay')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.docked}\n key=\"switchDisplayDock\"\n icon={<OpenDrawerRightIcon />}\n onClick={handleDockedToWindow}\n isSelected={displayMode === ChatbotDisplayMode.docked}\n >\n {t('settings.displayMode.docked')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.embedded}\n key=\"switchDisplayFullscreen\"\n icon={<ExpandIcon />}\n onClick={handleFullscreen}\n isSelected={displayMode === ChatbotDisplayMode.embedded}\n >\n {t('settings.displayMode.fullscreen')}\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n <Divider />\n <DropdownGroup>\n <DropdownList>\n {isPinningChatsEnabled ? (\n <DropdownItem\n value=\"disablePinningChats\"\n key=\"disablePinningChat\"\n icon={<ToggleOnOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.enabled.description')}\n onClick={() => handlePinningChatsToggle(false)}\n >\n {t('settings.pinned.disable')}\n </DropdownItem>\n ) : (\n <DropdownItem\n value=\"enablePinningChats\"\n key=\"enablePinningChats\"\n icon={<ToggleOffOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.disabled.description')}\n onClick={() => handlePinningChatsToggle(true)}\n >\n {t('settings.pinned.enable')}\n </DropdownItem>\n )}\n <DropdownItem\n value=\"mcpSettings\"\n key=\"mcpSettings\"\n icon={<McpSettingsIcon />}\n onClick={onMcpSettingsClick}\n >\n {t('settings.mcp.label')}\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n </ChatbotHeaderOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,12 +1,15 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useState, useMemo, useEffect } from 'react';
3
3
  import { useAsync } from 'react-use';
4
4
  import { useApi, identityApiRef } from '@backstage/core-plugin-api';
5
+ import { Button } from '@material-ui/core';
5
6
  import { useTheme } from '@material-ui/core/styles';
7
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
6
8
  import { QueryClientProvider } from '@tanstack/react-query';
7
9
  import { useAllModels } from '../hooks/useAllModels.esm.js';
8
10
  import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
9
11
  import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
12
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
10
13
  import queryClient from '../utils/queryClient.esm.js';
11
14
  import FileAttachmentContextProvider from './AttachmentContext.esm.js';
12
15
  import { LightspeedChat } from './LightSpeedChat.esm.js';
@@ -19,6 +22,7 @@ const LightspeedChatContainerInner = () => {
19
22
  const {
20
23
  palette: { type }
21
24
  } = useTheme();
25
+ const { t } = useTranslation();
22
26
  const identityApi = useApi(identityApiRef);
23
27
  const { data: models } = useAllModels();
24
28
  const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();
@@ -89,7 +93,27 @@ const LightspeedChatContainerInner = () => {
89
93
  return null;
90
94
  }
91
95
  if (!hasViewAccess) {
92
- return /* @__PURE__ */ jsx(PermissionRequiredState, {});
96
+ return /* @__PURE__ */ jsx(
97
+ PermissionRequiredState,
98
+ {
99
+ subject: t("permission.subject.plugin"),
100
+ permissions: ["lightspeed.chat.read", "lightspeed.chat.create"],
101
+ action: /* @__PURE__ */ jsxs(
102
+ Button,
103
+ {
104
+ variant: "outlined",
105
+ color: "primary",
106
+ target: "_blank",
107
+ href: "https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support",
108
+ children: [
109
+ t("common.readMore"),
110
+ " \xA0 ",
111
+ /* @__PURE__ */ jsx(OpenInNewIcon, {})
112
+ ]
113
+ }
114
+ )
115
+ }
116
+ );
93
117
  }
94
118
  return /* @__PURE__ */ jsx(FileAttachmentContextProvider, { children: /* @__PURE__ */ jsx(
95
119
  LightspeedChat,
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatContainer.esm.js","sources":["../../src/components/LightspeedChatContainer.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\nconst LAST_SELECTED_MODEL_KEY = 'lastSelectedModel';\n\n/**\n * Inner component that contains all the Lightspeed chat rendering logic\n */\nconst LightspeedChatContainerInner = () => {\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n const [selectedProvider, setSelectedProvider] = useState('');\n\n const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();\n\n const modelsItems = useMemo(\n () =>\n models\n ? models\n .filter(model => model.model_type === 'llm')\n .map(m => ({\n label: m.provider_resource_id,\n value: m.provider_resource_id,\n provider: m.provider_id,\n }))\n : [],\n [models],\n );\n\n // Handle dark theme class on document\n useEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [type]);\n\n // Load last selected model from localStorage\n useEffect(() => {\n if (modelsItems.length > 0) {\n try {\n const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);\n const parsedData = storedData ? JSON.parse(storedData) : null;\n\n const storedModel = parsedData?.model\n ? modelsItems.find(m => m.value === parsedData.model)\n : null;\n\n if (storedModel) {\n setSelectedModel(storedModel.value);\n setSelectedProvider(storedModel.provider);\n } else {\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error loading last selected model from localStorage:',\n error,\n );\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n }\n }, [modelsItems]);\n\n // Save selected model to localStorage\n useEffect(() => {\n if (selectedModel && selectedProvider) {\n try {\n localStorage.setItem(\n LAST_SELECTED_MODEL_KEY,\n JSON.stringify({\n model: selectedModel,\n provider: selectedProvider,\n }),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error saving last selected model to localStorage:',\n error,\n );\n }\n }\n }, [selectedModel, selectedProvider]);\n\n if (loading) {\n return null;\n }\n\n if (!hasViewAccess) {\n return <PermissionRequiredState />;\n }\n\n return (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n selectedProvider={selectedProvider}\n topicRestrictionEnabled={topicRestrictionEnabled ?? false}\n handleSelectedModel={item => {\n setSelectedModel(item);\n setSelectedProvider(\n modelsItems.find((m: any) => m.value === item)?.provider || '',\n );\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n );\n};\n\n/**\n * @public\n */\nexport const LightspeedChatContainer = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedChatContainerInner />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAgCA,MAAM,UAAa,GAAA,MAAA;AACnB,MAAM,gBAAmB,GAAA,kBAAA;AACzB,MAAM,uBAA0B,GAAA,mBAAA;AAKhC,MAAM,+BAA+B,MAAM;AACzC,EAAM,MAAA;AAAA,IACJ,OAAA,EAAS,EAAE,IAAK;AAAA,MACd,QAAS,EAAA;AAEb,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AAEzC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAO,EAAA,GAAI,YAAa,EAAA;AAEtC,EAAA,MAAM,EAAE,OAAA,EAAS,aAAe,EAAA,OAAA,KAAY,2BAA4B,EAAA;AAExE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAmB,GAAA,QAAA;AAAA,IAClD,YAAY,MAAM,WAAA,CAAY,cAAe;AAAA,GAC/C;AAEA,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,EAAE,CAAA;AACrD,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,EAAE,CAAA;AAE3D,EAAA,MAAM,EAAE,IAAA,EAAM,uBAAwB,EAAA,GAAI,yBAA0B,EAAA;AAEpE,EAAA,MAAM,WAAc,GAAA,OAAA;AAAA,IAClB,MACE,MACI,GAAA,MAAA,CACG,MAAO,CAAA,CAAA,KAAA,KAAS,MAAM,UAAe,KAAA,KAAK,CAC1C,CAAA,GAAA,CAAI,CAAM,CAAA,MAAA;AAAA,MACT,OAAO,CAAE,CAAA,oBAAA;AAAA,MACT,OAAO,CAAE,CAAA,oBAAA;AAAA,MACT,UAAU,CAAE,CAAA;AAAA,KACd,CAAE,IACJ,EAAC;AAAA,IACP,CAAC,MAAM;AAAA,GACT;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,iBAAiB,QAAS,CAAA,eAAA;AAChC,IAAA,IAAI,SAAS,UAAY,EAAA;AACvB,MAAe,cAAA,CAAA,SAAA,CAAU,IAAI,gBAAgB,CAAA;AAAA,KACxC,MAAA;AACL,MAAe,cAAA,CAAA,SAAA,CAAU,OAAO,gBAAgB,CAAA;AAAA;AAClD,GACF,EAAG,CAAC,IAAI,CAAC,CAAA;AAGT,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,WAAA,CAAY,SAAS,CAAG,EAAA;AAC1B,MAAI,IAAA;AACF,QAAM,MAAA,UAAA,GAAa,YAAa,CAAA,OAAA,CAAQ,uBAAuB,CAAA;AAC/D,QAAA,MAAM,UAAa,GAAA,UAAA,GAAa,IAAK,CAAA,KAAA,CAAM,UAAU,CAAI,GAAA,IAAA;AAEzD,QAAM,MAAA,WAAA,GAAc,UAAY,EAAA,KAAA,GAC5B,WAAY,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,KAAA,KAAU,UAAW,CAAA,KAAK,CAClD,GAAA,IAAA;AAEJ,QAAA,IAAI,WAAa,EAAA;AACf,UAAA,gBAAA,CAAiB,YAAY,KAAK,CAAA;AAClC,UAAA,mBAAA,CAAoB,YAAY,QAAQ,CAAA;AAAA,SACnC,MAAA;AACL,UAAiB,gBAAA,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,KAAK,CAAA;AACrC,UAAoB,mBAAA,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,QAAQ,CAAA;AAAA;AAC7C,eACO,KAAO,EAAA;AAEd,QAAQ,OAAA,CAAA,KAAA;AAAA,UACN,sDAAA;AAAA,UACA;AAAA,SACF;AACA,QAAiB,gBAAA,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,KAAK,CAAA;AACrC,QAAoB,mBAAA,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,QAAQ,CAAA;AAAA;AAC7C;AACF,GACF,EAAG,CAAC,WAAW,CAAC,CAAA;AAGhB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,iBAAiB,gBAAkB,EAAA;AACrC,MAAI,IAAA;AACF,QAAa,YAAA,CAAA,OAAA;AAAA,UACX,uBAAA;AAAA,UACA,KAAK,SAAU,CAAA;AAAA,YACb,KAAO,EAAA,aAAA;AAAA,YACP,QAAU,EAAA;AAAA,WACX;AAAA,SACH;AAAA,eACO,KAAO,EAAA;AAEd,QAAQ,OAAA,CAAA,KAAA;AAAA,UACN,mDAAA;AAAA,UACA;AAAA,SACF;AAAA;AACF;AACF,GACC,EAAA,CAAC,aAAe,EAAA,gBAAgB,CAAC,CAAA;AAEpC,EAAA,IAAI,OAAS,EAAA;AACX,IAAO,OAAA,IAAA;AAAA;AAGT,EAAA,IAAI,CAAC,aAAe,EAAA;AAClB,IAAA,2BAAQ,uBAAwB,EAAA,EAAA,CAAA;AAAA;AAGlC,EAAA,2BACG,6BACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,yBAAyB,uBAA2B,IAAA,KAAA;AAAA,MACpD,qBAAqB,CAAQ,IAAA,KAAA;AAC3B,QAAA,gBAAA,CAAiB,IAAI,CAAA;AACrB,QAAA,mBAAA;AAAA,UACE,WAAA,CAAY,KAAK,CAAC,CAAA,KAAW,EAAE,KAAU,KAAA,IAAI,GAAG,QAAY,IAAA;AAAA,SAC9D;AAAA,OACF;AAAA,MACA,MAAQ,EAAA,WAAA;AAAA,MACR,UAAU,OAAS,EAAA,WAAA;AAAA,MACnB,QAAQ,OAAS,EAAA,OAAA;AAAA,MACjB;AAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ,CAAA;AAKO,MAAM,0BAA0B,MAAM;AAC3C,EAAA,2BACG,mBAAoB,EAAA,EAAA,MAAA,EAAQ,WAC3B,EAAA,QAAA,kBAAA,GAAA,CAAC,gCAA6B,CAChC,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"LightspeedChatContainer.esm.js","sources":["../../src/components/LightspeedChatContainer.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { Button } from '@material-ui/core';\nimport { useTheme } from '@material-ui/core/styles';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport { useTranslation } from '../hooks/useTranslation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\nconst LAST_SELECTED_MODEL_KEY = 'lastSelectedModel';\n\n/**\n * Inner component that contains all the Lightspeed chat rendering logic\n */\nconst LightspeedChatContainerInner = () => {\n const {\n palette: { type },\n } = useTheme();\n const { t } = useTranslation();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n const [selectedProvider, setSelectedProvider] = useState('');\n\n const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();\n\n const modelsItems = useMemo(\n () =>\n models\n ? models\n .filter(model => model.model_type === 'llm')\n .map(m => ({\n label: m.provider_resource_id,\n value: m.provider_resource_id,\n provider: m.provider_id,\n }))\n : [],\n [models],\n );\n\n // Handle dark theme class on document\n useEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [type]);\n\n // Load last selected model from localStorage\n useEffect(() => {\n if (modelsItems.length > 0) {\n try {\n const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);\n const parsedData = storedData ? JSON.parse(storedData) : null;\n\n const storedModel = parsedData?.model\n ? modelsItems.find(m => m.value === parsedData.model)\n : null;\n\n if (storedModel) {\n setSelectedModel(storedModel.value);\n setSelectedProvider(storedModel.provider);\n } else {\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error loading last selected model from localStorage:',\n error,\n );\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n }\n }, [modelsItems]);\n\n // Save selected model to localStorage\n useEffect(() => {\n if (selectedModel && selectedProvider) {\n try {\n localStorage.setItem(\n LAST_SELECTED_MODEL_KEY,\n JSON.stringify({\n model: selectedModel,\n provider: selectedProvider,\n }),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error saving last selected model to localStorage:',\n error,\n );\n }\n }\n }, [selectedModel, selectedProvider]);\n\n if (loading) {\n return null;\n }\n\n if (!hasViewAccess) {\n return (\n <PermissionRequiredState\n subject={t('permission.subject.plugin')}\n permissions={['lightspeed.chat.read', 'lightspeed.chat.create']}\n action={\n <Button\n variant=\"outlined\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support\"\n >\n {t('common.readMore')} &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n );\n }\n\n return (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n selectedProvider={selectedProvider}\n topicRestrictionEnabled={topicRestrictionEnabled ?? false}\n handleSelectedModel={item => {\n setSelectedModel(item);\n setSelectedProvider(\n modelsItems.find((m: any) => m.value === item)?.provider || '',\n );\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n );\n};\n\n/**\n * @public\n */\nexport const LightspeedChatContainer = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedChatContainerInner />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,18 +1,8 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
3
- import { useNavigate, useLocation, useMatch } from 'react-router-dom';
4
2
  import { makeStyles } from '@mui/styles';
5
- import { ChatbotDisplayMode, ChatbotModal } from '@patternfly/chatbot';
6
- import '@backstage/core-plugin-api';
7
- import '@tanstack/react-query';
8
- import '../api/api.esm.js';
9
- import { useBackstageUserIdentity } from '../hooks/useBackstageUserIdentity.esm.js';
10
- import '@mui/icons-material/PushPin';
11
- import '@backstage/plugin-permission-react';
12
- import '@red-hat-developer-hub/backstage-plugin-lightspeed-common';
13
- import { useDisplayModeSettings } from '../hooks/useDisplayModeSettings.esm.js';
14
- import '@backstage/core-plugin-api/alpha';
15
- import '../translations/ref.esm.js';
3
+ import { ChatbotModal } from '@patternfly/chatbot';
4
+ import { DOCKED_CONTENT_OFFSET } from '../const.esm.js';
5
+ import { useLightspeedProviderState } from '../hooks/useLightspeedProviderState.esm.js';
16
6
  import { LightspeedChatContainer } from './LightspeedChatContainer.esm.js';
17
7
  import { LightspeedDrawerContext } from './LightspeedDrawerContext.esm.js';
18
8
 
@@ -20,160 +10,25 @@ const useStyles = makeStyles((theme) => ({
20
10
  chatbotModal: {
21
11
  boxShadow: "0 14px 20px -7px rgba(0, 0, 0, 0.22), 0 32px 50px 6px rgba(0, 0, 0, 0.16), 0 12px 60px 12px rgba(0, 0, 0, 0.14) !important",
22
12
  bottom: `calc(${theme?.spacing?.(2) ?? "16px"} + 5em)`,
23
- right: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`
13
+ right: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`,
14
+ maxWidth: "min(30rem, calc(100vw - 32px)) !important",
15
+ overflowX: "hidden",
16
+ transition: "margin-right 0.3s ease",
17
+ "body.docked-drawer-open &": {
18
+ marginRight: DOCKED_CONTENT_OFFSET
19
+ }
24
20
  }
25
21
  }));
26
22
  const LightspeedDrawerProvider = ({ children }) => {
27
23
  const classes = useStyles();
28
- const navigate = useNavigate();
29
- const location = useLocation();
30
- const user = useBackstageUserIdentity();
31
- const {
32
- displayMode: persistedDisplayMode,
33
- setDisplayMode: setPersistedDisplayMode
34
- } = useDisplayModeSettings(user, ChatbotDisplayMode.default);
35
- const [displayModeState, setDisplayModeState] = useState(persistedDisplayMode);
36
- const [isOpen, setIsOpen] = useState(false);
37
- const [drawerWidth, setDrawerWidth] = useState(400);
38
- const [currentConversationIdState, setCurrentConversationIdState] = useState(undefined);
39
- const [draftMessage, setDraftMessageState] = useState("");
40
- const [draftFileContents, setDraftFileContentsState] = useState([]);
41
- const openedViaFABRef = useRef(false);
42
- const isLightspeedRoute = location.pathname.startsWith("/lightspeed");
43
- const conversationMatch = useMatch(
44
- "/lightspeed/conversation/:conversationId"
45
- );
46
- const conversationId = conversationMatch?.params?.conversationId;
47
- const navigateBackOrGoToCatalog = useCallback(() => {
48
- if (!openedViaFABRef.current) {
49
- navigate("/catalog");
50
- openedViaFABRef.current = true;
51
- return;
52
- }
53
- navigate(-1);
54
- }, [navigate]);
55
- useEffect(() => {
56
- if (conversationId) {
57
- setCurrentConversationIdState(conversationId);
58
- } else {
59
- setCurrentConversationIdState(undefined);
60
- }
61
- if (isLightspeedRoute) {
62
- setDisplayModeState(ChatbotDisplayMode.embedded);
63
- setIsOpen(true);
64
- } else {
65
- if (persistedDisplayMode === ChatbotDisplayMode.embedded) {
66
- setDisplayModeState(ChatbotDisplayMode.default);
67
- } else {
68
- setDisplayModeState(persistedDisplayMode);
69
- }
70
- }
71
- }, [conversationId, isLightspeedRoute, persistedDisplayMode]);
72
- const openChatbot = useCallback(() => {
73
- openedViaFABRef.current = true;
74
- const modeToUse = persistedDisplayMode || ChatbotDisplayMode.default;
75
- setDisplayModeState(modeToUse);
76
- if (modeToUse === ChatbotDisplayMode.embedded) {
77
- const convId = currentConversationIdState;
78
- const path = convId ? `/lightspeed/conversation/${convId}` : "/lightspeed";
79
- navigate(path);
80
- }
81
- setIsOpen(true);
82
- }, [persistedDisplayMode, currentConversationIdState, navigate]);
83
- const closeChatbot = useCallback(() => {
84
- if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {
85
- navigateBackOrGoToCatalog();
86
- }
87
- setIsOpen(false);
88
- }, [displayModeState, isLightspeedRoute, navigateBackOrGoToCatalog]);
89
- const toggleChatbot = useCallback(() => {
90
- if (isOpen) {
91
- closeChatbot();
92
- } else {
93
- openChatbot();
94
- }
95
- }, [isOpen, openChatbot, closeChatbot]);
96
- const setCurrentConversationId = useCallback(
97
- (id) => {
98
- setCurrentConversationIdState(id);
99
- if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {
100
- const path = id ? `/lightspeed/conversation/${id}` : "/lightspeed";
101
- navigate(path, { replace: true });
102
- }
103
- },
104
- [displayModeState, isLightspeedRoute, navigate]
105
- );
106
- const setDraftMessage = useCallback((message) => {
107
- setDraftMessageState(message);
108
- }, []);
109
- const setDraftFileContents = useCallback((files) => {
110
- setDraftFileContentsState(files);
111
- }, []);
112
- const setDisplayMode = useCallback(
113
- (mode, conversationIdParam) => {
114
- if (mode === displayModeState) {
115
- return;
116
- }
117
- setPersistedDisplayMode(mode);
118
- if (mode === ChatbotDisplayMode.embedded) {
119
- const convId = conversationIdParam ?? currentConversationIdState;
120
- const path = convId ? `/lightspeed/conversation/${convId}` : "/lightspeed";
121
- navigate(path);
122
- setIsOpen(true);
123
- } else {
124
- if (isLightspeedRoute) {
125
- navigateBackOrGoToCatalog();
126
- }
127
- setIsOpen(true);
128
- }
129
- },
130
- [
131
- navigate,
132
- isLightspeedRoute,
133
- currentConversationIdState,
134
- displayModeState,
135
- navigateBackOrGoToCatalog,
136
- setPersistedDisplayMode
137
- ]
138
- );
139
- const shouldRenderOverlayModal = isOpen && displayModeState === ChatbotDisplayMode.default && !isLightspeedRoute;
140
- const contextValue = useMemo(
141
- () => ({
142
- isChatbotActive: isOpen,
143
- toggleChatbot,
144
- displayMode: displayModeState,
145
- setDisplayMode,
146
- drawerWidth,
147
- setDrawerWidth,
148
- currentConversationId: currentConversationIdState,
149
- setCurrentConversationId,
150
- draftMessage,
151
- setDraftMessage,
152
- draftFileContents,
153
- setDraftFileContents
154
- }),
155
- [
156
- isOpen,
157
- toggleChatbot,
158
- displayModeState,
159
- setDisplayMode,
160
- drawerWidth,
161
- setDrawerWidth,
162
- currentConversationIdState,
163
- setCurrentConversationId,
164
- draftMessage,
165
- setDraftMessage,
166
- draftFileContents,
167
- setDraftFileContents
168
- ]
169
- );
24
+ const { contextValue, shouldRenderOverlayModal, closeChatbot } = useLightspeedProviderState();
170
25
  return /* @__PURE__ */ jsxs(LightspeedDrawerContext.Provider, { value: contextValue, children: [
171
26
  children,
172
27
  shouldRenderOverlayModal && /* @__PURE__ */ jsx(
173
28
  ChatbotModal,
174
29
  {
175
30
  isOpen: true,
176
- displayMode: displayModeState,
31
+ displayMode: contextValue.displayMode,
177
32
  onClose: closeChatbot,
178
33
  ouiaId: "LightspeedChatbotModal",
179
34
  "aria-labelledby": "lightspeed-chatpopup-modal",
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedDrawerProvider.esm.js","sources":["../../src/components/LightspeedDrawerProvider.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useLocation, useMatch, useNavigate } from 'react-router-dom';\n\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode, ChatbotModal } from '@patternfly/chatbot';\n\nimport { useBackstageUserIdentity, useDisplayModeSettings } from '../hooks';\nimport { FileContent } from '../types';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\nimport { LightspeedDrawerContext } from './LightspeedDrawerContext';\n\nconst useStyles = makeStyles(theme => ({\n chatbotModal: {\n boxShadow:\n '0 14px 20px -7px rgba(0, 0, 0, 0.22), 0 32px 50px 6px rgba(0, 0, 0, 0.16), 0 12px 60px 12px rgba(0, 0, 0, 0.14) !important',\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n },\n}));\n\n/**\n * @public\n */\nexport const LightspeedDrawerProvider = ({ children }: PropsWithChildren) => {\n const classes = useStyles();\n const navigate = useNavigate();\n const location = useLocation();\n const user = useBackstageUserIdentity();\n const {\n displayMode: persistedDisplayMode,\n setDisplayMode: setPersistedDisplayMode,\n } = useDisplayModeSettings(user, ChatbotDisplayMode.default);\n\n const [displayModeState, setDisplayModeState] =\n useState<ChatbotDisplayMode>(persistedDisplayMode);\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [drawerWidth, setDrawerWidth] = useState<number>(400);\n const [currentConversationIdState, setCurrentConversationIdState] = useState<\n string | undefined\n >(undefined);\n const [draftMessage, setDraftMessageState] = useState<string>('');\n const [draftFileContents, setDraftFileContentsState] = useState<\n FileContent[]\n >([]);\n const openedViaFABRef = useRef<boolean>(false);\n\n const isLightspeedRoute = location.pathname.startsWith('/lightspeed');\n\n const conversationMatch = useMatch(\n '/lightspeed/conversation/:conversationId',\n );\n\n const conversationId = conversationMatch?.params?.conversationId;\n\n const navigateBackOrGoToCatalog = useCallback(() => {\n // go to catalog page, if the user opens the lightspeed route via a new tab\n if (!openedViaFABRef.current) {\n navigate('/catalog');\n openedViaFABRef.current = true;\n return;\n }\n navigate(-1);\n }, [navigate]);\n\n useEffect(() => {\n if (conversationId) {\n setCurrentConversationIdState(conversationId);\n } else {\n setCurrentConversationIdState(undefined);\n }\n\n if (isLightspeedRoute) {\n setDisplayModeState(ChatbotDisplayMode.embedded);\n setIsOpen(true);\n } else {\n // When leaving lightspeed route, restore the persisted display mode\n // If persisted mode is embedded, reset to default\n if (persistedDisplayMode === ChatbotDisplayMode.embedded) {\n setDisplayModeState(ChatbotDisplayMode.default);\n } else {\n setDisplayModeState(persistedDisplayMode);\n }\n }\n }, [conversationId, isLightspeedRoute, persistedDisplayMode]);\n\n // Open chatbot using the persisted display mode preference\n const openChatbot = useCallback(() => {\n openedViaFABRef.current = true;\n\n const modeToUse = persistedDisplayMode || ChatbotDisplayMode.default;\n setDisplayModeState(modeToUse);\n\n if (modeToUse === ChatbotDisplayMode.embedded) {\n const convId = currentConversationIdState;\n const path = convId\n ? `/lightspeed/conversation/${convId}`\n : '/lightspeed';\n navigate(path);\n }\n\n setIsOpen(true);\n }, [persistedDisplayMode, currentConversationIdState, navigate]);\n\n const closeChatbot = useCallback(() => {\n // If in embedded mode on the lightspeed route, navigate back\n if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n setIsOpen(false);\n }, [displayModeState, isLightspeedRoute, navigateBackOrGoToCatalog]);\n\n const toggleChatbot = useCallback(() => {\n if (isOpen) {\n closeChatbot();\n } else {\n openChatbot();\n }\n }, [isOpen, openChatbot, closeChatbot]);\n\n const setCurrentConversationId = useCallback(\n (id: string | undefined) => {\n setCurrentConversationIdState(id);\n\n if (\n displayModeState === ChatbotDisplayMode.embedded &&\n isLightspeedRoute\n ) {\n const path = id ? `/lightspeed/conversation/${id}` : '/lightspeed';\n navigate(path, { replace: true });\n }\n },\n [displayModeState, isLightspeedRoute, navigate],\n );\n\n const setDraftMessage = useCallback((message: string) => {\n setDraftMessageState(message);\n }, []);\n\n const setDraftFileContents = useCallback((files: FileContent[]) => {\n setDraftFileContentsState(files);\n }, []);\n\n // Set display mode with route handling for embedded/fullscreen\n const setDisplayMode = useCallback(\n (mode: ChatbotDisplayMode, conversationIdParam?: string) => {\n if (mode === displayModeState) {\n return;\n }\n\n setPersistedDisplayMode(mode);\n\n // Navigate to fullscreen route with conversation ID if available\n if (mode === ChatbotDisplayMode.embedded) {\n const convId = conversationIdParam ?? currentConversationIdState;\n const path = convId\n ? `/lightspeed/conversation/${convId}`\n : '/lightspeed';\n navigate(path);\n setIsOpen(true);\n } else {\n if (isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n setIsOpen(true);\n }\n },\n [\n navigate,\n isLightspeedRoute,\n currentConversationIdState,\n displayModeState,\n navigateBackOrGoToCatalog,\n setPersistedDisplayMode,\n ],\n );\n\n // Only render ChatbotModal for overlay mode\n // Docked mode is handled by ApplicationDrawer in Root\n // Embedded mode is handled by LightspeedPage route\n const shouldRenderOverlayModal =\n isOpen &&\n displayModeState === ChatbotDisplayMode.default &&\n !isLightspeedRoute;\n\n const contextValue = useMemo(\n () => ({\n isChatbotActive: isOpen,\n toggleChatbot,\n displayMode: displayModeState,\n setDisplayMode,\n drawerWidth,\n setDrawerWidth,\n currentConversationId: currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n }),\n [\n isOpen,\n toggleChatbot,\n displayModeState,\n setDisplayMode,\n drawerWidth,\n setDrawerWidth,\n currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n ],\n );\n\n return (\n <LightspeedDrawerContext.Provider value={contextValue}>\n {children}\n {shouldRenderOverlayModal && (\n <ChatbotModal\n isOpen\n displayMode={displayModeState}\n onClose={closeChatbot}\n ouiaId=\"LightspeedChatbotModal\"\n aria-labelledby=\"lightspeed-chatpopup-modal\"\n className={classes.chatbotModal}\n >\n <LightspeedChatContainer />\n </ChatbotModal>\n )}\n </LightspeedDrawerContext.Provider>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedDrawerProvider.esm.js","sources":["../../src/components/LightspeedDrawerProvider.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PropsWithChildren } from 'react';\n\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotModal } from '@patternfly/chatbot';\n\nimport { DOCKED_CONTENT_OFFSET } from '../const';\nimport { useLightspeedProviderState } from '../hooks/useLightspeedProviderState';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\nimport { LightspeedDrawerContext } from './LightspeedDrawerContext';\n\nconst useStyles = makeStyles(theme => ({\n chatbotModal: {\n boxShadow:\n '0 14px 20px -7px rgba(0, 0, 0, 0.22), 0 32px 50px 6px rgba(0, 0, 0, 0.16), 0 12px 60px 12px rgba(0, 0, 0, 0.14) !important',\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n maxWidth: 'min(30rem, calc(100vw - 32px)) !important',\n overflowX: 'hidden' as const,\n transition: 'margin-right 0.3s ease',\n 'body.docked-drawer-open &': {\n marginRight: DOCKED_CONTENT_OFFSET,\n },\n },\n}));\n\n/**\n * @public\n */\nexport const LightspeedDrawerProvider = ({ children }: PropsWithChildren) => {\n const classes = useStyles();\n const { contextValue, shouldRenderOverlayModal, closeChatbot } =\n useLightspeedProviderState();\n\n return (\n <LightspeedDrawerContext.Provider value={contextValue}>\n {children}\n {shouldRenderOverlayModal && (\n <ChatbotModal\n isOpen\n displayMode={contextValue.displayMode}\n onClose={closeChatbot}\n ouiaId=\"LightspeedChatbotModal\"\n aria-labelledby=\"lightspeed-chatpopup-modal\"\n className={classes.chatbotModal}\n >\n <LightspeedChatContainer />\n </ChatbotModal>\n )}\n </LightspeedDrawerContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,YAAc,EAAA;AAAA,IACZ,SACE,EAAA,4HAAA;AAAA,IACF,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,OAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC5C,QAAU,EAAA,2CAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA,wBAAA;AAAA,IACZ,2BAA6B,EAAA;AAAA,MAC3B,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAKK,MAAM,wBAA2B,GAAA,CAAC,EAAE,QAAA,EAAkC,KAAA;AAC3E,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,EAAE,YAAA,EAAc,wBAA0B,EAAA,YAAA,KAC9C,0BAA2B,EAAA;AAE7B,EAAA,uBACG,IAAA,CAAA,uBAAA,CAAwB,QAAxB,EAAA,EAAiC,OAAO,YACtC,EAAA,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,wBACC,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAM,EAAA,IAAA;AAAA,QACN,aAAa,YAAa,CAAA,WAAA;AAAA,QAC1B,OAAS,EAAA,YAAA;AAAA,QACT,MAAO,EAAA,wBAAA;AAAA,QACP,iBAAgB,EAAA,4BAAA;AAAA,QAChB,WAAW,OAAQ,CAAA,YAAA;AAAA,QAEnB,8BAAC,uBAAwB,EAAA,EAAA;AAAA;AAAA;AAC3B,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -4,6 +4,7 @@ import Fab from '@mui/material/Fab';
4
4
  import Tooltip from '@mui/material/Tooltip';
5
5
  import { makeStyles } from '@mui/styles';
6
6
  import { ChatbotDisplayMode } from '@patternfly/chatbot';
7
+ import { DOCKED_CONTENT_OFFSET } from '../const.esm.js';
7
8
  import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
8
9
  import { LightspeedFABIcon } from './LightspeedIcon.esm.js';
9
10
 
@@ -21,10 +22,10 @@ const useStyles = makeStyles((theme) => ({
21
22
  zIndex: 200,
22
23
  display: "flex",
23
24
  position: "fixed",
24
- // When drawer is docked, adjust margin
25
- ".docked-drawer-open &": {
25
+ // When ApplicationDrawer is docked, match main content inset
26
+ "body.docked-drawer-open &": {
26
27
  transition: "margin-right 0.3s ease",
27
- marginRight: "var(--docked-drawer-width, 500px) "
28
+ marginRight: DOCKED_CONTENT_OFFSET
28
29
  }
29
30
  }
30
31
  }));
@@ -52,7 +53,7 @@ const LightspeedFAB = () => {
52
53
  variant: "circular",
53
54
  size: "small",
54
55
  onClick: toggleChatbot,
55
- "aria-label": isChatbotActive ? "lightspeed-open" : "lightspeed-close",
56
+ "aria-label": isChatbotActive ? "lightspeed-close" : "lightspeed-open",
56
57
  className: fabButton.fab,
57
58
  sx: { borderRadius: "100% !important" },
58
59
  children: isChatbotActive ? /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(LightspeedFABIcon, {})
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedFAB.esm.js","sources":["../../src/components/LightspeedFAB.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Close from '@mui/icons-material/Close';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\nimport { LightspeedFABIcon } from './LightspeedIcon';\n\nconst useStyles = makeStyles(theme => ({\n fab: {\n opacity: '1 !important',\n backgroundColor: `${theme?.palette?.primary?.main ?? '#1976d2'} !important`,\n color: `${theme?.palette?.primary?.contrastText ?? '#fff'} !important`,\n boxShadow: `${\n theme?.shadows?.[6] ??\n '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)'\n } !important`,\n },\n 'fab-button': {\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n alignItems: 'end',\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n\n // When drawer is docked, adjust margin\n '.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: 'var(--docked-drawer-width, 500px) ',\n },\n },\n}));\n\n/**\n * @public\n * Lightspeed Floating action button to open/close the lightspeed chatbot\n */\n\nexport const LightspeedFAB = () => {\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const fabButton = useStyles();\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n return (\n <div\n className={fabButton['fab-button']}\n id=\"lightspeed-fab\"\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}\n placement=\"left\"\n >\n <Fab\n color=\"primary\"\n variant=\"circular\"\n size=\"small\"\n onClick={toggleChatbot}\n aria-label={isChatbotActive ? 'lightspeed-open' : 'lightspeed-close'}\n className={fabButton.fab}\n sx={{ borderRadius: '100% !important' }}\n >\n {isChatbotActive ? <Close fontSize=\"small\" /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </div>\n );\n};\n"],"names":["Close"],"mappings":";;;;;;;;;AAyBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,GAAK,EAAA;AAAA,IACH,OAAS,EAAA,cAAA;AAAA,IACT,iBAAiB,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,QAAQ,SAAS,CAAA,WAAA,CAAA;AAAA,IAC9D,OAAO,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAgB,MAAM,CAAA,WAAA,CAAA;AAAA,IACzD,WAAW,CACT,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAClB,wGACF,CAAA,WAAA;AAAA,GACF;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC5C,UAAY,EAAA,KAAA;AAAA,IACZ,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA;AAAA,IAGV,uBAAyB,EAAA;AAAA,MACvB,UAAY,EAAA,wBAAA;AAAA,MACZ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAOK,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAe,EAAA,WAAA,KACtC,0BAA2B,EAAA;AAC7B,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAI,IAAA,WAAA,KAAgB,mBAAmB,QAAU,EAAA;AAC/C,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAU,YAAY,CAAA;AAAA,MACjC,EAAG,EAAA,gBAAA;AAAA,MACH,aAAY,EAAA,gBAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,UAC9C,SAAU,EAAA,MAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,KAAM,EAAA,SAAA;AAAA,cACN,OAAQ,EAAA,UAAA;AAAA,cACR,IAAK,EAAA,OAAA;AAAA,cACL,OAAS,EAAA,aAAA;AAAA,cACT,YAAA,EAAY,kBAAkB,iBAAoB,GAAA,kBAAA;AAAA,cAClD,WAAW,SAAU,CAAA,GAAA;AAAA,cACrB,EAAA,EAAI,EAAE,YAAA,EAAc,iBAAkB,EAAA;AAAA,cAErC,4CAAmB,GAAA,CAAAA,SAAA,EAAA,EAAM,UAAS,OAAQ,EAAA,CAAA,uBAAM,iBAAkB,EAAA,EAAA;AAAA;AAAA;AACrE;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"LightspeedFAB.esm.js","sources":["../../src/components/LightspeedFAB.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Close from '@mui/icons-material/Close';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { DOCKED_CONTENT_OFFSET } from '../const';\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\nimport { LightspeedFABIcon } from './LightspeedIcon';\n\nconst useStyles = makeStyles(theme => ({\n fab: {\n opacity: '1 !important',\n backgroundColor: `${theme?.palette?.primary?.main ?? '#1976d2'} !important`,\n color: `${theme?.palette?.primary?.contrastText ?? '#fff'} !important`,\n boxShadow: `${\n theme?.shadows?.[6] ??\n '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)'\n } !important`,\n },\n 'fab-button': {\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n alignItems: 'end',\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n\n // When ApplicationDrawer is docked, match main content inset\n 'body.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: DOCKED_CONTENT_OFFSET,\n },\n },\n}));\n\n/**\n * @public\n * Lightspeed Floating action button to open/close the lightspeed chatbot\n */\n\nexport const LightspeedFAB = () => {\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const fabButton = useStyles();\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n return (\n <div\n className={fabButton['fab-button']}\n id=\"lightspeed-fab\"\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}\n placement=\"left\"\n >\n <Fab\n color=\"primary\"\n variant=\"circular\"\n size=\"small\"\n onClick={toggleChatbot}\n aria-label={isChatbotActive ? 'lightspeed-close' : 'lightspeed-open'}\n className={fabButton.fab}\n sx={{ borderRadius: '100% !important' }}\n >\n {isChatbotActive ? <Close fontSize=\"small\" /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </div>\n );\n};\n"],"names":["Close"],"mappings":";;;;;;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,GAAK,EAAA;AAAA,IACH,OAAS,EAAA,cAAA;AAAA,IACT,iBAAiB,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,QAAQ,SAAS,CAAA,WAAA,CAAA;AAAA,IAC9D,OAAO,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAgB,MAAM,CAAA,WAAA,CAAA;AAAA,IACzD,WAAW,CACT,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAClB,wGACF,CAAA,WAAA;AAAA,GACF;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC5C,UAAY,EAAA,KAAA;AAAA,IACZ,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA;AAAA,IAGV,2BAA6B,EAAA;AAAA,MAC3B,UAAY,EAAA,wBAAA;AAAA,MACZ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAOK,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAe,EAAA,WAAA,KACtC,0BAA2B,EAAA;AAC7B,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAI,IAAA,WAAA,KAAgB,mBAAmB,QAAU,EAAA;AAC/C,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAU,YAAY,CAAA;AAAA,MACjC,EAAG,EAAA,gBAAA;AAAA,MACH,aAAY,EAAA,gBAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,UAC9C,SAAU,EAAA,MAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,KAAM,EAAA,SAAA;AAAA,cACN,OAAQ,EAAA,UAAA;AAAA,cACR,IAAK,EAAA,OAAA;AAAA,cACL,OAAS,EAAA,aAAA;AAAA,cACT,YAAA,EAAY,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,cACnD,WAAW,SAAU,CAAA,GAAA;AAAA,cACrB,EAAA,EAAI,EAAE,YAAA,EAAc,iBAAkB,EAAA;AAAA,cAErC,4CAAmB,GAAA,CAAAA,SAAA,EAAA,EAAM,UAAS,OAAQ,EAAA,CAAA,uBAAM,iBAAkB,EAAA,EAAA;AAAA;AAAA;AACrE;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}