@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.0.2 → 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 (59) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/alpha.d.ts +0 -7
  3. package/dist/components/LightSpeedChat.esm.js +100 -67
  4. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  5. package/dist/components/LightspeedChatBoxHeader.esm.js +2 -1
  6. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  7. package/dist/components/LightspeedChatContainer.esm.js +38 -60
  8. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  9. package/dist/components/LightspeedFABContent.esm.js +9 -0
  10. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  11. package/dist/components/LightspeedPage.esm.js +11 -2
  12. package/dist/components/LightspeedPage.esm.js.map +1 -1
  13. package/dist/components/McpConfigureServerModal.esm.js +2 -3
  14. package/dist/components/McpConfigureServerModal.esm.js.map +1 -1
  15. package/dist/components/McpServersSettings.esm.js +24 -38
  16. package/dist/components/McpServersSettings.esm.js.map +1 -1
  17. package/dist/hooks/useAllModels.esm.js +2 -1
  18. package/dist/hooks/useAllModels.esm.js.map +1 -1
  19. package/dist/hooks/useConversations.esm.js +2 -1
  20. package/dist/hooks/useConversations.esm.js.map +1 -1
  21. package/dist/hooks/useIaChatPermission.esm.js +15 -0
  22. package/dist/hooks/useIaChatPermission.esm.js.map +1 -0
  23. package/dist/hooks/useIaMcpToolsPermission.esm.js +15 -0
  24. package/dist/hooks/useIaMcpToolsPermission.esm.js.map +1 -0
  25. package/dist/hooks/{notebooks/useLightspeedNotebooksPermission.esm.js → useIaNotebooksPermission.esm.js} +4 -5
  26. package/dist/hooks/useIaNotebooksPermission.esm.js.map +1 -0
  27. package/dist/hooks/useMcpConfigureModal.esm.js +5 -9
  28. package/dist/hooks/useMcpConfigureModal.esm.js.map +1 -1
  29. package/dist/hooks/useNotebookConversationIds.esm.js +2 -1
  30. package/dist/hooks/useNotebookConversationIds.esm.js.map +1 -1
  31. package/dist/hooks/useQuestionValidation.esm.js +3 -2
  32. package/dist/hooks/useQuestionValidation.esm.js.map +1 -1
  33. package/dist/hooks/useWelcomePrompts.esm.js +2 -2
  34. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  35. package/dist/translations/de.esm.js +0 -7
  36. package/dist/translations/de.esm.js.map +1 -1
  37. package/dist/translations/es.esm.js +0 -7
  38. package/dist/translations/es.esm.js.map +1 -1
  39. package/dist/translations/fr.esm.js +0 -7
  40. package/dist/translations/fr.esm.js.map +1 -1
  41. package/dist/translations/it.esm.js +0 -7
  42. package/dist/translations/it.esm.js.map +1 -1
  43. package/dist/translations/ja.esm.js +0 -7
  44. package/dist/translations/ja.esm.js.map +1 -1
  45. package/dist/translations/ref.esm.js +0 -8
  46. package/dist/translations/ref.esm.js.map +1 -1
  47. package/package.json +3 -2
  48. package/dist/components/PermissionRequiredIcon.esm.js +0 -18
  49. package/dist/components/PermissionRequiredIcon.esm.js.map +0 -1
  50. package/dist/components/PermissionRequiredState.esm.js +0 -88
  51. package/dist/components/PermissionRequiredState.esm.js.map +0 -1
  52. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +0 -1
  53. package/dist/hooks/useLightspeedDeletePermission.esm.js +0 -12
  54. package/dist/hooks/useLightspeedDeletePermission.esm.js.map +0 -1
  55. package/dist/hooks/useLightspeedUpdatePermission.esm.js +0 -12
  56. package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +0 -1
  57. package/dist/hooks/useLightspeedViewPermission.esm.js +0 -16
  58. package/dist/hooks/useLightspeedViewPermission.esm.js.map +0 -1
  59. package/dist/images/permission-required.svg +0 -319
@@ -43,6 +43,7 @@ const LightspeedChatBoxHeader = ({
43
43
  isModelSelectorDisabled = false,
44
44
  hideModelSelector = false,
45
45
  showChatTabOptions = true,
46
+ showMcpSettings = false,
46
47
  setDisplayMode
47
48
  }) => {
48
49
  const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);
@@ -189,7 +190,7 @@ const LightspeedChatBoxHeader = ({
189
190
  },
190
191
  "enablePinningChats"
191
192
  ),
192
- /* @__PURE__ */ jsxs(
193
+ showMcpSettings && /* @__PURE__ */ jsxs(
193
194
  DropdownItem,
194
195
  {
195
196
  value: "mcpSettings",
@@ -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, useState } from 'react';\n\nimport ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport { styled } from '@mui/material/styles';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n Icon,\n Label,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n RhUiEllipsisVerticalFillIcon,\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 hideModelSelector?: boolean;\n /** When false, omits pinned-chats and MCP entries (Chat tab only). */\n showChatTabOptions?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst StyledDropdown = styled(Dropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst StyledOptionsDropdown = styled(ChatbotHeaderOptionsDropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst SelectorToggle = styled(MenuToggle, {\n shouldForwardProp: prop => prop !== 'dimmed',\n})<{ dimmed?: boolean }>(({ theme, dimmed }) => ({\n ...(dimmed && {\n backgroundColor: theme.palette.action.disabled,\n }),\n}));\n\nconst StyledDropdownGroup = styled(DropdownGroup)({\n fontWeight: 'bold',\n});\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n onMcpSettingsClick,\n isModelSelectorDisabled = false,\n hideModelSelector = false,\n showChatTabOptions = true,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\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 <SelectorToggle\n dimmed={isModelSelectorDisabled}\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 </SelectorToggle>\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 {!hideModelSelector && (\n <StyledDropdown\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 <StyledDropdownGroup 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 </StyledDropdownGroup>\n ))}\n </DropdownList>\n </StyledDropdown>\n )}\n <StyledOptionsDropdown\n isCompact\n shouldFocusFirstItemOnOpen={false}\n popperProps={{\n position: 'right',\n preventOverflow: true,\n appendTo: () => document.body,\n }}\n toggleProps={{\n 'aria-label': t('aria.options.label'),\n className: 'pf-chatbot__button--toggle-options pf-m-compact',\n icon: (\n <Icon size=\"lg\" isInline>\n <RhUiEllipsisVerticalFillIcon />\n </Icon>\n ),\n }}\n tooltipProps={{\n trigger: 'manual',\n content: '',\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 {showChatTabOptions && (\n <>\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 <Label color=\"purple\" isCompact style={{ marginLeft: 8 }}>\n {t('settings.mcp.badge')}\n </Label>\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n </>\n )}\n </StyledOptionsDropdown>\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 ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport { styled } from '@mui/material/styles';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n Icon,\n Label,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n RhUiEllipsisVerticalFillIcon,\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 hideModelSelector?: boolean;\n /** When false, omits pinned-chats and MCP entries (Chat tab only). */\n showChatTabOptions?: boolean;\n /** When false, hides MCP settings from the header menu. */\n showMcpSettings?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst StyledDropdown = styled(Dropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst StyledOptionsDropdown = styled(ChatbotHeaderOptionsDropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst SelectorToggle = styled(MenuToggle, {\n shouldForwardProp: prop => prop !== 'dimmed',\n})<{ dimmed?: boolean }>(({ theme, dimmed }) => ({\n ...(dimmed && {\n backgroundColor: theme.palette.action.disabled,\n }),\n}));\n\nconst StyledDropdownGroup = styled(DropdownGroup)({\n fontWeight: 'bold',\n});\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n onMcpSettingsClick,\n isModelSelectorDisabled = false,\n hideModelSelector = false,\n showChatTabOptions = true,\n showMcpSettings = false,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\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 <SelectorToggle\n dimmed={isModelSelectorDisabled}\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 </SelectorToggle>\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 {!hideModelSelector && (\n <StyledDropdown\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 <StyledDropdownGroup 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 </StyledDropdownGroup>\n ))}\n </DropdownList>\n </StyledDropdown>\n )}\n <StyledOptionsDropdown\n isCompact\n shouldFocusFirstItemOnOpen={false}\n popperProps={{\n position: 'right',\n preventOverflow: true,\n appendTo: () => document.body,\n }}\n toggleProps={{\n 'aria-label': t('aria.options.label'),\n className: 'pf-chatbot__button--toggle-options pf-m-compact',\n icon: (\n <Icon size=\"lg\" isInline>\n <RhUiEllipsisVerticalFillIcon />\n </Icon>\n ),\n }}\n tooltipProps={{\n trigger: 'manual',\n content: '',\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 {showChatTabOptions && (\n <>\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 {showMcpSettings && (\n <DropdownItem\n value=\"mcpSettings\"\n key=\"mcpSettings\"\n icon={<McpSettingsIcon />}\n onClick={onMcpSettingsClick}\n >\n {t('settings.mcp.label')}\n <Label color=\"purple\" isCompact style={{ marginLeft: 8 }}>\n {t('settings.mcp.badge')}\n </Label>\n </DropdownItem>\n )}\n </DropdownList>\n </DropdownGroup>\n </>\n )}\n </StyledOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,22 +1,19 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { jsx } from 'react/jsx-runtime';
2
2
  import '@patternfly/react-core/dist/styles/base-no-reset.css';
3
3
  import '@patternfly/chatbot/dist/css/main.css';
4
4
  import { useState, useMemo, useLayoutEffect, useEffect } from 'react';
5
5
  import { useAsync } from 'react-use';
6
6
  import { useApi, identityApiRef } from '@backstage/core-plugin-api';
7
- import OpenInNewIcon from '@mui/icons-material/OpenInNew';
8
- import Button from '@mui/material/Button';
9
7
  import { useTheme } from '@mui/material/styles';
10
8
  import { QueryClientProvider } from '@tanstack/react-query';
11
9
  import { useAllModels } from '../hooks/useAllModels.esm.js';
12
- import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
10
+ import { useIaChatPermission } from '../hooks/useIaChatPermission.esm.js';
11
+ import { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission.esm.js';
13
12
  import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
14
- import { useTranslation } from '../hooks/useTranslation.esm.js';
15
13
  import queryClient from '../utils/queryClient.esm.js';
16
14
  import FileAttachmentContextProvider from './AttachmentContext.esm.js';
17
15
  import { LightspeedChat } from './LightSpeedChat.esm.js';
18
16
  import { LightspeedChatModelsLoading, ModelsLoadErrorEmptyState, LcoreNotConfiguredEmptyState } from './LightspeedChatModelsState.esm.js';
19
- import PermissionRequiredState from './PermissionRequiredState.esm.js';
20
17
 
21
18
  const THEME_DARK = "dark";
22
19
  const THEME_DARK_CLASS = "pf-v6-theme-dark";
@@ -25,25 +22,23 @@ const LightspeedChatContainerInner = () => {
25
22
  const {
26
23
  palette: { mode }
27
24
  } = useTheme();
28
- const { t } = useTranslation();
29
25
  const identityApi = useApi(identityApiRef);
26
+ const { allowed: hasChatAccess, loading: chatPermissionLoading } = useIaChatPermission();
27
+ const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } = useIaNotebooksPermission();
28
+ const permissionsLoading = chatPermissionLoading || notebooksPermissionLoading;
29
+ const hasPluginAccess = hasChatAccess || hasNotebooksAccess;
30
30
  const {
31
31
  data: models,
32
32
  isLoading: modelsLoading,
33
33
  isError: modelsError,
34
34
  refetch: refetchModels
35
- } = useAllModels();
36
- const {
37
- allowed: hasViewAccess,
38
- loading,
39
- iaChatPermissionName
40
- } = useLightspeedViewPermission();
35
+ } = useAllModels(hasChatAccess);
41
36
  const { value: profile, loading: profileLoading } = useAsync(
42
37
  async () => await identityApi.getProfileInfo()
43
38
  );
44
39
  const [selectedModel, setSelectedModel] = useState("");
45
40
  const [selectedProvider, setSelectedProvider] = useState("");
46
- const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();
41
+ const { data: topicRestrictionEnabled } = useTopicRestrictionStatus(hasChatAccess);
47
42
  const modelsItems = useMemo(
48
43
  () => models ? models.filter((model) => model.model_type === "llm").map((m) => ({
49
44
  label: m.provider_resource_id,
@@ -61,28 +56,29 @@ const LightspeedChatContainerInner = () => {
61
56
  }
62
57
  }, [mode]);
63
58
  useEffect(() => {
64
- if (modelsItems.length > 0) {
65
- try {
66
- const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);
67
- const parsedData = storedData ? JSON.parse(storedData) : null;
68
- const storedModel = parsedData?.model ? modelsItems.find((m) => m.value === parsedData.model) : null;
69
- if (storedModel) {
70
- setSelectedModel(storedModel.value);
71
- setSelectedProvider(storedModel.provider);
72
- } else {
73
- setSelectedModel(modelsItems[0].value);
74
- setSelectedProvider(modelsItems[0].provider);
75
- }
76
- } catch (error) {
77
- console.error(
78
- "Error loading last selected model from localStorage:",
79
- error
80
- );
59
+ if (!hasChatAccess || modelsItems.length === 0) {
60
+ return;
61
+ }
62
+ try {
63
+ const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);
64
+ const parsedData = storedData ? JSON.parse(storedData) : null;
65
+ const storedModel = parsedData?.model ? modelsItems.find((m) => m.value === parsedData.model) : null;
66
+ if (storedModel) {
67
+ setSelectedModel(storedModel.value);
68
+ setSelectedProvider(storedModel.provider);
69
+ } else {
81
70
  setSelectedModel(modelsItems[0].value);
82
71
  setSelectedProvider(modelsItems[0].provider);
83
72
  }
73
+ } catch (error) {
74
+ console.error(
75
+ "Error loading last selected model from localStorage:",
76
+ error
77
+ );
78
+ setSelectedModel(modelsItems[0].value);
79
+ setSelectedProvider(modelsItems[0].provider);
84
80
  }
85
- }, [modelsItems]);
81
+ }, [hasChatAccess, modelsItems]);
86
82
  useEffect(() => {
87
83
  if (selectedModel && selectedProvider) {
88
84
  try {
@@ -101,46 +97,28 @@ const LightspeedChatContainerInner = () => {
101
97
  }
102
98
  }
103
99
  }, [selectedModel, selectedProvider]);
104
- if (loading) {
100
+ if (permissionsLoading) {
105
101
  return /* @__PURE__ */ jsx(LightspeedChatModelsLoading, {});
106
102
  }
107
- if (!hasViewAccess) {
108
- return /* @__PURE__ */ jsx(
109
- PermissionRequiredState,
110
- {
111
- subject: t("permission.subject.plugin"),
112
- permissions: [iaChatPermissionName],
113
- action: /* @__PURE__ */ jsxs(
114
- Button,
115
- {
116
- variant: "outlined",
117
- color: "primary",
118
- target: "_blank",
119
- href: "https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/intelligent-assistant/plugins/intelligent-assistant/README.md#permission-framework-support",
120
- children: [
121
- t("common.readMore"),
122
- " \xA0 ",
123
- /* @__PURE__ */ jsx(OpenInNewIcon, {})
124
- ]
125
- }
126
- )
127
- }
128
- );
103
+ if (!hasPluginAccess) {
104
+ return null;
129
105
  }
130
- if (modelsLoading) {
106
+ if (hasChatAccess && modelsLoading) {
131
107
  return /* @__PURE__ */ jsx(LightspeedChatModelsLoading, {});
132
108
  }
133
- if (modelsError && modelsItems.length === 0) {
109
+ if (hasChatAccess && modelsError && modelsItems.length === 0) {
134
110
  return /* @__PURE__ */ jsx(ModelsLoadErrorEmptyState, { onRetry: () => refetchModels() });
135
111
  }
136
- if (modelsItems.length === 0) {
112
+ if (hasChatAccess && modelsItems.length === 0) {
137
113
  return /* @__PURE__ */ jsx(LcoreNotConfiguredEmptyState, {});
138
114
  }
115
+ const resolvedSelectedModel = selectedModel || modelsItems[0]?.value || "";
116
+ const resolvedSelectedProvider = selectedProvider || modelsItems[0]?.provider || "";
139
117
  return /* @__PURE__ */ jsx(FileAttachmentContextProvider, { children: /* @__PURE__ */ jsx(
140
118
  LightspeedChat,
141
119
  {
142
- selectedModel,
143
- selectedProvider,
120
+ selectedModel: resolvedSelectedModel,
121
+ selectedProvider: resolvedSelectedProvider,
144
122
  topicRestrictionEnabled: topicRestrictionEnabled ?? false,
145
123
  handleSelectedModel: (item) => {
146
124
  setSelectedModel(item);
@@ -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 '@patternfly/react-core/dist/styles/base-no-reset.css';\nimport '@patternfly/chatbot/dist/css/main.css';\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport Button from '@mui/material/Button';\nimport { useTheme } from '@mui/material/styles';\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 {\n LcoreNotConfiguredEmptyState,\n LightspeedChatModelsLoading,\n ModelsLoadErrorEmptyState,\n} from './LightspeedChatModelsState';\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: { mode },\n } = useTheme();\n const { t } = useTranslation();\n\n const identityApi = useApi(identityApiRef);\n\n const {\n data: models,\n isLoading: modelsLoading,\n isError: modelsError,\n refetch: refetchModels,\n } = useAllModels();\n\n const {\n allowed: hasViewAccess,\n loading,\n iaChatPermissionName,\n } = 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 useLayoutEffect(() => {\n const htmlTagElement = document.documentElement;\n if (mode === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [mode]);\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 // Never return null inside the overlay modal: PatternFly's focus-trap requires at least\n // one tabbable node (e.g. after removing the modal close button). Locale switches can\n // briefly re-enter this loading state.\n return <LightspeedChatModelsLoading />;\n }\n\n if (!hasViewAccess) {\n return (\n <PermissionRequiredState\n subject={t('permission.subject.plugin')}\n permissions={[iaChatPermissionName]}\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/intelligent-assistant/plugins/intelligent-assistant/README.md#permission-framework-support\"\n >\n {t('common.readMore')} &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n );\n }\n\n if (modelsLoading) {\n return <LightspeedChatModelsLoading />;\n }\n\n // TanStack Query can keep the last successful `data` while `isError` is true after a\n // failed refetch. Prefer showing chat when we still have LLM rows; only use the full-page\n // error state when there is nothing usable to render.\n if (modelsError && modelsItems.length === 0) {\n return <ModelsLoadErrorEmptyState onRetry={() => refetchModels()} />;\n }\n\n if (modelsItems.length === 0) {\n return <LcoreNotConfiguredEmptyState />;\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
+ {"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 '@patternfly/react-core/dist/styles/base-no-reset.css';\nimport '@patternfly/chatbot/dist/css/main.css';\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { useTheme } from '@mui/material/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useIaChatPermission } from '../hooks/useIaChatPermission';\nimport { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport {\n LcoreNotConfiguredEmptyState,\n LightspeedChatModelsLoading,\n ModelsLoadErrorEmptyState,\n} from './LightspeedChatModelsState';\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: { mode },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { allowed: hasChatAccess, loading: chatPermissionLoading } =\n useIaChatPermission();\n\n const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } =\n useIaNotebooksPermission();\n\n const permissionsLoading =\n chatPermissionLoading || notebooksPermissionLoading;\n const hasPluginAccess = hasChatAccess || hasNotebooksAccess;\n\n const {\n data: models,\n isLoading: modelsLoading,\n isError: modelsError,\n refetch: refetchModels,\n } = useAllModels(hasChatAccess);\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 } =\n useTopicRestrictionStatus(hasChatAccess);\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 useLayoutEffect(() => {\n const htmlTagElement = document.documentElement;\n if (mode === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [mode]);\n\n // Load last selected model from localStorage\n useEffect(() => {\n if (!hasChatAccess || modelsItems.length === 0) {\n return;\n }\n\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 }, [hasChatAccess, 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 (permissionsLoading) {\n // Never return null inside the overlay modal: PatternFly's focus-trap requires at least\n // one tabbable node (e.g. after removing the modal close button). Locale switches can\n // briefly re-enter this loading state.\n return <LightspeedChatModelsLoading />;\n }\n\n if (!hasPluginAccess) {\n return null;\n }\n\n if (hasChatAccess && modelsLoading) {\n return <LightspeedChatModelsLoading />;\n }\n\n // TanStack Query can keep the last successful `data` while `isError` is true after a\n // failed refetch. Prefer showing chat when we still have LLM rows; only use the full-page\n // error state when there is nothing usable to render.\n if (hasChatAccess && modelsError && modelsItems.length === 0) {\n return <ModelsLoadErrorEmptyState onRetry={() => refetchModels()} />;\n }\n\n if (hasChatAccess && modelsItems.length === 0) {\n return <LcoreNotConfiguredEmptyState />;\n }\n\n const resolvedSelectedModel = selectedModel || modelsItems[0]?.value || '';\n const resolvedSelectedProvider =\n selectedProvider || modelsItems[0]?.provider || '';\n\n return (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={resolvedSelectedModel}\n selectedProvider={resolvedSelectedProvider}\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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"}
@@ -6,6 +6,8 @@ import { useTheme } from '@mui/material/styles';
6
6
  import Tooltip from '@mui/material/Tooltip';
7
7
  import { ChatbotDisplayMode } from '@patternfly/chatbot';
8
8
  import { LIGHTSPEED_FAB_ELEMENT_ID, DOCKED_CONTENT_OFFSET } from '../const.esm.js';
9
+ import { useIaChatPermission } from '../hooks/useIaChatPermission.esm.js';
10
+ import { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission.esm.js';
9
11
  import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
10
12
  import { useTranslation } from '../hooks/useTranslation.esm.js';
11
13
  import { getLightspeedFabEdgeInset, clearLightspeedFabAnchorVars, publishLightspeedFabAnchorVars } from '../utils/fab-anchor-utils.esm.js';
@@ -15,6 +17,10 @@ const LightspeedFABContent = () => {
15
17
  const { t } = useTranslation();
16
18
  const theme = useTheme();
17
19
  const { isChatbotActive, toggleChatbot, displayMode } = useLightspeedDrawerContext();
20
+ const { allowed: hasChatAccess, loading: chatPermissionLoading } = useIaChatPermission();
21
+ const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } = useIaNotebooksPermission();
22
+ const permissionsLoading = chatPermissionLoading || notebooksPermissionLoading;
23
+ const hasPluginAccess = hasChatAccess || hasNotebooksAccess;
18
24
  const fabRef = useRef(null);
19
25
  const fabEdgeInset = getLightspeedFabEdgeInset(theme);
20
26
  useLayoutEffect(() => {
@@ -44,6 +50,9 @@ const LightspeedFABContent = () => {
44
50
  if (displayMode === ChatbotDisplayMode.embedded) {
45
51
  return null;
46
52
  }
53
+ if (permissionsLoading || !hasPluginAccess) {
54
+ return null;
55
+ }
47
56
  return /* @__PURE__ */ jsx(
48
57
  Box,
49
58
  {
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedFABContent.esm.js","sources":["../../src/components/LightspeedFABContent.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 { useLayoutEffect, useRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Fab from '@mui/material/Fab';\nimport { useTheme } from '@mui/material/styles';\nimport Tooltip from '@mui/material/Tooltip';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { DOCKED_CONTENT_OFFSET, LIGHTSPEED_FAB_ELEMENT_ID } from '../const';\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\nimport { useTranslation } from '../hooks/useTranslation';\nimport {\n clearLightspeedFabAnchorVars,\n getLightspeedFabEdgeInset,\n publishLightspeedFabAnchorVars,\n} from '../utils/fab-anchor-utils';\nimport { LightspeedFABIcon, LightspeedFABOpenIcon } from './LightspeedIcon';\n\nexport const LightspeedFABContent = () => {\n const { t } = useTranslation();\n const theme = useTheme();\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const fabRef = useRef<HTMLDivElement>(null);\n const fabEdgeInset = getLightspeedFabEdgeInset(theme);\n\n useLayoutEffect(() => {\n const fab = fabRef.current;\n if (!fab) {\n return undefined;\n }\n\n const syncAnchor = () =>\n publishLightspeedFabAnchorVars({ fabElement: fab, theme });\n syncAnchor();\n\n const resizeObserver =\n typeof ResizeObserver === 'function'\n ? new ResizeObserver(syncAnchor)\n : undefined;\n resizeObserver?.observe(fab);\n\n window.addEventListener('resize', syncAnchor);\n fab.addEventListener('transitionend', syncAnchor);\n const mutationObserver = new MutationObserver(syncAnchor);\n mutationObserver.observe(document.body, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n return () => {\n resizeObserver?.disconnect();\n window.removeEventListener('resize', syncAnchor);\n fab.removeEventListener('transitionend', syncAnchor);\n mutationObserver.disconnect();\n clearLightspeedFabAnchorVars();\n };\n }, [displayMode, theme]);\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n return (\n <Box\n ref={fabRef}\n sx={{\n bottom: fabEdgeInset,\n right: fabEdgeInset,\n alignItems: 'end',\n zIndex: theme.zIndex.tooltip,\n display: 'flex',\n position: 'fixed',\n 'body.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: DOCKED_CONTENT_OFFSET,\n },\n }}\n id={LIGHTSPEED_FAB_ELEMENT_ID}\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')}\n placement=\"left\"\n >\n <Fab\n color=\"inherit\"\n variant=\"circular\"\n size=\"large\"\n onClick={toggleChatbot}\n aria-label={\n isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')\n }\n sx={{\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n border: `1px solid ${theme.palette.divider}`,\n '&:hover': {\n backgroundColor: theme.palette.background.paper,\n },\n }}\n >\n {isChatbotActive ? <LightspeedFABOpenIcon /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedFABContent.esm.js","sources":["../../src/components/LightspeedFABContent.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 { useLayoutEffect, useRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Fab from '@mui/material/Fab';\nimport { useTheme } from '@mui/material/styles';\nimport Tooltip from '@mui/material/Tooltip';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { DOCKED_CONTENT_OFFSET, LIGHTSPEED_FAB_ELEMENT_ID } from '../const';\nimport { useIaChatPermission } from '../hooks/useIaChatPermission';\nimport { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission';\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\nimport { useTranslation } from '../hooks/useTranslation';\nimport {\n clearLightspeedFabAnchorVars,\n getLightspeedFabEdgeInset,\n publishLightspeedFabAnchorVars,\n} from '../utils/fab-anchor-utils';\nimport { LightspeedFABIcon, LightspeedFABOpenIcon } from './LightspeedIcon';\n\nexport const LightspeedFABContent = () => {\n const { t } = useTranslation();\n const theme = useTheme();\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const { allowed: hasChatAccess, loading: chatPermissionLoading } =\n useIaChatPermission();\n const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } =\n useIaNotebooksPermission();\n\n const permissionsLoading =\n chatPermissionLoading || notebooksPermissionLoading;\n const hasPluginAccess = hasChatAccess || hasNotebooksAccess;\n const fabRef = useRef<HTMLDivElement>(null);\n const fabEdgeInset = getLightspeedFabEdgeInset(theme);\n\n useLayoutEffect(() => {\n const fab = fabRef.current;\n if (!fab) {\n return undefined;\n }\n\n const syncAnchor = () =>\n publishLightspeedFabAnchorVars({ fabElement: fab, theme });\n syncAnchor();\n\n const resizeObserver =\n typeof ResizeObserver === 'function'\n ? new ResizeObserver(syncAnchor)\n : undefined;\n resizeObserver?.observe(fab);\n\n window.addEventListener('resize', syncAnchor);\n fab.addEventListener('transitionend', syncAnchor);\n const mutationObserver = new MutationObserver(syncAnchor);\n mutationObserver.observe(document.body, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n return () => {\n resizeObserver?.disconnect();\n window.removeEventListener('resize', syncAnchor);\n fab.removeEventListener('transitionend', syncAnchor);\n mutationObserver.disconnect();\n clearLightspeedFabAnchorVars();\n };\n }, [displayMode, theme]);\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n if (permissionsLoading || !hasPluginAccess) {\n return null;\n }\n\n return (\n <Box\n ref={fabRef}\n sx={{\n bottom: fabEdgeInset,\n right: fabEdgeInset,\n alignItems: 'end',\n zIndex: theme.zIndex.tooltip,\n display: 'flex',\n position: 'fixed',\n 'body.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: DOCKED_CONTENT_OFFSET,\n },\n }}\n id={LIGHTSPEED_FAB_ELEMENT_ID}\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')}\n placement=\"left\"\n >\n <Fab\n color=\"inherit\"\n variant=\"circular\"\n size=\"large\"\n onClick={toggleChatbot}\n aria-label={\n isChatbotActive ? t('tooltip.fab.close') : t('tooltip.fab.open')\n }\n sx={{\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n border: `1px solid ${theme.palette.divider}`,\n '&:hover': {\n backgroundColor: theme.palette.background.paper,\n },\n }}\n >\n {isChatbotActive ? <LightspeedFABOpenIcon /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,19 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { Page, Header, Content } from '@backstage/core-components';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { ErrorPage, Page, Header, Content } from '@backstage/core-components';
3
+ import { useIaChatPermission } from '../hooks/useIaChatPermission.esm.js';
4
+ import { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission.esm.js';
3
5
  import { useTranslation } from '../hooks/useTranslation.esm.js';
4
6
  import { LightspeedChatContainer } from './LightspeedChatContainer.esm.js';
5
7
 
6
8
  const LightspeedPage = () => {
7
9
  const { t } = useTranslation();
10
+ const { allowed: hasChatAccess, loading: chatPermissionLoading } = useIaChatPermission();
11
+ const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } = useIaNotebooksPermission();
12
+ const permissionsLoading = chatPermissionLoading || notebooksPermissionLoading;
13
+ const hasPluginAccess = hasChatAccess || hasNotebooksAccess;
14
+ if (!permissionsLoading && !hasPluginAccess) {
15
+ return /* @__PURE__ */ jsx(ErrorPage, { status: "404", statusMessage: "Page not found" });
16
+ }
8
17
  return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
9
18
  /* @__PURE__ */ jsx(
10
19
  Header,
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.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 { Content, Header, Page } from '@backstage/core-components';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\n\n/**\n * Lightspeed Page - Routable fullscreen/embedded mode\n * @public\n */\nexport const LightspeedPage = () => {\n const { t } = useTranslation();\n\n return (\n <Page themeId=\"tool\">\n <Header\n title={t('page.title')}\n style={{ display: 'none' }}\n pageTitleOverride={t('page.title')}\n />\n <Content noPadding>\n <LightspeedChatContainer />\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;AAyBO,MAAM,iBAAiB,MAAM;AAClC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAE7B,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,MAAA,EACZ,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,YAAY,CAAA;AAAA,QACrB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAO;AAAA,QACzB,iBAAA,EAAmB,EAAE,YAAY;AAAA;AAAA,KACnC;AAAA,wBACC,OAAA,EAAA,EAAQ,SAAA,EAAS,IAAA,EAChB,QAAA,kBAAA,GAAA,CAAC,2BAAwB,CAAA,EAC3B;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.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 { Content, ErrorPage, Header, Page } from '@backstage/core-components';\n\nimport { useIaChatPermission } from '../hooks/useIaChatPermission';\nimport { useIaNotebooksPermission } from '../hooks/useIaNotebooksPermission';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\n\n/**\n * Lightspeed Page - Routable fullscreen/embedded mode\n * @public\n */\nexport const LightspeedPage = () => {\n const { t } = useTranslation();\n const { allowed: hasChatAccess, loading: chatPermissionLoading } =\n useIaChatPermission();\n const { allowed: hasNotebooksAccess, loading: notebooksPermissionLoading } =\n useIaNotebooksPermission();\n\n const permissionsLoading =\n chatPermissionLoading || notebooksPermissionLoading;\n const hasPluginAccess = hasChatAccess || hasNotebooksAccess;\n\n if (!permissionsLoading && !hasPluginAccess) {\n return <ErrorPage status=\"404\" statusMessage=\"Page not found\" />;\n }\n\n return (\n <Page themeId=\"tool\">\n <Header\n title={t('page.title')}\n style={{ display: 'none' }}\n pageTitleOverride={t('page.title')}\n />\n <Content noPadding>\n <LightspeedChatContainer />\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2BO,MAAM,iBAAiB,MAAM;AAClC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAe,OAAA,EAAS,qBAAA,KACvC,mBAAA,EAAoB;AACtB,EAAA,MAAM,EAAE,OAAA,EAAS,kBAAA,EAAoB,OAAA,EAAS,0BAAA,KAC5C,wBAAA,EAAyB;AAE3B,EAAA,MAAM,qBACJ,qBAAA,IAAyB,0BAAA;AAC3B,EAAA,MAAM,kBAAkB,aAAA,IAAiB,kBAAA;AAEzC,EAAA,IAAI,CAAC,kBAAA,IAAsB,CAAC,eAAA,EAAiB;AAC3C,IAAA,uBAAO,GAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAO,KAAA,EAAM,eAAc,gBAAA,EAAiB,CAAA;AAAA,EAChE;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,MAAA,EACZ,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,YAAY,CAAA;AAAA,QACrB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAO;AAAA,QACzB,iBAAA,EAAmB,EAAE,YAAY;AAAA;AAAA,KACnC;AAAA,wBACC,OAAA,EAAA,EAAQ,SAAA,EAAS,IAAA,EAChB,QAAA,kBAAA,GAAA,CAAC,2BAAwB,CAAA,EAC3B;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
@@ -68,7 +68,6 @@ const McpConfigureServerModal = ({
68
68
  close,
69
69
  save,
70
70
  removePersonalToken,
71
- canManageMcp,
72
71
  configureModalTitle,
73
72
  isConfigureModalSaving,
74
73
  isSaveTokenButtonDisabled,
@@ -375,7 +374,7 @@ const McpConfigureServerModal = ({
375
374
  {
376
375
  variant: "primary",
377
376
  onClick: () => void save(),
378
- isDisabled: !canManageMcp || isConfigureModalSaving || tokenValidationState === "validating" || isSaveTokenButtonDisabled || isUpdatingModalStatus,
377
+ isDisabled: isConfigureModalSaving || tokenValidationState === "validating" || isSaveTokenButtonDisabled || isUpdatingModalStatus,
379
378
  children: t("modal.save")
380
379
  }
381
380
  ),
@@ -385,7 +384,7 @@ const McpConfigureServerModal = ({
385
384
  variant: "secondary",
386
385
  isDanger: true,
387
386
  onClick: () => void removePersonalToken(),
388
- isDisabled: !canManageMcp || isConfigureModalSaving || tokenValidationState === "validating" || isUpdatingModalStatus || hasRemovedPersonalToken || !hasSavedTokenInModal,
387
+ isDisabled: isConfigureModalSaving || tokenValidationState === "validating" || isUpdatingModalStatus || hasRemovedPersonalToken || !hasSavedTokenInModal,
389
388
  children: t("mcp.settings.removePersonalToken")
390
389
  }
391
390
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"McpConfigureServerModal.esm.js","sources":["../../src/components/McpConfigureServerModal.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 { styled } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport {\n Alert,\n Button,\n Flex,\n FlexItem,\n Form,\n FormGroup,\n FormHelperText,\n HelperText,\n HelperTextItem,\n List,\n ListItem,\n Modal,\n ModalBody,\n ModalFooter,\n ModalHeader,\n Radio,\n Spinner,\n Stack,\n StackItem,\n Switch,\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Tooltip,\n} from '@patternfly/react-core';\nimport {\n CheckCircleIcon,\n ExclamationCircleIcon,\n InfoCircleIcon,\n KeyIcon,\n TimesIcon,\n} from '@patternfly/react-icons';\n\nimport { type UseMcpConfigureModalResult } from '../hooks/useMcpConfigureModal';\nimport { useTranslation } from '../hooks/useTranslation';\n\nconst StyledModal = styled(Modal)({\n '& .pf-v6-c-modal-box__close, & .pf-v5-c-modal-box__close': {\n display: 'none',\n },\n '& .pf-v6-c-modal-box__body, & .pf-v5-c-modal-box__body': {\n paddingTop: 0,\n },\n '& .ia-mcp-modal-close': {\n position: 'absolute',\n insetBlockStart: 'var(--pf-v6-c-modal-box__close--InsetBlockStart, 1.5rem)',\n insetInlineEnd: 'var(--pf-v6-c-modal-box__close--InsetInlineEnd, 1.5rem)',\n zIndex: 1,\n },\n});\n\nconst ModalInfoAlert = styled(Alert)({\n '--pf-v6-c-alert--m-custom--BorderColor':\n 'var(--pf-t--global--color--status--info--default)',\n '--pf-v6-c-alert--m-custom__icon--Color':\n 'var(--pf-t--global--color--status--info--default)',\n '& .pf-v6-c-alert__icon': {\n alignSelf: 'start',\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'center',\n boxSizing: 'border-box',\n marginBlockStart: 0,\n paddingBlockStart: '18.620px',\n paddingInline: 'var(--pf-t--global--spacer--md)',\n paddingBlockEnd: 'var(--pf-t--global--spacer--md)',\n },\n});\n\nconst sectionTitleSx = {\n fontSize: '0.875rem',\n fontWeight: 600,\n} as const;\n\nconst sectionDescriptionSx = {\n color: 'var(--pf-t--global--text--color--subtle)',\n fontSize: '0.875rem',\n} as const;\n\nconst credentialRadioDescriptionSx = {\n color: 'var(--pf-t--global--text--color--subtle)',\n fontSize: '0.875rem',\n} as const;\n\nconst StatusOkIcon = styled(CheckCircleIcon)({\n color: 'var(--pf-t--global--icon--color--status--custom--default)',\n});\n\nconst StatusWarnIcon = styled(ExclamationCircleIcon)({\n color: 'var(--pf-t--global--icon--color--status--danger--default)',\n});\n\nconst StatusDisabledIcon = styled(InfoCircleIcon)({\n color: 'var(--pf-t--global--icon--color--subtle)',\n});\n\nconst StatusWarnKeyIcon = styled(KeyIcon)({\n color: 'var(--pf-t--global--icon--color--status--danger--default)',\n});\n\nconst RemovePersonalTokenButton = styled(Button)({\n borderRadius: '1.25rem',\n boxShadow: 'none',\n});\n\ntype McpConfigureServerModalProps = UseMcpConfigureModalResult;\n\nexport const McpConfigureServerModal = ({\n isOpen,\n editingServer,\n close,\n save,\n removePersonalToken,\n canManageMcp,\n configureModalTitle,\n isConfigureModalSaving,\n isSaveTokenButtonDisabled,\n isUpdatingModalStatus,\n tokenInputValue,\n onTokenInputChange,\n clearTokenInput,\n tokenInputValidated,\n tokenValidationState,\n tokenHelperVariant,\n showTokenHelperText,\n tokenHelperText,\n modalCredentialMode,\n onCredentialModeChange,\n showCredentialRadios,\n showPersonalTokenField,\n onModalEnabledChange,\n isModalEnabledChecked,\n isModalEnabledToggleDisabled,\n modalDisplayStatus,\n modalStatusDetail,\n modalStatusText,\n modalTools,\n modalToolCount,\n isLoadingModalTools,\n modalToolsError,\n modalToolsEmptyText,\n modalVerifiedHasToken,\n modalEnabledDescription,\n canRemovePersonalToken,\n hasSavedTokenInModal,\n hasRemovedPersonalToken,\n}: McpConfigureServerModalProps) => {\n const { t } = useTranslation();\n\n const renderStatusIcon = () => {\n if (isUpdatingModalStatus || isLoadingModalTools) {\n return (\n <Spinner\n size=\"md\"\n aria-label={\n isUpdatingModalStatus\n ? t('mcp.settings.modal.loadingStatus')\n : t('mcp.settings.modal.fetchingStatus')\n }\n />\n );\n }\n if (modalDisplayStatus === 'disabled') {\n return <StatusDisabledIcon />;\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return <StatusWarnKeyIcon />;\n }\n if (modalDisplayStatus === 'ok' && modalTools.length > 0) {\n return <StatusOkIcon />;\n }\n if (modalToolsError || modalDisplayStatus === 'failed') {\n return <StatusWarnIcon />;\n }\n return <StatusDisabledIcon />;\n };\n\n const renderToolsContent = () => {\n if (isLoadingModalTools) {\n return (\n <Spinner size=\"md\" aria-label={t('mcp.settings.modal.loadingTools')} />\n );\n }\n if (modalTools.length > 0) {\n return (\n <List\n isPlain\n aria-label={t('mcp.settings.modal.toolsHeading' as any, {\n count: String(modalToolCount),\n })}\n >\n {modalTools.map(toolName => (\n <ListItem key={toolName} icon={<StatusOkIcon />}>\n {toolName}\n </ListItem>\n ))}\n </List>\n );\n }\n return (\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mt-xs\"\n sx={sectionDescriptionSx}\n >\n {modalToolsEmptyText}\n </Typography>\n );\n };\n\n const enabledSwitch = (\n <Switch\n id=\"mcp-configure-enabled-switch\"\n aria-label={t('mcp.settings.toggleServerAriaLabel' as any, {\n serverName: editingServer?.name ?? '',\n })}\n isChecked={isModalEnabledChecked}\n isDisabled={isModalEnabledToggleDisabled}\n onChange={onModalEnabledChange}\n />\n );\n\n return (\n <StyledModal\n variant=\"small\"\n width={608}\n isOpen={isOpen}\n onClose={close}\n aria-labelledby=\"mcp-configure-modal\"\n aria-describedby=\"mcp-configure-modal-body\"\n >\n <ModalHeader\n title={configureModalTitle}\n labelId=\"mcp-configure-modal\"\n descriptorId=\"mcp-configure-modal-body\"\n />\n <Button\n className=\"ia-mcp-modal-close\"\n variant=\"plain\"\n icon={<TimesIcon />}\n aria-label={t('mcp.settings.closeConfigureModalAriaLabel')}\n onClick={close}\n />\n <ModalBody id=\"mcp-configure-modal-body\">\n <Stack hasGutter>\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modalDescription')}\n isInline\n />\n </StackItem>\n {editingServer?.auth === 'dcr' && (\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modalDescriptionDcr')}\n isInline\n />\n </StackItem>\n )}\n {hasRemovedPersonalToken && !editingServer?.hasOrgToken && (\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modal.tokenRemovedWarning')}\n isInline\n />\n </StackItem>\n )}\n <StackItem>\n <Typography\n component=\"div\"\n sx={sectionTitleSx}\n className=\"pf-v6-u-mb-sm\"\n >\n {t('mcp.settings.status')}\n </Typography>\n <Flex\n alignItems={{ default: 'alignItemsCenter' }}\n spaceItems={{ default: 'spaceItemsSm' }}\n >\n <FlexItem>{renderStatusIcon()}</FlexItem>\n <FlexItem>\n <Typography component=\"span\">{modalStatusText}</Typography>\n </FlexItem>\n </Flex>\n </StackItem>\n {modalVerifiedHasToken && modalDisplayStatus === 'ok' && (\n <StackItem>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mb-sm\"\n sx={sectionTitleSx}\n >\n {t('mcp.settings.modal.toolsHeading' as any, {\n count: String(modalToolCount),\n })}\n </Typography>\n {renderToolsContent()}\n </StackItem>\n )}\n <StackItem>\n <Flex\n justifyContent={{ default: 'justifyContentSpaceBetween' }}\n alignItems={{ default: 'alignItemsFlexStart' }}\n spaceItems={{ default: 'spaceItemsMd' }}\n >\n <FlexItem flex={{ default: 'flex_1' }}>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mb-sm\"\n sx={sectionTitleSx}\n >\n {t('mcp.settings.enabled')}\n </Typography>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mt-xs\"\n sx={sectionDescriptionSx}\n >\n {modalEnabledDescription}\n </Typography>\n </FlexItem>\n <FlexItem>\n {isModalEnabledToggleDisabled ? (\n <Tooltip content={modalStatusDetail}>\n <Typography component=\"span\">{enabledSwitch}</Typography>\n </Tooltip>\n ) : (\n enabledSwitch\n )}\n </FlexItem>\n </Flex>\n </StackItem>\n {(showCredentialRadios || showPersonalTokenField) && (\n <StackItem>\n <Form>\n {showCredentialRadios && (\n <FormGroup\n role=\"radiogroup\"\n id=\"mcp-credential-mode\"\n fieldId=\"mcp-credential-mode\"\n label={t('mcp.settings.modal.authenticationHeading')}\n >\n <Stack hasGutter>\n <StackItem>\n <Radio\n id=\"mcp-credential-organization\"\n name=\"mcp-credential-mode\"\n label={t(\n 'mcp.settings.modal.credentialMode.organization',\n )}\n isChecked={modalCredentialMode === 'organization'}\n onChange={() =>\n onCredentialModeChange('organization')\n }\n />\n <Typography\n component=\"div\"\n className=\"pf-v6-u-ml-xl pf-v6-u-mt-xs\"\n sx={credentialRadioDescriptionSx}\n >\n {t(\n 'mcp.settings.modal.credentialMode.organizationDescription',\n )}\n </Typography>\n </StackItem>\n <StackItem>\n <Radio\n id=\"mcp-credential-personal\"\n name=\"mcp-credential-mode\"\n label={t(\n 'mcp.settings.modal.credentialMode.personal',\n )}\n isChecked={modalCredentialMode === 'personal'}\n onChange={() => onCredentialModeChange('personal')}\n />\n </StackItem>\n </Stack>\n </FormGroup>\n )}\n {showPersonalTokenField && (\n <FormGroup\n label={t('mcp.settings.authenticationToken')}\n fieldId=\"mcp-pat-input\"\n >\n <TextInputGroup validated={tokenInputValidated}>\n <TextInputGroupMain\n inputId=\"mcp-pat-input\"\n type=\"password\"\n value={tokenInputValue}\n onChange={(_event, value) => onTokenInputChange(value)}\n />\n {(tokenValidationState === 'idle' ||\n tokenValidationState === 'validating') && (\n <TextInputGroupUtilities>\n <Button\n variant=\"plain\"\n onClick={clearTokenInput}\n aria-label={t('mcp.settings.token.clearAriaLabel')}\n icon={<TimesIcon />}\n />\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n {showTokenHelperText && (\n <FormHelperText>\n <HelperText>\n <HelperTextItem variant={tokenHelperVariant}>\n {tokenHelperText}\n </HelperTextItem>\n </HelperText>\n </FormHelperText>\n )}\n </FormGroup>\n )}\n </Form>\n </StackItem>\n )}\n </Stack>\n </ModalBody>\n <ModalFooter>\n <Button\n variant=\"primary\"\n onClick={() => void save()}\n isDisabled={\n !canManageMcp ||\n isConfigureModalSaving ||\n tokenValidationState === 'validating' ||\n isSaveTokenButtonDisabled ||\n isUpdatingModalStatus\n }\n >\n {t('modal.save')}\n </Button>\n {canRemovePersonalToken && (\n <RemovePersonalTokenButton\n variant=\"secondary\"\n isDanger\n onClick={() => void removePersonalToken()}\n isDisabled={\n !canManageMcp ||\n isConfigureModalSaving ||\n tokenValidationState === 'validating' ||\n isUpdatingModalStatus ||\n hasRemovedPersonalToken ||\n !hasSavedTokenInModal\n }\n >\n {t('mcp.settings.removePersonalToken')}\n </RemovePersonalTokenButton>\n )}\n <Button variant=\"link\" onClick={close}>\n {t('common.cancel')}\n </Button>\n </ModalFooter>\n </StyledModal>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"McpConfigureServerModal.esm.js","sources":["../../src/components/McpConfigureServerModal.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 { styled } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport {\n Alert,\n Button,\n Flex,\n FlexItem,\n Form,\n FormGroup,\n FormHelperText,\n HelperText,\n HelperTextItem,\n List,\n ListItem,\n Modal,\n ModalBody,\n ModalFooter,\n ModalHeader,\n Radio,\n Spinner,\n Stack,\n StackItem,\n Switch,\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Tooltip,\n} from '@patternfly/react-core';\nimport {\n CheckCircleIcon,\n ExclamationCircleIcon,\n InfoCircleIcon,\n KeyIcon,\n TimesIcon,\n} from '@patternfly/react-icons';\n\nimport { type UseMcpConfigureModalResult } from '../hooks/useMcpConfigureModal';\nimport { useTranslation } from '../hooks/useTranslation';\n\nconst StyledModal = styled(Modal)({\n '& .pf-v6-c-modal-box__close, & .pf-v5-c-modal-box__close': {\n display: 'none',\n },\n '& .pf-v6-c-modal-box__body, & .pf-v5-c-modal-box__body': {\n paddingTop: 0,\n },\n '& .ia-mcp-modal-close': {\n position: 'absolute',\n insetBlockStart: 'var(--pf-v6-c-modal-box__close--InsetBlockStart, 1.5rem)',\n insetInlineEnd: 'var(--pf-v6-c-modal-box__close--InsetInlineEnd, 1.5rem)',\n zIndex: 1,\n },\n});\n\nconst ModalInfoAlert = styled(Alert)({\n '--pf-v6-c-alert--m-custom--BorderColor':\n 'var(--pf-t--global--color--status--info--default)',\n '--pf-v6-c-alert--m-custom__icon--Color':\n 'var(--pf-t--global--color--status--info--default)',\n '& .pf-v6-c-alert__icon': {\n alignSelf: 'start',\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'center',\n boxSizing: 'border-box',\n marginBlockStart: 0,\n paddingBlockStart: '18.620px',\n paddingInline: 'var(--pf-t--global--spacer--md)',\n paddingBlockEnd: 'var(--pf-t--global--spacer--md)',\n },\n});\n\nconst sectionTitleSx = {\n fontSize: '0.875rem',\n fontWeight: 600,\n} as const;\n\nconst sectionDescriptionSx = {\n color: 'var(--pf-t--global--text--color--subtle)',\n fontSize: '0.875rem',\n} as const;\n\nconst credentialRadioDescriptionSx = {\n color: 'var(--pf-t--global--text--color--subtle)',\n fontSize: '0.875rem',\n} as const;\n\nconst StatusOkIcon = styled(CheckCircleIcon)({\n color: 'var(--pf-t--global--icon--color--status--custom--default)',\n});\n\nconst StatusWarnIcon = styled(ExclamationCircleIcon)({\n color: 'var(--pf-t--global--icon--color--status--danger--default)',\n});\n\nconst StatusDisabledIcon = styled(InfoCircleIcon)({\n color: 'var(--pf-t--global--icon--color--subtle)',\n});\n\nconst StatusWarnKeyIcon = styled(KeyIcon)({\n color: 'var(--pf-t--global--icon--color--status--danger--default)',\n});\n\nconst RemovePersonalTokenButton = styled(Button)({\n borderRadius: '1.25rem',\n boxShadow: 'none',\n});\n\ntype McpConfigureServerModalProps = UseMcpConfigureModalResult;\n\nexport const McpConfigureServerModal = ({\n isOpen,\n editingServer,\n close,\n save,\n removePersonalToken,\n configureModalTitle,\n isConfigureModalSaving,\n isSaveTokenButtonDisabled,\n isUpdatingModalStatus,\n tokenInputValue,\n onTokenInputChange,\n clearTokenInput,\n tokenInputValidated,\n tokenValidationState,\n tokenHelperVariant,\n showTokenHelperText,\n tokenHelperText,\n modalCredentialMode,\n onCredentialModeChange,\n showCredentialRadios,\n showPersonalTokenField,\n onModalEnabledChange,\n isModalEnabledChecked,\n isModalEnabledToggleDisabled,\n modalDisplayStatus,\n modalStatusDetail,\n modalStatusText,\n modalTools,\n modalToolCount,\n isLoadingModalTools,\n modalToolsError,\n modalToolsEmptyText,\n modalVerifiedHasToken,\n modalEnabledDescription,\n canRemovePersonalToken,\n hasSavedTokenInModal,\n hasRemovedPersonalToken,\n}: McpConfigureServerModalProps) => {\n const { t } = useTranslation();\n\n const renderStatusIcon = () => {\n if (isUpdatingModalStatus || isLoadingModalTools) {\n return (\n <Spinner\n size=\"md\"\n aria-label={\n isUpdatingModalStatus\n ? t('mcp.settings.modal.loadingStatus')\n : t('mcp.settings.modal.fetchingStatus')\n }\n />\n );\n }\n if (modalDisplayStatus === 'disabled') {\n return <StatusDisabledIcon />;\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return <StatusWarnKeyIcon />;\n }\n if (modalDisplayStatus === 'ok' && modalTools.length > 0) {\n return <StatusOkIcon />;\n }\n if (modalToolsError || modalDisplayStatus === 'failed') {\n return <StatusWarnIcon />;\n }\n return <StatusDisabledIcon />;\n };\n\n const renderToolsContent = () => {\n if (isLoadingModalTools) {\n return (\n <Spinner size=\"md\" aria-label={t('mcp.settings.modal.loadingTools')} />\n );\n }\n if (modalTools.length > 0) {\n return (\n <List\n isPlain\n aria-label={t('mcp.settings.modal.toolsHeading' as any, {\n count: String(modalToolCount),\n })}\n >\n {modalTools.map(toolName => (\n <ListItem key={toolName} icon={<StatusOkIcon />}>\n {toolName}\n </ListItem>\n ))}\n </List>\n );\n }\n return (\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mt-xs\"\n sx={sectionDescriptionSx}\n >\n {modalToolsEmptyText}\n </Typography>\n );\n };\n\n const enabledSwitch = (\n <Switch\n id=\"mcp-configure-enabled-switch\"\n aria-label={t('mcp.settings.toggleServerAriaLabel' as any, {\n serverName: editingServer?.name ?? '',\n })}\n isChecked={isModalEnabledChecked}\n isDisabled={isModalEnabledToggleDisabled}\n onChange={onModalEnabledChange}\n />\n );\n\n return (\n <StyledModal\n variant=\"small\"\n width={608}\n isOpen={isOpen}\n onClose={close}\n aria-labelledby=\"mcp-configure-modal\"\n aria-describedby=\"mcp-configure-modal-body\"\n >\n <ModalHeader\n title={configureModalTitle}\n labelId=\"mcp-configure-modal\"\n descriptorId=\"mcp-configure-modal-body\"\n />\n <Button\n className=\"ia-mcp-modal-close\"\n variant=\"plain\"\n icon={<TimesIcon />}\n aria-label={t('mcp.settings.closeConfigureModalAriaLabel')}\n onClick={close}\n />\n <ModalBody id=\"mcp-configure-modal-body\">\n <Stack hasGutter>\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modalDescription')}\n isInline\n />\n </StackItem>\n {editingServer?.auth === 'dcr' && (\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modalDescriptionDcr')}\n isInline\n />\n </StackItem>\n )}\n {hasRemovedPersonalToken && !editingServer?.hasOrgToken && (\n <StackItem>\n <ModalInfoAlert\n variant=\"custom\"\n customIcon={<InfoCircleIcon />}\n title={t('mcp.settings.modal.tokenRemovedWarning')}\n isInline\n />\n </StackItem>\n )}\n <StackItem>\n <Typography\n component=\"div\"\n sx={sectionTitleSx}\n className=\"pf-v6-u-mb-sm\"\n >\n {t('mcp.settings.status')}\n </Typography>\n <Flex\n alignItems={{ default: 'alignItemsCenter' }}\n spaceItems={{ default: 'spaceItemsSm' }}\n >\n <FlexItem>{renderStatusIcon()}</FlexItem>\n <FlexItem>\n <Typography component=\"span\">{modalStatusText}</Typography>\n </FlexItem>\n </Flex>\n </StackItem>\n {modalVerifiedHasToken && modalDisplayStatus === 'ok' && (\n <StackItem>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mb-sm\"\n sx={sectionTitleSx}\n >\n {t('mcp.settings.modal.toolsHeading' as any, {\n count: String(modalToolCount),\n })}\n </Typography>\n {renderToolsContent()}\n </StackItem>\n )}\n <StackItem>\n <Flex\n justifyContent={{ default: 'justifyContentSpaceBetween' }}\n alignItems={{ default: 'alignItemsFlexStart' }}\n spaceItems={{ default: 'spaceItemsMd' }}\n >\n <FlexItem flex={{ default: 'flex_1' }}>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mb-sm\"\n sx={sectionTitleSx}\n >\n {t('mcp.settings.enabled')}\n </Typography>\n <Typography\n component=\"div\"\n className=\"pf-v6-u-mt-xs\"\n sx={sectionDescriptionSx}\n >\n {modalEnabledDescription}\n </Typography>\n </FlexItem>\n <FlexItem>\n {isModalEnabledToggleDisabled ? (\n <Tooltip content={modalStatusDetail}>\n <Typography component=\"span\">{enabledSwitch}</Typography>\n </Tooltip>\n ) : (\n enabledSwitch\n )}\n </FlexItem>\n </Flex>\n </StackItem>\n {(showCredentialRadios || showPersonalTokenField) && (\n <StackItem>\n <Form>\n {showCredentialRadios && (\n <FormGroup\n role=\"radiogroup\"\n id=\"mcp-credential-mode\"\n fieldId=\"mcp-credential-mode\"\n label={t('mcp.settings.modal.authenticationHeading')}\n >\n <Stack hasGutter>\n <StackItem>\n <Radio\n id=\"mcp-credential-organization\"\n name=\"mcp-credential-mode\"\n label={t(\n 'mcp.settings.modal.credentialMode.organization',\n )}\n isChecked={modalCredentialMode === 'organization'}\n onChange={() =>\n onCredentialModeChange('organization')\n }\n />\n <Typography\n component=\"div\"\n className=\"pf-v6-u-ml-xl pf-v6-u-mt-xs\"\n sx={credentialRadioDescriptionSx}\n >\n {t(\n 'mcp.settings.modal.credentialMode.organizationDescription',\n )}\n </Typography>\n </StackItem>\n <StackItem>\n <Radio\n id=\"mcp-credential-personal\"\n name=\"mcp-credential-mode\"\n label={t(\n 'mcp.settings.modal.credentialMode.personal',\n )}\n isChecked={modalCredentialMode === 'personal'}\n onChange={() => onCredentialModeChange('personal')}\n />\n </StackItem>\n </Stack>\n </FormGroup>\n )}\n {showPersonalTokenField && (\n <FormGroup\n label={t('mcp.settings.authenticationToken')}\n fieldId=\"mcp-pat-input\"\n >\n <TextInputGroup validated={tokenInputValidated}>\n <TextInputGroupMain\n inputId=\"mcp-pat-input\"\n type=\"password\"\n value={tokenInputValue}\n onChange={(_event, value) => onTokenInputChange(value)}\n />\n {(tokenValidationState === 'idle' ||\n tokenValidationState === 'validating') && (\n <TextInputGroupUtilities>\n <Button\n variant=\"plain\"\n onClick={clearTokenInput}\n aria-label={t('mcp.settings.token.clearAriaLabel')}\n icon={<TimesIcon />}\n />\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n {showTokenHelperText && (\n <FormHelperText>\n <HelperText>\n <HelperTextItem variant={tokenHelperVariant}>\n {tokenHelperText}\n </HelperTextItem>\n </HelperText>\n </FormHelperText>\n )}\n </FormGroup>\n )}\n </Form>\n </StackItem>\n )}\n </Stack>\n </ModalBody>\n <ModalFooter>\n <Button\n variant=\"primary\"\n onClick={() => void save()}\n isDisabled={\n isConfigureModalSaving ||\n tokenValidationState === 'validating' ||\n isSaveTokenButtonDisabled ||\n isUpdatingModalStatus\n }\n >\n {t('modal.save')}\n </Button>\n {canRemovePersonalToken && (\n <RemovePersonalTokenButton\n variant=\"secondary\"\n isDanger\n onClick={() => void removePersonalToken()}\n isDisabled={\n isConfigureModalSaving ||\n tokenValidationState === 'validating' ||\n isUpdatingModalStatus ||\n hasRemovedPersonalToken ||\n !hasSavedTokenInModal\n }\n >\n {t('mcp.settings.removePersonalToken')}\n </RemovePersonalTokenButton>\n )}\n <Button variant=\"link\" onClick={close}>\n {t('common.cancel')}\n </Button>\n </ModalFooter>\n </StyledModal>\n );\n};\n"],"names":[],"mappings":"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"}