@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.0.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +26 -3
  3. package/dist/alpha.d.ts +37 -7
  4. package/dist/api/LightspeedApiClient.esm.js +57 -0
  5. package/dist/api/LightspeedApiClient.esm.js.map +1 -1
  6. package/dist/api/api.esm.js.map +1 -1
  7. package/dist/components/DeleteModal.esm.js +2 -0
  8. package/dist/components/DeleteModal.esm.js.map +1 -1
  9. package/dist/components/DeleteSavedPromptModal.esm.js +75 -0
  10. package/dist/components/DeleteSavedPromptModal.esm.js.map +1 -0
  11. package/dist/components/LightSpeedChat.esm.js +296 -168
  12. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatBoxHeader.esm.js +29 -1
  14. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  15. package/dist/components/LightspeedChatContainer.esm.js +38 -60
  16. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  17. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  18. package/dist/components/LightspeedFABContent.esm.js +9 -0
  19. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  20. package/dist/components/LightspeedPage.esm.js +11 -2
  21. package/dist/components/LightspeedPage.esm.js.map +1 -1
  22. package/dist/components/McpConfigureServerModal.esm.js +2 -3
  23. package/dist/components/McpConfigureServerModal.esm.js.map +1 -1
  24. package/dist/components/McpServersSettings.esm.js +33 -60
  25. package/dist/components/McpServersSettings.esm.js.map +1 -1
  26. package/dist/components/SavedPromptCard.esm.js +100 -0
  27. package/dist/components/SavedPromptCard.esm.js.map +1 -0
  28. package/dist/components/SavedPromptKebabMenu.esm.js +87 -0
  29. package/dist/components/SavedPromptKebabMenu.esm.js.map +1 -0
  30. package/dist/components/SavedPromptMenuItems.esm.js +52 -0
  31. package/dist/components/SavedPromptMenuItems.esm.js.map +1 -0
  32. package/dist/components/SavedPromptsEmptyState.esm.js +63 -0
  33. package/dist/components/SavedPromptsEmptyState.esm.js.map +1 -0
  34. package/dist/components/SavedPromptsList.esm.js +63 -0
  35. package/dist/components/SavedPromptsList.esm.js.map +1 -0
  36. package/dist/components/SavedPromptsSettings.esm.js +285 -0
  37. package/dist/components/SavedPromptsSettings.esm.js.map +1 -0
  38. package/dist/components/SettingsPanel.esm.js +135 -0
  39. package/dist/components/SettingsPanel.esm.js.map +1 -0
  40. package/dist/hooks/useAllModels.esm.js +2 -1
  41. package/dist/hooks/useAllModels.esm.js.map +1 -1
  42. package/dist/hooks/useConversationHistoryGroups.esm.js +71 -0
  43. package/dist/hooks/useConversationHistoryGroups.esm.js.map +1 -0
  44. package/dist/hooks/useConversations.esm.js +2 -1
  45. package/dist/hooks/useConversations.esm.js.map +1 -1
  46. package/dist/hooks/useFeedbackActions.esm.js.map +1 -1
  47. package/dist/hooks/useIaChatPermission.esm.js +15 -0
  48. package/dist/hooks/useIaChatPermission.esm.js.map +1 -0
  49. package/dist/hooks/useIaMcpToolsPermission.esm.js +15 -0
  50. package/dist/hooks/useIaMcpToolsPermission.esm.js.map +1 -0
  51. package/dist/hooks/{notebooks/useLightspeedNotebooksPermission.esm.js → useIaNotebooksPermission.esm.js} +4 -5
  52. package/dist/hooks/useIaNotebooksPermission.esm.js.map +1 -0
  53. package/dist/hooks/useLightspeedProviderState.esm.js +19 -5
  54. package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -1
  55. package/dist/hooks/useMcpConfigureModal.esm.js +5 -9
  56. package/dist/hooks/useMcpConfigureModal.esm.js.map +1 -1
  57. package/dist/hooks/useNotebookConversationIds.esm.js +2 -1
  58. package/dist/hooks/useNotebookConversationIds.esm.js.map +1 -1
  59. package/dist/hooks/useQuestionValidation.esm.js +3 -2
  60. package/dist/hooks/useQuestionValidation.esm.js.map +1 -1
  61. package/dist/hooks/useSavedPromptActions.esm.js +64 -0
  62. package/dist/hooks/useSavedPromptActions.esm.js.map +1 -0
  63. package/dist/hooks/useSavedPrompts.esm.js +75 -0
  64. package/dist/hooks/useSavedPrompts.esm.js.map +1 -0
  65. package/dist/hooks/useSavedPromptsSettings.esm.js +65 -0
  66. package/dist/hooks/useSavedPromptsSettings.esm.js.map +1 -0
  67. package/dist/hooks/useSettingsPanelUrlState.esm.js +95 -0
  68. package/dist/hooks/useSettingsPanelUrlState.esm.js.map +1 -0
  69. package/dist/hooks/useWelcomePrompts.esm.js +17 -6
  70. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  71. package/dist/translations/de.esm.js +40 -8
  72. package/dist/translations/de.esm.js.map +1 -1
  73. package/dist/translations/es.esm.js +40 -8
  74. package/dist/translations/es.esm.js.map +1 -1
  75. package/dist/translations/fr.esm.js +40 -8
  76. package/dist/translations/fr.esm.js.map +1 -1
  77. package/dist/translations/it.esm.js +40 -8
  78. package/dist/translations/it.esm.js.map +1 -1
  79. package/dist/translations/ja.esm.js +40 -8
  80. package/dist/translations/ja.esm.js.map +1 -1
  81. package/dist/translations/ref.esm.js +40 -10
  82. package/dist/translations/ref.esm.js.map +1 -1
  83. package/dist/utils/buildConversationHistoryGroups.esm.js +241 -0
  84. package/dist/utils/buildConversationHistoryGroups.esm.js.map +1 -0
  85. package/dist/utils/prompt-utils.esm.js +18 -1
  86. package/dist/utils/prompt-utils.esm.js.map +1 -1
  87. package/package.json +5 -14
  88. package/dist/components/PermissionRequiredIcon.esm.js +0 -18
  89. package/dist/components/PermissionRequiredIcon.esm.js.map +0 -1
  90. package/dist/components/PermissionRequiredState.esm.js +0 -88
  91. package/dist/components/PermissionRequiredState.esm.js.map +0 -1
  92. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +0 -1
  93. package/dist/hooks/useLightspeedDeletePermission.esm.js +0 -12
  94. package/dist/hooks/useLightspeedDeletePermission.esm.js.map +0 -1
  95. package/dist/hooks/useLightspeedUpdatePermission.esm.js +0 -12
  96. package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +0 -1
  97. package/dist/hooks/useLightspeedViewPermission.esm.js +0 -16
  98. package/dist/hooks/useLightspeedViewPermission.esm.js.map +0 -1
  99. package/dist/images/permission-required.svg +0 -319
@@ -1 +1 @@
1
- {"version":3,"file":"useLightspeedProviderState.esm.js","sources":["../../src/hooks/useLightspeedProviderState.ts"],"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 { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation, useMatch, useNavigate } from 'react-router-dom';\n\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { useAppDrawer } from '@red-hat-developer-hub/backstage-plugin-app-react';\n\nimport type {\n LightspeedDrawerContextType,\n LightspeedEmbeddedNotebooksTarget,\n} from '../components/LightspeedDrawerContext';\nimport { LIGHTSPEED_APP_DRAWER_ID, LIGHTSPEED_PATH } from '../const';\nimport type { FileContent } from '../types';\nimport { useBackstageUserIdentity } from './useBackstageUserIdentity';\nimport { useDisplayModeSettings } from './useDisplayModeSettings';\n\nfunction lightspeedRoutePath(conversationId?: string): string {\n return conversationId\n ? `${LIGHTSPEED_PATH}/conversation/${conversationId}`\n : LIGHTSPEED_PATH;\n}\n\n/**\n * Encapsulates LightspeedDrawerProvider state, routing, and ApplicationDrawer sync.\n *\n * @internal\n */\nexport function useLightspeedProviderState(): {\n contextValue: LightspeedDrawerContextType;\n shouldRenderOverlayModal: boolean;\n closeChatbot: () => void;\n} {\n const navigate = useNavigate();\n const location = useLocation();\n const { openDrawer, closeDrawer } = useAppDrawer();\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(false);\n const [drawerWidth, setDrawerWidth] = useState(400);\n const [currentConversationIdState, setCurrentConversationIdState] = useState<\n string | undefined\n >(undefined);\n const [draftMessage, setDraftMessageState] = useState('');\n const [draftFileContents, setDraftFileContentsState] = useState<\n FileContent[]\n >([]);\n const [shellViewTab, setShellViewTabState] = useState(0);\n const [activeNotebookId, setActiveNotebookId] = useState<string | undefined>(\n undefined,\n );\n const shellViewTabRef = useRef(shellViewTab);\n shellViewTabRef.current = shellViewTab;\n const setShellViewTab = useCallback((tab: number) => {\n const next = tab === 1 ? 1 : 0;\n shellViewTabRef.current = next;\n setShellViewTabState(next);\n }, []);\n const openedViaFABRef = useRef(false);\n const dockedAfterLeavingFullscreenRef = useRef(false);\n /** True while navigating off /lightspeed after user chose overlay/docked (URL can lag persisted mode). */\n const leavingLightspeedForNonEmbeddedShellRef = useRef(false);\n /** True until overlay/docked LightspeedChat consumes it (new mount after leaving fullscreen route). */\n const pendingOverlayThreadHandoffRef = useRef(false);\n /** Used to detect in-app moves (e.g. Chat ↔ Notebooks) so display mode is not reset to embedded. */\n const lightspeedPathnamePrevRef = useRef<string | null>(null);\n\n const isLightspeedRouteRef = useRef(false);\n const isOnNotebooksPathRef = useRef(false);\n const persistedDisplayModeRef = useRef(persistedDisplayMode);\n\n const isLightspeedRoute = location.pathname.startsWith(LIGHTSPEED_PATH);\n isLightspeedRouteRef.current = isLightspeedRoute;\n isOnNotebooksPathRef.current = location.pathname.startsWith(\n `${LIGHTSPEED_PATH}/notebooks`,\n );\n persistedDisplayModeRef.current = persistedDisplayMode;\n const conversationMatch = useMatch(\n `${LIGHTSPEED_PATH}/conversation/:conversationId`,\n );\n const conversationId = conversationMatch?.params?.conversationId;\n\n const syncShellDrawerForMode = useCallback(\n (mode: ChatbotDisplayMode) => {\n if (mode === ChatbotDisplayMode.docked) {\n if (isLightspeedRoute) {\n dockedAfterLeavingFullscreenRef.current = true;\n } else {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n } else {\n dockedAfterLeavingFullscreenRef.current = false;\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n },\n [closeDrawer, isLightspeedRoute, openDrawer],\n );\n\n const navigateBackOrGoToCatalog = useCallback(() => {\n if (!openedViaFABRef.current) {\n navigate('/catalog');\n openedViaFABRef.current = true;\n return;\n }\n navigate(-1);\n }, [navigate]);\n\n /**\n * Leaving /lightspeed for overlay/docked must not use navigate(-1): after the first FAB\n * open, navigateBackOrGoToCatalog uses -1 and can land back on /lightspeed (fullscreen).\n */\n const leaveLightspeedRouteForShellDisplayMode = useCallback(() => {\n navigate('/catalog', { replace: true });\n }, [navigate]);\n\n useEffect(() => {\n const pathname = location.pathname;\n const prevPathname = lightspeedPathnamePrevRef.current;\n const isUnderLightspeedPath = (p: string | null) =>\n Boolean(p && p.startsWith(LIGHTSPEED_PATH));\n const isInternalLightspeedRouteChange =\n isUnderLightspeedPath(prevPathname) &&\n isUnderLightspeedPath(pathname) &&\n prevPathname !== pathname;\n\n if (!isLightspeedRoute) {\n leavingLightspeedForNonEmbeddedShellRef.current = false;\n }\n\n if (conversationId) {\n setCurrentConversationIdState(conversationId);\n } else if (isLightspeedRoute) {\n // On `/lightspeed` without a `:conversationId` segment, URL implies a fresh thread.\n // When navigating to another app route (overlay/docked), keep the last id so display\n // mode switches and re-entry to fullscreen stay on the active conversation.\n setCurrentConversationIdState(undefined);\n }\n\n if (isLightspeedRoute) {\n if (!isInternalLightspeedRouteChange) {\n if (\n leavingLightspeedForNonEmbeddedShellRef.current &&\n persistedDisplayMode !== ChatbotDisplayMode.embedded\n ) {\n setDisplayModeState(persistedDisplayMode);\n } else {\n setDisplayModeState(ChatbotDisplayMode.embedded);\n }\n }\n setIsOpen(true);\n if (!dockedAfterLeavingFullscreenRef.current) {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n } else if (persistedDisplayMode === ChatbotDisplayMode.embedded) {\n // Off /lightspeed there is no fullscreen surface; use overlay so FAB stays available.\n // (Persisted preference remains \"fullscreen\" for the next open.)\n setDisplayModeState(ChatbotDisplayMode.default);\n } else {\n setDisplayModeState(persistedDisplayMode);\n }\n\n lightspeedPathnamePrevRef.current = pathname;\n }, [\n closeDrawer,\n conversationId,\n isLightspeedRoute,\n location.pathname,\n persistedDisplayMode,\n ]);\n\n useEffect(() => {\n if (\n !isLightspeedRoute &&\n isOpen &&\n displayModeState === ChatbotDisplayMode.docked\n ) {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n dockedAfterLeavingFullscreenRef.current = false;\n }\n }, [displayModeState, isLightspeedRoute, isOpen, openDrawer]);\n\n const openChatbot = useCallback(() => {\n openedViaFABRef.current = true;\n const rawMode = persistedDisplayMode || ChatbotDisplayMode.default;\n\n if (rawMode === ChatbotDisplayMode.embedded) {\n if (!isLightspeedRoute) {\n if (shellViewTabRef.current === 1) {\n navigate(`${LIGHTSPEED_PATH}/notebooks`);\n } else {\n navigate(lightspeedRoutePath(currentConversationIdState));\n }\n }\n setDisplayModeState(ChatbotDisplayMode.embedded);\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n setIsOpen(true);\n return;\n }\n\n setDisplayModeState(rawMode);\n\n if (rawMode === ChatbotDisplayMode.docked) {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n } else {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n\n setIsOpen(true);\n }, [\n closeDrawer,\n currentConversationIdState,\n isLightspeedRoute,\n navigate,\n openDrawer,\n persistedDisplayMode,\n ]);\n\n const closeChatbot = useCallback(() => {\n dockedAfterLeavingFullscreenRef.current = false;\n if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n if (displayModeState === ChatbotDisplayMode.docked) {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n setIsOpen(false);\n }, [\n closeDrawer,\n displayModeState,\n isLightspeedRoute,\n navigateBackOrGoToCatalog,\n ]);\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 // Refs: first-stream completion calls onStart after unmount / mode change; a stale\n // embedded + /lightspeed closure would navigate back to fullscreen without this.\n // Skip navigation when the user is on a notebooks path — conversation route updates\n // must not overwrite the notebooks URL (fixes notebook closing on mode switch).\n if (\n persistedDisplayModeRef.current === ChatbotDisplayMode.embedded &&\n isLightspeedRouteRef.current &&\n !isOnNotebooksPathRef.current\n ) {\n navigate(lightspeedRoutePath(id), { replace: true });\n }\n },\n [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 const consumePendingOverlayThreadHandoff = useCallback(() => {\n if (!pendingOverlayThreadHandoffRef.current) {\n return false;\n }\n pendingOverlayThreadHandoffRef.current = false;\n return true;\n }, []);\n\n const setDisplayMode = useCallback(\n (\n mode: ChatbotDisplayMode,\n conversationIdParam?: string,\n embeddedNotebooks?: LightspeedEmbeddedNotebooksTarget,\n ) => {\n if (mode === displayModeState) {\n return;\n }\n setPersistedDisplayMode(mode);\n syncShellDrawerForMode(mode);\n\n if (mode === ChatbotDisplayMode.embedded) {\n if (embeddedNotebooks) {\n const path =\n embeddedNotebooks === 'notebooks'\n ? `${LIGHTSPEED_PATH}/notebooks`\n : `${LIGHTSPEED_PATH}/notebooks/${embeddedNotebooks.notebookSessionId}`;\n navigate(path);\n } else if (shellViewTabRef.current === 1) {\n navigate(`${LIGHTSPEED_PATH}/notebooks`);\n } else {\n const convId = conversationIdParam ?? currentConversationIdState;\n navigate(lightspeedRoutePath(convId));\n }\n setIsOpen(true);\n } else {\n if (isLightspeedRoute) {\n leavingLightspeedForNonEmbeddedShellRef.current = true;\n pendingOverlayThreadHandoffRef.current = true;\n leaveLightspeedRouteForShellDisplayMode();\n }\n setIsOpen(true);\n }\n },\n [\n currentConversationIdState,\n displayModeState,\n isLightspeedRoute,\n leaveLightspeedRouteForShellDisplayMode,\n navigate,\n setPersistedDisplayMode,\n syncShellDrawerForMode,\n ],\n );\n\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 consumePendingOverlayThreadHandoff,\n shellViewTab,\n setShellViewTab,\n activeNotebookId,\n setActiveNotebookId,\n }),\n [\n isOpen,\n toggleChatbot,\n displayModeState,\n setDisplayMode,\n drawerWidth,\n currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n consumePendingOverlayThreadHandoff,\n shellViewTab,\n setShellViewTab,\n activeNotebookId,\n setActiveNotebookId,\n ],\n );\n\n return {\n contextValue,\n shouldRenderOverlayModal,\n closeChatbot,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useLightspeedProviderState.esm.js","sources":["../../src/hooks/useLightspeedProviderState.ts"],"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 { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useLocation, useMatch, useNavigate } from 'react-router-dom';\n\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { useAppDrawer } from '@red-hat-developer-hub/backstage-plugin-app-react';\n\nimport type {\n LightspeedDrawerContextType,\n LightspeedEmbeddedNotebooksTarget,\n} from '../components/LightspeedDrawerContext';\nimport { LIGHTSPEED_APP_DRAWER_ID, LIGHTSPEED_PATH } from '../const';\nimport type { FileContent } from '../types';\nimport { useBackstageUserIdentity } from './useBackstageUserIdentity';\nimport { useDisplayModeSettings } from './useDisplayModeSettings';\nimport type { SettingsTab } from './useSettingsPanelUrlState';\n\nfunction lightspeedRoutePath(conversationId?: string): string {\n return conversationId\n ? `${LIGHTSPEED_PATH}/conversation/${conversationId}`\n : LIGHTSPEED_PATH;\n}\n\n/**\n * Encapsulates LightspeedDrawerProvider state, routing, and ApplicationDrawer sync.\n *\n * @internal\n */\nexport function useLightspeedProviderState(): {\n contextValue: LightspeedDrawerContextType;\n shouldRenderOverlayModal: boolean;\n closeChatbot: () => void;\n} {\n const navigate = useNavigate();\n const location = useLocation();\n const { openDrawer, closeDrawer } = useAppDrawer();\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(false);\n const [drawerWidth, setDrawerWidth] = useState(400);\n const [currentConversationIdState, setCurrentConversationIdState] = useState<\n string | undefined\n >(undefined);\n const [draftMessage, setDraftMessageState] = useState('');\n const [draftFileContents, setDraftFileContentsState] = useState<\n FileContent[]\n >([]);\n const [shellViewTab, setShellViewTabState] = useState(0);\n const [activeNotebookId, setActiveNotebookId] = useState<string | undefined>(\n undefined,\n );\n const [settingsTab, setSettingsTabState] = useState<SettingsTab | null>(null);\n const setSettingsTab = useCallback((tab: SettingsTab | null) => {\n setSettingsTabState(tab);\n }, []);\n const shellViewTabRef = useRef(shellViewTab);\n shellViewTabRef.current = shellViewTab;\n const setShellViewTab = useCallback((tab: number) => {\n const next = tab === 1 ? 1 : 0;\n shellViewTabRef.current = next;\n setShellViewTabState(next);\n }, []);\n const openedViaFABRef = useRef(false);\n const dockedAfterLeavingFullscreenRef = useRef(false);\n /** True while navigating off /lightspeed after user chose overlay/docked (URL can lag persisted mode). */\n const leavingLightspeedForNonEmbeddedShellRef = useRef(false);\n /** True until overlay/docked LightspeedChat consumes it (new mount after leaving fullscreen route). */\n const pendingOverlayThreadHandoffRef = useRef(false);\n /** Used to detect in-app moves (e.g. Chat ↔ Notebooks) so display mode is not reset to embedded. */\n const lightspeedPathnamePrevRef = useRef<string | null>(null);\n\n const isLightspeedRouteRef = useRef(false);\n const isOnNotebooksPathRef = useRef(false);\n const persistedDisplayModeRef = useRef(persistedDisplayMode);\n\n const isLightspeedRoute = location.pathname.startsWith(LIGHTSPEED_PATH);\n isLightspeedRouteRef.current = isLightspeedRoute;\n isOnNotebooksPathRef.current = location.pathname.startsWith(\n `${LIGHTSPEED_PATH}/notebooks`,\n );\n persistedDisplayModeRef.current = persistedDisplayMode;\n const conversationMatch = useMatch(\n `${LIGHTSPEED_PATH}/conversation/:conversationId`,\n );\n const conversationId = conversationMatch?.params?.conversationId;\n\n const syncShellDrawerForMode = useCallback(\n (mode: ChatbotDisplayMode) => {\n if (mode === ChatbotDisplayMode.docked) {\n if (isLightspeedRoute) {\n dockedAfterLeavingFullscreenRef.current = true;\n } else {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n } else {\n dockedAfterLeavingFullscreenRef.current = false;\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n },\n [closeDrawer, isLightspeedRoute, openDrawer],\n );\n\n const navigateBackOrGoToCatalog = useCallback(() => {\n if (!openedViaFABRef.current) {\n navigate('/catalog');\n openedViaFABRef.current = true;\n return;\n }\n navigate(-1);\n }, [navigate]);\n\n /**\n * Leaving /lightspeed for overlay/docked must not use navigate(-1): after the first FAB\n * open, navigateBackOrGoToCatalog uses -1 and can land back on /lightspeed (fullscreen).\n */\n const leaveLightspeedRouteForShellDisplayMode = useCallback(() => {\n navigate('/catalog', { replace: true });\n }, [navigate]);\n\n useEffect(() => {\n const pathname = location.pathname;\n const prevPathname = lightspeedPathnamePrevRef.current;\n const isUnderLightspeedPath = (p: string | null) =>\n Boolean(p && p.startsWith(LIGHTSPEED_PATH));\n const isInternalLightspeedRouteChange =\n isUnderLightspeedPath(prevPathname) &&\n isUnderLightspeedPath(pathname) &&\n prevPathname !== pathname;\n\n if (!isLightspeedRoute) {\n leavingLightspeedForNonEmbeddedShellRef.current = false;\n }\n\n if (conversationId) {\n setCurrentConversationIdState(conversationId);\n } else if (isLightspeedRoute) {\n // On `/lightspeed` without a `:conversationId` segment, URL implies a fresh thread.\n // When navigating to another app route (overlay/docked), keep the last id so display\n // mode switches and re-entry to fullscreen stay on the active conversation.\n setCurrentConversationIdState(undefined);\n }\n\n if (isLightspeedRoute) {\n if (!isInternalLightspeedRouteChange) {\n if (\n leavingLightspeedForNonEmbeddedShellRef.current &&\n persistedDisplayMode !== ChatbotDisplayMode.embedded\n ) {\n setDisplayModeState(persistedDisplayMode);\n } else {\n setDisplayModeState(ChatbotDisplayMode.embedded);\n }\n }\n setIsOpen(true);\n if (!dockedAfterLeavingFullscreenRef.current) {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n } else if (persistedDisplayMode === ChatbotDisplayMode.embedded) {\n // Off /lightspeed there is no fullscreen surface; use overlay so FAB stays available.\n // (Persisted preference remains \"fullscreen\" for the next open.)\n setDisplayModeState(ChatbotDisplayMode.default);\n } else {\n setDisplayModeState(persistedDisplayMode);\n }\n\n lightspeedPathnamePrevRef.current = pathname;\n }, [\n closeDrawer,\n conversationId,\n isLightspeedRoute,\n location.pathname,\n persistedDisplayMode,\n ]);\n\n useEffect(() => {\n if (\n !isLightspeedRoute &&\n isOpen &&\n displayModeState === ChatbotDisplayMode.docked\n ) {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n dockedAfterLeavingFullscreenRef.current = false;\n }\n }, [displayModeState, isLightspeedRoute, isOpen, openDrawer]);\n\n const openChatbot = useCallback(() => {\n openedViaFABRef.current = true;\n const rawMode = persistedDisplayMode || ChatbotDisplayMode.default;\n\n if (rawMode === ChatbotDisplayMode.embedded) {\n if (!isLightspeedRoute) {\n if (shellViewTabRef.current === 1) {\n navigate(`${LIGHTSPEED_PATH}/notebooks`);\n } else {\n navigate(lightspeedRoutePath(currentConversationIdState));\n }\n }\n setDisplayModeState(ChatbotDisplayMode.embedded);\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n setIsOpen(true);\n return;\n }\n\n setDisplayModeState(rawMode);\n\n if (rawMode === ChatbotDisplayMode.docked) {\n openDrawer(LIGHTSPEED_APP_DRAWER_ID);\n } else {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n\n setIsOpen(true);\n }, [\n closeDrawer,\n currentConversationIdState,\n isLightspeedRoute,\n navigate,\n openDrawer,\n persistedDisplayMode,\n ]);\n\n const closeChatbot = useCallback(() => {\n dockedAfterLeavingFullscreenRef.current = false;\n if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n if (displayModeState === ChatbotDisplayMode.docked) {\n closeDrawer(LIGHTSPEED_APP_DRAWER_ID);\n }\n setIsOpen(false);\n }, [\n closeDrawer,\n displayModeState,\n isLightspeedRoute,\n navigateBackOrGoToCatalog,\n ]);\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 // Refs: first-stream completion calls onStart after unmount / mode change; a stale\n // embedded + /lightspeed closure would navigate back to fullscreen without this.\n // Skip navigation when the user is on a notebooks path — conversation route updates\n // must not overwrite the notebooks URL (fixes notebook closing on mode switch).\n if (\n persistedDisplayModeRef.current === ChatbotDisplayMode.embedded &&\n isLightspeedRouteRef.current &&\n !isOnNotebooksPathRef.current\n ) {\n navigate(\n {\n pathname: lightspeedRoutePath(id),\n search: location.search,\n },\n { replace: true },\n );\n }\n },\n [navigate, location.search],\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 const consumePendingOverlayThreadHandoff = useCallback(() => {\n if (!pendingOverlayThreadHandoffRef.current) {\n return false;\n }\n pendingOverlayThreadHandoffRef.current = false;\n return true;\n }, []);\n\n const setDisplayMode = useCallback(\n (\n mode: ChatbotDisplayMode,\n conversationIdParam?: string,\n embeddedNotebooks?: LightspeedEmbeddedNotebooksTarget,\n ) => {\n if (mode === displayModeState) {\n return;\n }\n setPersistedDisplayMode(mode);\n syncShellDrawerForMode(mode);\n\n if (mode === ChatbotDisplayMode.embedded) {\n if (embeddedNotebooks) {\n const path =\n embeddedNotebooks === 'notebooks'\n ? `${LIGHTSPEED_PATH}/notebooks`\n : `${LIGHTSPEED_PATH}/notebooks/${embeddedNotebooks.notebookSessionId}`;\n navigate(path);\n } else if (shellViewTabRef.current === 1) {\n navigate(`${LIGHTSPEED_PATH}/notebooks`);\n } else {\n const convId = conversationIdParam ?? currentConversationIdState;\n navigate(lightspeedRoutePath(convId));\n }\n setIsOpen(true);\n } else {\n if (isLightspeedRoute) {\n leavingLightspeedForNonEmbeddedShellRef.current = true;\n pendingOverlayThreadHandoffRef.current = true;\n leaveLightspeedRouteForShellDisplayMode();\n }\n setIsOpen(true);\n }\n },\n [\n currentConversationIdState,\n displayModeState,\n isLightspeedRoute,\n leaveLightspeedRouteForShellDisplayMode,\n navigate,\n setPersistedDisplayMode,\n syncShellDrawerForMode,\n ],\n );\n\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 consumePendingOverlayThreadHandoff,\n shellViewTab,\n setShellViewTab,\n activeNotebookId,\n setActiveNotebookId,\n settingsTab,\n setSettingsTab,\n }),\n [\n isOpen,\n toggleChatbot,\n displayModeState,\n setDisplayMode,\n drawerWidth,\n currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n consumePendingOverlayThreadHandoff,\n shellViewTab,\n setShellViewTab,\n activeNotebookId,\n setActiveNotebookId,\n settingsTab,\n setSettingsTab,\n ],\n );\n\n return {\n contextValue,\n shouldRenderOverlayModal,\n closeChatbot,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,6 @@ import { useTranslation } from './useTranslation.esm.js';
5
5
  const SAVED_TOKEN_MASK = "********************";
6
6
  const useMcpConfigureModal = ({
7
7
  servers,
8
- canManageMcp,
9
8
  isSaving,
10
9
  patchServer,
11
10
  validateServer,
@@ -201,7 +200,7 @@ const useMcpConfigureModal = ({
201
200
  isDcrServer: editingServer?.auth === "dcr"
202
201
  });
203
202
  const removePersonalToken = useCallback(async () => {
204
- if (!editingServer || !canManageMcp || isUpdatingModalStatus || editingServer.hasOrgToken) {
203
+ if (!editingServer || isUpdatingModalStatus || editingServer.hasOrgToken) {
205
204
  return;
206
205
  }
207
206
  setIsUpdatingModalStatus(true);
@@ -229,7 +228,6 @@ const useMcpConfigureModal = ({
229
228
  setIsUpdatingModalStatus(false);
230
229
  }
231
230
  }, [
232
- canManageMcp,
233
231
  editingServer,
234
232
  editingServerId,
235
233
  isUpdatingModalStatus,
@@ -237,7 +235,7 @@ const useMcpConfigureModal = ({
237
235
  servers
238
236
  ]);
239
237
  const save = useCallback(async () => {
240
- if (!editingServer || !canManageMcp) return;
238
+ if (!editingServer) return;
241
239
  const hasCredentialModeChange = modalCredentialMode !== initialCredentialMode;
242
240
  const hasTokenInputChange = tokenInputValue !== initialTokenInputValue;
243
241
  const hasEnabledInputChange = modalEnabled !== editingServer.enabled;
@@ -335,7 +333,6 @@ const useMcpConfigureModal = ({
335
333
  markFailedTokenAttempt();
336
334
  }
337
335
  }, [
338
- canManageMcp,
339
336
  close,
340
337
  editingServer,
341
338
  initialCredentialMode,
@@ -350,12 +347,12 @@ const useMcpConfigureModal = ({
350
347
  ]);
351
348
  const onModalEnabledChange = useCallback(
352
349
  (_event, checked) => {
353
- if (!editingServer || !canManageMcp) {
350
+ if (!editingServer) {
354
351
  return;
355
352
  }
356
353
  setModalEnabled(checked);
357
354
  },
358
- [editingServer, canManageMcp]
355
+ [editingServer]
359
356
  );
360
357
  const modalVerifiedHasToken = editingServer ? editingServer.auth === "dcr" || getModalVerifiedHasToken({
361
358
  hasOrgToken: editingServer.hasOrgToken,
@@ -373,7 +370,7 @@ const useMcpConfigureModal = ({
373
370
  },
374
371
  modalEnabled
375
372
  ) : "unknown";
376
- const isModalEnabledToggleDisabled = !canManageMcp || !editingServer || isUpdatingModalStatus || isEnabledToggleUnavailable(modalDisplayStatus) || Boolean(isSaving[editingServer?.name ?? ""]);
373
+ const isModalEnabledToggleDisabled = !editingServer || isUpdatingModalStatus || isEnabledToggleUnavailable(modalDisplayStatus) || Boolean(isSaving[editingServer?.name ?? ""]);
377
374
  const isModalEnabledChecked$1 = isModalEnabledChecked({
378
375
  displayStatus: modalDisplayStatus,
379
376
  modalEnabled
@@ -425,7 +422,6 @@ const useMcpConfigureModal = ({
425
422
  close,
426
423
  save,
427
424
  removePersonalToken,
428
- canManageMcp,
429
425
  configureModalTitle,
430
426
  isConfigureModalSaving,
431
427
  isSaveTokenButtonDisabled,
@@ -1 +1 @@
1
- {"version":3,"file":"useMcpConfigureModal.esm.js","sources":["../../src/hooks/useMcpConfigureModal.ts"],"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 useCallback,\n useEffect,\n useMemo,\n useState,\n type FormEvent,\n} from 'react';\n\nimport {\n formatApiError,\n getDisplayDetail,\n getInitialCredentialMode,\n getModalDisplayHasToken,\n getModalDisplayStatus,\n isModalEnabledChecked as getModalEnabledChecked,\n getModalVerifiedHasToken,\n isSaveTokenDisabled as getSaveTokenDisabled,\n isEnabledToggleUnavailable,\n type CredentialMode,\n type McpConfigureServer,\n type ServerStatus,\n type TokenValidationState,\n} from '../components/mcpServersDisplayUtils';\nimport { useTranslation } from './useTranslation';\n\nconst SAVED_TOKEN_MASK = '********************';\n\nexport type McpToolInfo = {\n name: string;\n description?: string;\n};\n\nexport type McpServerValidationResult = {\n status: 'connected' | 'error' | 'unknown';\n toolCount: number;\n validation?: {\n error?: unknown;\n tools?: McpToolInfo[];\n };\n};\n\nexport type McpCredentialsValidationResult = {\n valid: boolean;\n error?: unknown;\n toolCount: number;\n tools?: McpToolInfo[];\n};\n\nexport type UseMcpConfigureModalOptions = {\n servers: McpConfigureServer[];\n canManageMcp: boolean;\n isSaving: Record<string, boolean>;\n patchServer: (\n serverName: string,\n body: { enabled?: boolean; token?: string | null },\n ) => Promise<void>;\n validateServer: (serverName: string) => Promise<McpServerValidationResult>;\n validateCredentials: (\n url: string,\n token: string,\n ) => Promise<McpCredentialsValidationResult>;\n fetchServerValidation: (\n serverName: string,\n ) => Promise<McpServerValidationResult>;\n};\n\n/**\n * Owns all state, handlers and derived display data for the MCP \"configure\n * server\" modal. Rendering (JSX/styles) lives in `McpConfigureServerModal`.\n */\nexport const useMcpConfigureModal = ({\n servers,\n canManageMcp,\n isSaving,\n patchServer,\n validateServer,\n validateCredentials,\n fetchServerValidation,\n}: UseMcpConfigureModalOptions) => {\n const { t } = useTranslation();\n const [editingServerId, setEditingServerId] = useState<string | null>(null);\n const [tokenInputValue, setTokenInputValue] = useState('');\n const [initialTokenInputValue, setInitialTokenInputValue] = useState('');\n const [hasSavedTokenInModal, setHasSavedTokenInModal] = useState(false);\n const [modalCredentialMode, setModalCredentialMode] =\n useState<CredentialMode>('personal');\n const [initialCredentialMode, setInitialCredentialMode] =\n useState<CredentialMode>('personal');\n const [tokenValidationState, setTokenValidationState] =\n useState<TokenValidationState>('idle');\n const [tokenValidationMessage, setTokenValidationMessage] = useState('');\n const [modalEnabled, setModalEnabled] = useState(true);\n const [modalTools, setModalTools] = useState<string[]>([]);\n const [isLoadingModalTools, setIsLoadingModalTools] = useState(false);\n const [modalToolsError, setModalToolsError] = useState<string | null>(null);\n const [canRemovePersonalToken, setCanRemovePersonalToken] = useState(false);\n const [isUpdatingModalStatus, setIsUpdatingModalStatus] = useState(false);\n const [hasRemovedPersonalToken, setHasRemovedPersonalToken] = useState(false);\n\n const editingServer = useMemo(\n () => servers.find(server => server.id === editingServerId),\n [servers, editingServerId],\n );\n\n const close = useCallback(() => {\n setEditingServerId(null);\n setTokenInputValue('');\n setInitialTokenInputValue('');\n setHasSavedTokenInModal(false);\n setModalCredentialMode('personal');\n setInitialCredentialMode('personal');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n setModalEnabled(true);\n setModalTools([]);\n setIsLoadingModalTools(false);\n setModalToolsError(null);\n setCanRemovePersonalToken(false);\n setIsUpdatingModalStatus(false);\n setHasRemovedPersonalToken(false);\n }, []);\n\n const open = useCallback(\n (server: McpConfigureServer) => {\n setEditingServerId(server.id);\n const credentialMode = getInitialCredentialMode(server);\n const hasSavedPersonalToken = server.hasUserToken;\n setModalCredentialMode(credentialMode);\n setInitialCredentialMode(credentialMode);\n setHasSavedTokenInModal(hasSavedPersonalToken);\n setCanRemovePersonalToken(server.hasUserToken && !server.hasOrgToken);\n const initialToken = hasSavedPersonalToken ? SAVED_TOKEN_MASK : '';\n setInitialTokenInputValue(initialToken);\n setTokenInputValue(initialToken);\n setModalEnabled(server.enabled);\n setModalTools([]);\n setModalToolsError(null);\n setIsUpdatingModalStatus(false);\n setHasRemovedPersonalToken(false);\n if (server.status === 'error' && server.validationError) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(server.validationError) ||\n t('mcp.settings.token.validationFailed'),\n );\n } else {\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n }\n },\n [t],\n );\n\n useEffect(() => {\n if (!editingServer) {\n return undefined;\n }\n\n if (!editingServer.hasToken) {\n setModalTools([]);\n setModalToolsError(null);\n setIsLoadingModalTools(false);\n return undefined;\n }\n\n let cancelled = false;\n setIsLoadingModalTools(true);\n setModalToolsError(null);\n\n void fetchServerValidation(editingServer.name)\n .then(data => {\n if (cancelled) {\n return;\n }\n const tools = data.validation?.tools?.map(tool => tool.name) ?? [];\n setModalTools(tools);\n if (data.status === 'error') {\n setModalToolsError(\n formatApiError(data.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n } else {\n setModalToolsError(null);\n }\n })\n .catch(e => {\n if (cancelled) {\n return;\n }\n setModalTools([]);\n setModalToolsError(\n e instanceof Error\n ? e.message\n : t('mcp.settings.modal.toolsLoadFailed'),\n );\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoadingModalTools(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [editingServer, fetchServerValidation, t]);\n\n const onTokenInputChange = useCallback(\n (value: string) => {\n if (hasSavedTokenInModal && value !== SAVED_TOKEN_MASK) {\n setHasSavedTokenInModal(false);\n }\n setTokenInputValue(value);\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n },\n [hasSavedTokenInModal],\n );\n\n const onCredentialModeChange = useCallback(\n (mode: CredentialMode) => {\n if (mode === modalCredentialMode) {\n return;\n }\n setModalCredentialMode(mode);\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n\n if (mode === 'organization') {\n setHasSavedTokenInModal(false);\n setTokenInputValue('');\n return;\n }\n\n if (editingServer?.hasUserToken) {\n setHasSavedTokenInModal(true);\n setTokenInputValue(SAVED_TOKEN_MASK);\n setInitialTokenInputValue(SAVED_TOKEN_MASK);\n return;\n }\n\n setHasSavedTokenInModal(false);\n setTokenInputValue('');\n setInitialTokenInputValue('');\n },\n [modalCredentialMode, editingServer],\n );\n\n const clearTokenInput = useCallback(() => {\n if (hasSavedTokenInModal) {\n setHasSavedTokenInModal(false);\n }\n setTokenInputValue('');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n }, [hasSavedTokenInModal]);\n\n const showCredentialRadios = Boolean(\n editingServer?.hasOrgToken && editingServer.auth !== 'dcr',\n );\n const showPersonalTokenField =\n editingServer?.auth !== 'dcr' &&\n (!showCredentialRadios || modalCredentialMode === 'personal');\n\n let tokenInputValidated: 'success' | 'error' | undefined;\n if (tokenValidationState === 'success') {\n tokenInputValidated = 'success';\n } else if (tokenValidationState === 'error') {\n tokenInputValidated = 'error';\n }\n\n let tokenHelperVariant: 'success' | 'error' | 'default' = 'default';\n if (tokenValidationState === 'success') {\n tokenHelperVariant = 'success';\n } else if (tokenValidationState === 'error') {\n tokenHelperVariant = 'error';\n }\n\n const showTokenHelperText =\n !hasSavedTokenInModal || tokenValidationState !== 'idle';\n\n const tokenHelperText =\n tokenValidationMessage || t('mcp.settings.enterToken');\n\n const configureModalTitle = t('mcp.settings.configureServerTitle' as any, {\n serverName: editingServer?.name ?? '',\n });\n\n const isConfigureModalSaving = Boolean(isSaving[editingServer?.name ?? '']);\n const isSaveTokenButtonDisabled = getSaveTokenDisabled({\n tokenInputValue,\n initialTokenInputValue,\n modalEnabled,\n serverEnabled: editingServer?.enabled ?? true,\n credentialMode: modalCredentialMode,\n initialCredentialMode,\n hasOrgToken: editingServer?.hasOrgToken ?? false,\n hasSavedPersonalTokenInModal: hasSavedTokenInModal,\n tokenValidationState,\n hasRemovedPersonalToken,\n isDcrServer: editingServer?.auth === 'dcr',\n });\n\n const removePersonalToken = useCallback(async () => {\n if (\n !editingServer ||\n !canManageMcp ||\n isUpdatingModalStatus ||\n editingServer.hasOrgToken\n ) {\n return;\n }\n\n setIsUpdatingModalStatus(true);\n setTokenInputValue('');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n setModalTools([]);\n setModalToolsError(null);\n setIsLoadingModalTools(false);\n\n try {\n await patchServer(editingServer.name, { token: null, enabled: false });\n setHasSavedTokenInModal(false);\n setInitialTokenInputValue('');\n setModalEnabled(false);\n setHasRemovedPersonalToken(true);\n } catch {\n const server = servers.find(item => item.id === editingServerId);\n if (server?.hasUserToken) {\n setHasSavedTokenInModal(true);\n setCanRemovePersonalToken(true);\n setTokenInputValue(SAVED_TOKEN_MASK);\n }\n setHasRemovedPersonalToken(false);\n } finally {\n setIsUpdatingModalStatus(false);\n }\n }, [\n canManageMcp,\n editingServer,\n editingServerId,\n isUpdatingModalStatus,\n patchServer,\n servers,\n ]);\n\n const save = useCallback(async () => {\n if (!editingServer || !canManageMcp) return;\n\n const hasCredentialModeChange =\n modalCredentialMode !== initialCredentialMode;\n const hasTokenInputChange = tokenInputValue !== initialTokenInputValue;\n const hasEnabledInputChange = modalEnabled !== editingServer.enabled;\n\n if (\n !hasCredentialModeChange &&\n !hasTokenInputChange &&\n !hasEnabledInputChange\n ) {\n close();\n return;\n }\n\n if (\n modalCredentialMode === 'organization' &&\n (hasCredentialModeChange || hasEnabledInputChange)\n ) {\n setTokenValidationState('validating');\n setTokenValidationMessage(t('mcp.settings.token.savingAndValidating'));\n try {\n await patchServer(editingServer.name, {\n token: null,\n enabled: modalEnabled,\n });\n const validationResult = await validateServer(editingServer.name);\n if (validationResult.status === 'error') {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(validationResult.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n return;\n }\n close();\n } catch (e) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n e instanceof Error\n ? e.message\n : `Failed to update ${editingServer.name} settings`,\n );\n }\n return;\n }\n\n if (!hasTokenInputChange && hasEnabledInputChange) {\n await patchServer(editingServer.name, { enabled: modalEnabled });\n close();\n return;\n }\n\n const markFailedTokenAttempt = () => {\n setInitialTokenInputValue(tokenInputValue);\n };\n\n const token = tokenInputValue.trim();\n const hasToken = token.length > 0;\n\n setTokenValidationState('validating');\n setTokenValidationMessage(t('mcp.settings.token.validating'));\n\n try {\n if (hasToken) {\n if (!editingServer.url) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n t('mcp.settings.token.urlUnavailableForValidation'),\n );\n markFailedTokenAttempt();\n return;\n }\n\n const credentialValidation = await validateCredentials(\n editingServer.url,\n token,\n );\n if (!credentialValidation.valid) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(credentialValidation.error) ||\n t('mcp.settings.token.invalidCredentials'),\n );\n markFailedTokenAttempt();\n return;\n }\n setModalTools(credentialValidation.tools?.map(tool => tool.name) ?? []);\n }\n\n setTokenValidationMessage(t('mcp.settings.token.savingAndValidating'));\n await patchServer(editingServer.name, {\n enabled: modalEnabled,\n token: hasToken ? token : null,\n });\n const validationResult = await validateServer(editingServer.name);\n if (validationResult.status === 'error') {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(validationResult.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n markFailedTokenAttempt();\n return;\n }\n if (hasToken && validationResult.status === 'connected') {\n await patchServer(editingServer.name, { enabled: true });\n setModalEnabled(true);\n }\n setTokenValidationState('success');\n setTokenValidationMessage(t('mcp.settings.token.connectionSuccessful'));\n close();\n } catch (e) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n e instanceof Error\n ? e.message\n : `Failed to update ${editingServer.name} token`,\n );\n markFailedTokenAttempt();\n }\n }, [\n canManageMcp,\n close,\n editingServer,\n initialCredentialMode,\n initialTokenInputValue,\n modalCredentialMode,\n modalEnabled,\n patchServer,\n t,\n tokenInputValue,\n validateCredentials,\n validateServer,\n ]);\n\n const onModalEnabledChange = useCallback(\n (_event: FormEvent, checked: boolean) => {\n if (!editingServer || !canManageMcp) {\n return;\n }\n setModalEnabled(checked);\n },\n [editingServer, canManageMcp],\n );\n\n const modalVerifiedHasToken = editingServer\n ? editingServer.auth === 'dcr' ||\n getModalVerifiedHasToken({\n hasOrgToken: editingServer.hasOrgToken,\n credentialMode: modalCredentialMode,\n hasSavedPersonalTokenInModal: hasSavedTokenInModal,\n })\n : false;\n\n const modalDisplayStatus: ServerStatus = editingServer\n ? getModalDisplayStatus(\n {\n ...editingServer,\n hasToken: getModalDisplayHasToken({\n modalVerifiedHasToken,\n modalEnabled,\n serverHasToken: editingServer.hasToken,\n }),\n },\n modalEnabled,\n )\n : 'unknown';\n\n const isModalEnabledToggleDisabled =\n !canManageMcp ||\n !editingServer ||\n isUpdatingModalStatus ||\n isEnabledToggleUnavailable(modalDisplayStatus) ||\n Boolean(isSaving[editingServer?.name ?? '']);\n\n const isModalEnabledChecked = getModalEnabledChecked({\n displayStatus: modalDisplayStatus,\n modalEnabled,\n });\n\n const modalStatusDetail = editingServer\n ? getDisplayDetail(editingServer, modalDisplayStatus, t)\n : '';\n\n const modalToolCount = modalTools.length || editingServer?.toolCount || 0;\n\n const modalEnabledDescription = (() => {\n if (isModalEnabledChecked) {\n return t('mcp.settings.modal.enabledDescription');\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return t('mcp.settings.modal.enabledDescriptionTokenRequired');\n }\n return t('mcp.settings.modal.enabledDescriptionOff');\n })();\n\n const modalStatusText = (() => {\n if (isUpdatingModalStatus) {\n return t('mcp.settings.modal.loadingStatus');\n }\n if (isLoadingModalTools) {\n return t('mcp.settings.modal.fetchingStatus');\n }\n if (modalDisplayStatus === 'disabled') {\n return t('mcp.settings.status.disabled');\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return t('mcp.settings.status.tokenRequired');\n }\n if (modalDisplayStatus === 'ok' && modalTools.length > 0) {\n if (modalTools.length === 1) {\n return t('mcp.settings.status.oneTool' as any, {\n count: String(modalTools.length),\n });\n }\n return t('mcp.settings.status.manyTools' as any, {\n count: String(modalTools.length),\n });\n }\n if (modalToolsError) {\n return modalToolsError;\n }\n return modalStatusDetail;\n })();\n\n const modalToolsEmptyText =\n modalToolsError ?? t('mcp.settings.modal.noToolsAvailable');\n\n return {\n isOpen: Boolean(editingServer),\n editingServer,\n open,\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 };\n};\n\nexport type UseMcpConfigureModalResult = ReturnType<\n typeof useMcpConfigureModal\n>;\n"],"names":["getSaveTokenDisabled","isModalEnabledChecked","getModalEnabledChecked"],"mappings":"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"}
1
+ {"version":3,"file":"useMcpConfigureModal.esm.js","sources":["../../src/hooks/useMcpConfigureModal.ts"],"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 useCallback,\n useEffect,\n useMemo,\n useState,\n type FormEvent,\n} from 'react';\n\nimport {\n formatApiError,\n getDisplayDetail,\n getInitialCredentialMode,\n getModalDisplayHasToken,\n getModalDisplayStatus,\n isModalEnabledChecked as getModalEnabledChecked,\n getModalVerifiedHasToken,\n isSaveTokenDisabled as getSaveTokenDisabled,\n isEnabledToggleUnavailable,\n type CredentialMode,\n type McpConfigureServer,\n type ServerStatus,\n type TokenValidationState,\n} from '../components/mcpServersDisplayUtils';\nimport { useTranslation } from './useTranslation';\n\nconst SAVED_TOKEN_MASK = '********************';\n\nexport type McpToolInfo = {\n name: string;\n description?: string;\n};\n\nexport type McpServerValidationResult = {\n status: 'connected' | 'error' | 'unknown';\n toolCount: number;\n validation?: {\n error?: unknown;\n tools?: McpToolInfo[];\n };\n};\n\nexport type McpCredentialsValidationResult = {\n valid: boolean;\n error?: unknown;\n toolCount: number;\n tools?: McpToolInfo[];\n};\n\nexport type UseMcpConfigureModalOptions = {\n servers: McpConfigureServer[];\n isSaving: Record<string, boolean>;\n patchServer: (\n serverName: string,\n body: { enabled?: boolean; token?: string | null },\n ) => Promise<void>;\n validateServer: (serverName: string) => Promise<McpServerValidationResult>;\n validateCredentials: (\n url: string,\n token: string,\n ) => Promise<McpCredentialsValidationResult>;\n fetchServerValidation: (\n serverName: string,\n ) => Promise<McpServerValidationResult>;\n};\n\n/**\n * Owns all state, handlers and derived display data for the MCP \"configure\n * server\" modal. Rendering (JSX/styles) lives in `McpConfigureServerModal`.\n */\nexport const useMcpConfigureModal = ({\n servers,\n isSaving,\n patchServer,\n validateServer,\n validateCredentials,\n fetchServerValidation,\n}: UseMcpConfigureModalOptions) => {\n const { t } = useTranslation();\n const [editingServerId, setEditingServerId] = useState<string | null>(null);\n const [tokenInputValue, setTokenInputValue] = useState('');\n const [initialTokenInputValue, setInitialTokenInputValue] = useState('');\n const [hasSavedTokenInModal, setHasSavedTokenInModal] = useState(false);\n const [modalCredentialMode, setModalCredentialMode] =\n useState<CredentialMode>('personal');\n const [initialCredentialMode, setInitialCredentialMode] =\n useState<CredentialMode>('personal');\n const [tokenValidationState, setTokenValidationState] =\n useState<TokenValidationState>('idle');\n const [tokenValidationMessage, setTokenValidationMessage] = useState('');\n const [modalEnabled, setModalEnabled] = useState(true);\n const [modalTools, setModalTools] = useState<string[]>([]);\n const [isLoadingModalTools, setIsLoadingModalTools] = useState(false);\n const [modalToolsError, setModalToolsError] = useState<string | null>(null);\n const [canRemovePersonalToken, setCanRemovePersonalToken] = useState(false);\n const [isUpdatingModalStatus, setIsUpdatingModalStatus] = useState(false);\n const [hasRemovedPersonalToken, setHasRemovedPersonalToken] = useState(false);\n\n const editingServer = useMemo(\n () => servers.find(server => server.id === editingServerId),\n [servers, editingServerId],\n );\n\n const close = useCallback(() => {\n setEditingServerId(null);\n setTokenInputValue('');\n setInitialTokenInputValue('');\n setHasSavedTokenInModal(false);\n setModalCredentialMode('personal');\n setInitialCredentialMode('personal');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n setModalEnabled(true);\n setModalTools([]);\n setIsLoadingModalTools(false);\n setModalToolsError(null);\n setCanRemovePersonalToken(false);\n setIsUpdatingModalStatus(false);\n setHasRemovedPersonalToken(false);\n }, []);\n\n const open = useCallback(\n (server: McpConfigureServer) => {\n setEditingServerId(server.id);\n const credentialMode = getInitialCredentialMode(server);\n const hasSavedPersonalToken = server.hasUserToken;\n setModalCredentialMode(credentialMode);\n setInitialCredentialMode(credentialMode);\n setHasSavedTokenInModal(hasSavedPersonalToken);\n setCanRemovePersonalToken(server.hasUserToken && !server.hasOrgToken);\n const initialToken = hasSavedPersonalToken ? SAVED_TOKEN_MASK : '';\n setInitialTokenInputValue(initialToken);\n setTokenInputValue(initialToken);\n setModalEnabled(server.enabled);\n setModalTools([]);\n setModalToolsError(null);\n setIsUpdatingModalStatus(false);\n setHasRemovedPersonalToken(false);\n if (server.status === 'error' && server.validationError) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(server.validationError) ||\n t('mcp.settings.token.validationFailed'),\n );\n } else {\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n }\n },\n [t],\n );\n\n useEffect(() => {\n if (!editingServer) {\n return undefined;\n }\n\n if (!editingServer.hasToken) {\n setModalTools([]);\n setModalToolsError(null);\n setIsLoadingModalTools(false);\n return undefined;\n }\n\n let cancelled = false;\n setIsLoadingModalTools(true);\n setModalToolsError(null);\n\n void fetchServerValidation(editingServer.name)\n .then(data => {\n if (cancelled) {\n return;\n }\n const tools = data.validation?.tools?.map(tool => tool.name) ?? [];\n setModalTools(tools);\n if (data.status === 'error') {\n setModalToolsError(\n formatApiError(data.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n } else {\n setModalToolsError(null);\n }\n })\n .catch(e => {\n if (cancelled) {\n return;\n }\n setModalTools([]);\n setModalToolsError(\n e instanceof Error\n ? e.message\n : t('mcp.settings.modal.toolsLoadFailed'),\n );\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoadingModalTools(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [editingServer, fetchServerValidation, t]);\n\n const onTokenInputChange = useCallback(\n (value: string) => {\n if (hasSavedTokenInModal && value !== SAVED_TOKEN_MASK) {\n setHasSavedTokenInModal(false);\n }\n setTokenInputValue(value);\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n },\n [hasSavedTokenInModal],\n );\n\n const onCredentialModeChange = useCallback(\n (mode: CredentialMode) => {\n if (mode === modalCredentialMode) {\n return;\n }\n setModalCredentialMode(mode);\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n\n if (mode === 'organization') {\n setHasSavedTokenInModal(false);\n setTokenInputValue('');\n return;\n }\n\n if (editingServer?.hasUserToken) {\n setHasSavedTokenInModal(true);\n setTokenInputValue(SAVED_TOKEN_MASK);\n setInitialTokenInputValue(SAVED_TOKEN_MASK);\n return;\n }\n\n setHasSavedTokenInModal(false);\n setTokenInputValue('');\n setInitialTokenInputValue('');\n },\n [modalCredentialMode, editingServer],\n );\n\n const clearTokenInput = useCallback(() => {\n if (hasSavedTokenInModal) {\n setHasSavedTokenInModal(false);\n }\n setTokenInputValue('');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n }, [hasSavedTokenInModal]);\n\n const showCredentialRadios = Boolean(\n editingServer?.hasOrgToken && editingServer.auth !== 'dcr',\n );\n const showPersonalTokenField =\n editingServer?.auth !== 'dcr' &&\n (!showCredentialRadios || modalCredentialMode === 'personal');\n\n let tokenInputValidated: 'success' | 'error' | undefined;\n if (tokenValidationState === 'success') {\n tokenInputValidated = 'success';\n } else if (tokenValidationState === 'error') {\n tokenInputValidated = 'error';\n }\n\n let tokenHelperVariant: 'success' | 'error' | 'default' = 'default';\n if (tokenValidationState === 'success') {\n tokenHelperVariant = 'success';\n } else if (tokenValidationState === 'error') {\n tokenHelperVariant = 'error';\n }\n\n const showTokenHelperText =\n !hasSavedTokenInModal || tokenValidationState !== 'idle';\n\n const tokenHelperText =\n tokenValidationMessage || t('mcp.settings.enterToken');\n\n const configureModalTitle = t('mcp.settings.configureServerTitle' as any, {\n serverName: editingServer?.name ?? '',\n });\n\n const isConfigureModalSaving = Boolean(isSaving[editingServer?.name ?? '']);\n const isSaveTokenButtonDisabled = getSaveTokenDisabled({\n tokenInputValue,\n initialTokenInputValue,\n modalEnabled,\n serverEnabled: editingServer?.enabled ?? true,\n credentialMode: modalCredentialMode,\n initialCredentialMode,\n hasOrgToken: editingServer?.hasOrgToken ?? false,\n hasSavedPersonalTokenInModal: hasSavedTokenInModal,\n tokenValidationState,\n hasRemovedPersonalToken,\n isDcrServer: editingServer?.auth === 'dcr',\n });\n\n const removePersonalToken = useCallback(async () => {\n if (!editingServer || isUpdatingModalStatus || editingServer.hasOrgToken) {\n return;\n }\n\n setIsUpdatingModalStatus(true);\n setTokenInputValue('');\n setTokenValidationState('idle');\n setTokenValidationMessage('');\n setModalTools([]);\n setModalToolsError(null);\n setIsLoadingModalTools(false);\n\n try {\n await patchServer(editingServer.name, { token: null, enabled: false });\n setHasSavedTokenInModal(false);\n setInitialTokenInputValue('');\n setModalEnabled(false);\n setHasRemovedPersonalToken(true);\n } catch {\n const server = servers.find(item => item.id === editingServerId);\n if (server?.hasUserToken) {\n setHasSavedTokenInModal(true);\n setCanRemovePersonalToken(true);\n setTokenInputValue(SAVED_TOKEN_MASK);\n }\n setHasRemovedPersonalToken(false);\n } finally {\n setIsUpdatingModalStatus(false);\n }\n }, [\n editingServer,\n editingServerId,\n isUpdatingModalStatus,\n patchServer,\n servers,\n ]);\n\n const save = useCallback(async () => {\n if (!editingServer) return;\n\n const hasCredentialModeChange =\n modalCredentialMode !== initialCredentialMode;\n const hasTokenInputChange = tokenInputValue !== initialTokenInputValue;\n const hasEnabledInputChange = modalEnabled !== editingServer.enabled;\n\n if (\n !hasCredentialModeChange &&\n !hasTokenInputChange &&\n !hasEnabledInputChange\n ) {\n close();\n return;\n }\n\n if (\n modalCredentialMode === 'organization' &&\n (hasCredentialModeChange || hasEnabledInputChange)\n ) {\n setTokenValidationState('validating');\n setTokenValidationMessage(t('mcp.settings.token.savingAndValidating'));\n try {\n await patchServer(editingServer.name, {\n token: null,\n enabled: modalEnabled,\n });\n const validationResult = await validateServer(editingServer.name);\n if (validationResult.status === 'error') {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(validationResult.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n return;\n }\n close();\n } catch (e) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n e instanceof Error\n ? e.message\n : `Failed to update ${editingServer.name} settings`,\n );\n }\n return;\n }\n\n if (!hasTokenInputChange && hasEnabledInputChange) {\n await patchServer(editingServer.name, { enabled: modalEnabled });\n close();\n return;\n }\n\n const markFailedTokenAttempt = () => {\n setInitialTokenInputValue(tokenInputValue);\n };\n\n const token = tokenInputValue.trim();\n const hasToken = token.length > 0;\n\n setTokenValidationState('validating');\n setTokenValidationMessage(t('mcp.settings.token.validating'));\n\n try {\n if (hasToken) {\n if (!editingServer.url) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n t('mcp.settings.token.urlUnavailableForValidation'),\n );\n markFailedTokenAttempt();\n return;\n }\n\n const credentialValidation = await validateCredentials(\n editingServer.url,\n token,\n );\n if (!credentialValidation.valid) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(credentialValidation.error) ||\n t('mcp.settings.token.invalidCredentials'),\n );\n markFailedTokenAttempt();\n return;\n }\n setModalTools(credentialValidation.tools?.map(tool => tool.name) ?? []);\n }\n\n setTokenValidationMessage(t('mcp.settings.token.savingAndValidating'));\n await patchServer(editingServer.name, {\n enabled: modalEnabled,\n token: hasToken ? token : null,\n });\n const validationResult = await validateServer(editingServer.name);\n if (validationResult.status === 'error') {\n setTokenValidationState('error');\n setTokenValidationMessage(\n formatApiError(validationResult.validation?.error) ||\n t('mcp.settings.token.validationFailed'),\n );\n markFailedTokenAttempt();\n return;\n }\n if (hasToken && validationResult.status === 'connected') {\n await patchServer(editingServer.name, { enabled: true });\n setModalEnabled(true);\n }\n setTokenValidationState('success');\n setTokenValidationMessage(t('mcp.settings.token.connectionSuccessful'));\n close();\n } catch (e) {\n setTokenValidationState('error');\n setTokenValidationMessage(\n e instanceof Error\n ? e.message\n : `Failed to update ${editingServer.name} token`,\n );\n markFailedTokenAttempt();\n }\n }, [\n close,\n editingServer,\n initialCredentialMode,\n initialTokenInputValue,\n modalCredentialMode,\n modalEnabled,\n patchServer,\n t,\n tokenInputValue,\n validateCredentials,\n validateServer,\n ]);\n\n const onModalEnabledChange = useCallback(\n (_event: FormEvent, checked: boolean) => {\n if (!editingServer) {\n return;\n }\n setModalEnabled(checked);\n },\n [editingServer],\n );\n\n const modalVerifiedHasToken = editingServer\n ? editingServer.auth === 'dcr' ||\n getModalVerifiedHasToken({\n hasOrgToken: editingServer.hasOrgToken,\n credentialMode: modalCredentialMode,\n hasSavedPersonalTokenInModal: hasSavedTokenInModal,\n })\n : false;\n\n const modalDisplayStatus: ServerStatus = editingServer\n ? getModalDisplayStatus(\n {\n ...editingServer,\n hasToken: getModalDisplayHasToken({\n modalVerifiedHasToken,\n modalEnabled,\n serverHasToken: editingServer.hasToken,\n }),\n },\n modalEnabled,\n )\n : 'unknown';\n\n const isModalEnabledToggleDisabled =\n !editingServer ||\n isUpdatingModalStatus ||\n isEnabledToggleUnavailable(modalDisplayStatus) ||\n Boolean(isSaving[editingServer?.name ?? '']);\n\n const isModalEnabledChecked = getModalEnabledChecked({\n displayStatus: modalDisplayStatus,\n modalEnabled,\n });\n\n const modalStatusDetail = editingServer\n ? getDisplayDetail(editingServer, modalDisplayStatus, t)\n : '';\n\n const modalToolCount = modalTools.length || editingServer?.toolCount || 0;\n\n const modalEnabledDescription = (() => {\n if (isModalEnabledChecked) {\n return t('mcp.settings.modal.enabledDescription');\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return t('mcp.settings.modal.enabledDescriptionTokenRequired');\n }\n return t('mcp.settings.modal.enabledDescriptionOff');\n })();\n\n const modalStatusText = (() => {\n if (isUpdatingModalStatus) {\n return t('mcp.settings.modal.loadingStatus');\n }\n if (isLoadingModalTools) {\n return t('mcp.settings.modal.fetchingStatus');\n }\n if (modalDisplayStatus === 'disabled') {\n return t('mcp.settings.status.disabled');\n }\n if (modalDisplayStatus === 'tokenRequired') {\n return t('mcp.settings.status.tokenRequired');\n }\n if (modalDisplayStatus === 'ok' && modalTools.length > 0) {\n if (modalTools.length === 1) {\n return t('mcp.settings.status.oneTool' as any, {\n count: String(modalTools.length),\n });\n }\n return t('mcp.settings.status.manyTools' as any, {\n count: String(modalTools.length),\n });\n }\n if (modalToolsError) {\n return modalToolsError;\n }\n return modalStatusDetail;\n })();\n\n const modalToolsEmptyText =\n modalToolsError ?? t('mcp.settings.modal.noToolsAvailable');\n\n return {\n isOpen: Boolean(editingServer),\n editingServer,\n open,\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 };\n};\n\nexport type UseMcpConfigureModalResult = ReturnType<\n typeof useMcpConfigureModal\n>;\n"],"names":["getSaveTokenDisabled","isModalEnabledChecked","getModalEnabledChecked"],"mappings":"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"}
@@ -2,13 +2,14 @@ import { useApi } from '@backstage/core-plugin-api';
2
2
  import { useQuery } from '@tanstack/react-query';
3
3
  import { lightspeedApiRef } from '../api/api.esm.js';
4
4
 
5
- const useNotebookConversationIds = () => {
5
+ const useNotebookConversationIds = (enabled = true) => {
6
6
  const lightspeedApi = useApi(lightspeedApiRef);
7
7
  return useQuery({
8
8
  queryKey: ["notebookConversationIds"],
9
9
  queryFn: async () => {
10
10
  return await lightspeedApi.getNotebookConversationIds();
11
11
  },
12
+ enabled,
12
13
  staleTime: 1e3 * 60 * 5,
13
14
  // 5 minutes
14
15
  retry: false
@@ -1 +1 @@
1
- {"version":3,"file":"useNotebookConversationIds.esm.js","sources":["../../src/hooks/useNotebookConversationIds.ts"],"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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\n/**\n * Hook to fetch conversation IDs associated with notebook sessions for filtering\n * Works even when notebooks feature is disabled\n */\nexport const useNotebookConversationIds = (): UseQueryResult<\n string[],\n Error\n> => {\n const lightspeedApi = useApi(lightspeedApiRef);\n\n return useQuery({\n queryKey: ['notebookConversationIds'],\n queryFn: async () => {\n return await lightspeedApi.getNotebookConversationIds();\n },\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: false,\n });\n};\n"],"names":[],"mappings":";;;;AA0BO,MAAM,6BAA6B,MAGrC;AACH,EAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAE7C,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,yBAAyB,CAAA;AAAA,IACpC,SAAS,YAAY;AACnB,MAAA,OAAO,MAAM,cAAc,0BAAA,EAA2B;AAAA,IACxD,CAAA;AAAA,IACA,SAAA,EAAW,MAAO,EAAA,GAAK,CAAA;AAAA;AAAA,IACvB,KAAA,EAAO;AAAA,GACR,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"useNotebookConversationIds.esm.js","sources":["../../src/hooks/useNotebookConversationIds.ts"],"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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\n/**\n * Hook to fetch conversation IDs associated with notebook sessions for filtering\n * Works even when notebooks feature is disabled\n */\nexport const useNotebookConversationIds = (\n enabled = true,\n): UseQueryResult<string[], Error> => {\n const lightspeedApi = useApi(lightspeedApiRef);\n\n return useQuery({\n queryKey: ['notebookConversationIds'],\n queryFn: async () => {\n return await lightspeedApi.getNotebookConversationIds();\n },\n enabled,\n staleTime: 1000 * 60 * 5, // 5 minutes\n retry: false,\n });\n};\n"],"names":[],"mappings":";;;;AA0BO,MAAM,0BAAA,GAA6B,CACxC,OAAA,GAAU,IAAA,KAC0B;AACpC,EAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAE7C,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,yBAAyB,CAAA;AAAA,IACpC,SAAS,YAAY;AACnB,MAAA,OAAO,MAAM,cAAc,0BAAA,EAA2B;AAAA,IACxD,CAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA,EAAW,MAAO,EAAA,GAAK,CAAA;AAAA;AAAA,IACvB,KAAA,EAAO;AAAA,GACR,CAAA;AACH;;;;"}
@@ -2,13 +2,14 @@ import { useApi } from '@backstage/core-plugin-api';
2
2
  import { useQuery } from '@tanstack/react-query';
3
3
  import { lightspeedApiRef } from '../api/api.esm.js';
4
4
 
5
- const useTopicRestrictionStatus = () => {
5
+ const useTopicRestrictionStatus = (enabled = true) => {
6
6
  const lightspeedApi = useApi(lightspeedApiRef);
7
7
  return useQuery({
8
8
  queryKey: ["topicRestrictionStatus"],
9
9
  queryFn: async () => {
10
10
  return await lightspeedApi.isTopicRestrictionEnabled();
11
- }
11
+ },
12
+ enabled
12
13
  });
13
14
  };
14
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"useQuestionValidation.esm.js","sources":["../../src/hooks/useQuestionValidation.ts"],"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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\nexport const useTopicRestrictionStatus = (): UseQueryResult<boolean, Error> => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['topicRestrictionStatus'],\n queryFn: async () => {\n return await lightspeedApi.isTopicRestrictionEnabled();\n },\n });\n};\n"],"names":[],"mappings":";;;;AAsBO,MAAM,4BAA4B,MAAsC;AAC7E,EAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,wBAAwB,CAAA;AAAA,IACnC,SAAS,YAAY;AACnB,MAAA,OAAO,MAAM,cAAc,yBAAA,EAA0B;AAAA,IACvD;AAAA,GACD,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"useQuestionValidation.esm.js","sources":["../../src/hooks/useQuestionValidation.ts"],"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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\nexport const useTopicRestrictionStatus = (\n enabled = true,\n): UseQueryResult<boolean, Error> => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['topicRestrictionStatus'],\n queryFn: async () => {\n return await lightspeedApi.isTopicRestrictionEnabled();\n },\n enabled,\n });\n};\n"],"names":[],"mappings":";;;;AAsBO,MAAM,yBAAA,GAA4B,CACvC,OAAA,GAAU,IAAA,KACyB;AACnC,EAAA,MAAM,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAA,OAAO,QAAA,CAAS;AAAA,IACd,QAAA,EAAU,CAAC,wBAAwB,CAAA;AAAA,IACnC,SAAS,YAAY;AACnB,MAAA,OAAO,MAAM,cAAc,yBAAA,EAA0B;AAAA,IACvD,CAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;;;;"}
@@ -0,0 +1,64 @@
1
+ import { useState, useCallback } from 'react';
2
+
3
+ const useSavedPromptActions = ({
4
+ onApplyToInput,
5
+ onSendDirectly,
6
+ onDelete
7
+ }) => {
8
+ const [promptToDelete, setPromptToDelete] = useState(
9
+ null
10
+ );
11
+ const [isDeleting, setIsDeleting] = useState(false);
12
+ const [deleteError, setDeleteError] = useState(null);
13
+ const applyToInput = useCallback(
14
+ (content) => {
15
+ onApplyToInput(content);
16
+ },
17
+ [onApplyToInput]
18
+ );
19
+ const sendDirectly = useCallback(
20
+ (content) => {
21
+ onSendDirectly(content);
22
+ },
23
+ [onSendDirectly]
24
+ );
25
+ const requestDelete = useCallback((prompt) => {
26
+ setDeleteError(null);
27
+ setPromptToDelete(prompt);
28
+ }, []);
29
+ const closeDeleteModal = useCallback(() => {
30
+ setPromptToDelete(null);
31
+ setDeleteError(null);
32
+ }, []);
33
+ const confirmDelete = useCallback(async () => {
34
+ if (!promptToDelete) {
35
+ return;
36
+ }
37
+ setIsDeleting(true);
38
+ setDeleteError(null);
39
+ try {
40
+ await onDelete(promptToDelete.id);
41
+ setPromptToDelete(null);
42
+ } catch (e) {
43
+ setDeleteError(
44
+ e instanceof Error ? e.message : "Failed to delete saved prompt"
45
+ );
46
+ } finally {
47
+ setIsDeleting(false);
48
+ }
49
+ }, [onDelete, promptToDelete]);
50
+ return {
51
+ applyToInput,
52
+ sendDirectly,
53
+ requestDelete,
54
+ promptToDelete,
55
+ closeDeleteModal,
56
+ confirmDelete,
57
+ isDeleting,
58
+ deleteError,
59
+ isDeleteModalOpen: promptToDelete !== null
60
+ };
61
+ };
62
+
63
+ export { useSavedPromptActions };
64
+ //# sourceMappingURL=useSavedPromptActions.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedPromptActions.esm.js","sources":["../../src/hooks/useSavedPromptActions.ts"],"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 */\nimport { useCallback, useState } from 'react';\n\nimport { SavedPrompt } from '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-common';\n\ntype UseSavedPromptActionsOptions = {\n onApplyToInput: (content: string) => void;\n onSendDirectly: (content: string) => void;\n onDelete: (promptId: string) => Promise<void>;\n};\n\nexport const useSavedPromptActions = ({\n onApplyToInput,\n onSendDirectly,\n onDelete,\n}: UseSavedPromptActionsOptions) => {\n const [promptToDelete, setPromptToDelete] = useState<SavedPrompt | null>(\n null,\n );\n const [isDeleting, setIsDeleting] = useState(false);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n\n const applyToInput = useCallback(\n (content: string) => {\n onApplyToInput(content);\n },\n [onApplyToInput],\n );\n\n const sendDirectly = useCallback(\n (content: string) => {\n onSendDirectly(content);\n },\n [onSendDirectly],\n );\n\n const requestDelete = useCallback((prompt: SavedPrompt) => {\n setDeleteError(null);\n setPromptToDelete(prompt);\n }, []);\n\n const closeDeleteModal = useCallback(() => {\n setPromptToDelete(null);\n setDeleteError(null);\n }, []);\n\n const confirmDelete = useCallback(async () => {\n if (!promptToDelete) {\n return;\n }\n setIsDeleting(true);\n setDeleteError(null);\n try {\n await onDelete(promptToDelete.id);\n setPromptToDelete(null);\n } catch (e) {\n setDeleteError(\n e instanceof Error ? e.message : 'Failed to delete saved prompt',\n );\n } finally {\n setIsDeleting(false);\n }\n }, [onDelete, promptToDelete]);\n\n return {\n applyToInput,\n sendDirectly,\n requestDelete,\n promptToDelete,\n closeDeleteModal,\n confirmDelete,\n isDeleting,\n deleteError,\n isDeleteModalOpen: promptToDelete !== null,\n };\n};\n"],"names":[],"mappings":";;AAyBO,MAAM,wBAAwB,CAAC;AAAA,EACpC,cAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,KAAoC;AAClC,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,QAAA;AAAA,IAC1C;AAAA,GACF;AACA,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAwB,IAAI,CAAA;AAElE,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,OAAA,KAAoB;AACnB,MAAA,cAAA,CAAe,OAAO,CAAA;AAAA,IACxB,CAAA;AAAA,IACA,CAAC,cAAc;AAAA,GACjB;AAEA,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,OAAA,KAAoB;AACnB,MAAA,cAAA,CAAe,OAAO,CAAA;AAAA,IACxB,CAAA;AAAA,IACA,CAAC,cAAc;AAAA,GACjB;AAEA,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,MAAA,KAAwB;AACzD,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,iBAAA,CAAkB,MAAM,CAAA;AAAA,EAC1B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAA,GAAmB,YAAY,MAAM;AACzC,IAAA,iBAAA,CAAkB,IAAI,CAAA;AACtB,IAAA,cAAA,CAAe,IAAI,CAAA;AAAA,EACrB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,aAAA,GAAgB,YAAY,YAAY;AAC5C,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA;AAAA,IACF;AACA,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,CAAS,eAAe,EAAE,CAAA;AAChC,MAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,IACxB,SAAS,CAAA,EAAG;AACV,MAAA,cAAA;AAAA,QACE,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU;AAAA,OACnC;AAAA,IACF,CAAA,SAAE;AACA,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,cAAc,CAAC,CAAA;AAE7B,EAAA,OAAO;AAAA,IACL,YAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,mBAAmB,cAAA,KAAmB;AAAA,GACxC;AACF;;;;"}
@@ -0,0 +1,75 @@
1
+ import { useCallback } from 'react';
2
+ import { useApi } from '@backstage/core-plugin-api';
3
+ import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
4
+ import { lightspeedApiRef } from '../api/api.esm.js';
5
+
6
+ const DEFAULT_LIMITS = {
7
+ max_prompts_per_user: 100,
8
+ max_display_name_length: 128,
9
+ max_content_length: 5e3
10
+ };
11
+ const useSavedPrompts = () => {
12
+ const api = useApi(lightspeedApiRef);
13
+ const queryClient = useQueryClient();
14
+ const configQuery = useQuery({
15
+ queryKey: ["savedPromptsConfig"],
16
+ queryFn: async () => {
17
+ try {
18
+ return await api.getSavedPromptsConfig();
19
+ } catch {
20
+ return DEFAULT_LIMITS;
21
+ }
22
+ },
23
+ staleTime: Infinity
24
+ });
25
+ const promptsQuery = useQuery({
26
+ queryKey: ["savedPrompts"],
27
+ queryFn: () => api.getSavedPrompts(),
28
+ staleTime: 1e3 * 60 * 5
29
+ });
30
+ const createMutation = useMutation({
31
+ mutationFn: ({ name, content }) => api.createSavedPrompt({ name, content }),
32
+ onSuccess: async () => {
33
+ await queryClient.invalidateQueries({ queryKey: ["savedPrompts"] });
34
+ }
35
+ });
36
+ const deleteMutation = useMutation({
37
+ mutationFn: (promptId) => api.deleteSavedPrompt(promptId),
38
+ onSuccess: async () => {
39
+ await queryClient.invalidateQueries({ queryKey: ["savedPrompts"] });
40
+ }
41
+ });
42
+ const createPrompt = useCallback(
43
+ async (name, content) => {
44
+ await createMutation.mutateAsync({ name, content });
45
+ },
46
+ [createMutation]
47
+ );
48
+ const deletePrompt = useCallback(
49
+ async (promptId) => {
50
+ await deleteMutation.mutateAsync(promptId);
51
+ },
52
+ [deleteMutation]
53
+ );
54
+ const refresh = useCallback(() => {
55
+ void queryClient.invalidateQueries({ queryKey: ["savedPrompts"] });
56
+ }, [queryClient]);
57
+ let error = null;
58
+ if (promptsQuery.error instanceof Error) {
59
+ error = promptsQuery.error.message;
60
+ } else if (promptsQuery.error) {
61
+ error = "Failed to fetch saved prompts";
62
+ }
63
+ return {
64
+ savedPrompts: promptsQuery.data ?? [],
65
+ config: configQuery.data ?? DEFAULT_LIMITS,
66
+ loading: configQuery.isLoading || promptsQuery.isLoading,
67
+ error,
68
+ createPrompt,
69
+ deletePrompt,
70
+ refresh
71
+ };
72
+ };
73
+
74
+ export { useSavedPrompts };
75
+ //# sourceMappingURL=useSavedPrompts.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedPrompts.esm.js","sources":["../../src/hooks/useSavedPrompts.ts"],"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 */\nimport { useCallback } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport {\n SavedPrompt,\n SavedPromptsConfig,\n} from '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-common';\n\nimport { lightspeedApiRef } from '../api/api';\n\nconst DEFAULT_LIMITS: SavedPromptsConfig = {\n max_prompts_per_user: 100,\n max_display_name_length: 128,\n max_content_length: 5000,\n};\n\ntype UseSavedPromptsReturn = {\n savedPrompts: SavedPrompt[];\n config: SavedPromptsConfig;\n loading: boolean;\n error: string | null;\n createPrompt: (name: string, content: string) => Promise<void>;\n deletePrompt: (promptId: string) => Promise<void>;\n refresh: () => void;\n};\n\n/**\n * Hook to manage saved prompts CRUD operations and configuration.\n * Fetches config once per session (cached in state with DEFAULT_LIMITS fallback).\n */\nexport const useSavedPrompts = (): UseSavedPromptsReturn => {\n const api = useApi(lightspeedApiRef);\n const queryClient = useQueryClient();\n\n const configQuery = useQuery({\n queryKey: ['savedPromptsConfig'],\n queryFn: async () => {\n try {\n return await api.getSavedPromptsConfig();\n } catch {\n return DEFAULT_LIMITS;\n }\n },\n staleTime: Infinity,\n });\n\n const promptsQuery = useQuery({\n queryKey: ['savedPrompts'],\n queryFn: () => api.getSavedPrompts(),\n staleTime: 1000 * 60 * 5,\n });\n\n const createMutation = useMutation({\n mutationFn: ({ name, content }: { name: string; content: string }) =>\n api.createSavedPrompt({ name, content }),\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['savedPrompts'] });\n },\n });\n\n const deleteMutation = useMutation({\n mutationFn: (promptId: string) => api.deleteSavedPrompt(promptId),\n onSuccess: async () => {\n await queryClient.invalidateQueries({ queryKey: ['savedPrompts'] });\n },\n });\n\n const createPrompt = useCallback(\n async (name: string, content: string) => {\n await createMutation.mutateAsync({ name, content });\n },\n [createMutation],\n );\n\n const deletePrompt = useCallback(\n async (promptId: string) => {\n await deleteMutation.mutateAsync(promptId);\n },\n [deleteMutation],\n );\n\n const refresh = useCallback(() => {\n void queryClient.invalidateQueries({ queryKey: ['savedPrompts'] });\n }, [queryClient]);\n\n let error: string | null = null;\n if (promptsQuery.error instanceof Error) {\n error = promptsQuery.error.message;\n } else if (promptsQuery.error) {\n error = 'Failed to fetch saved prompts';\n }\n\n return {\n savedPrompts: promptsQuery.data ?? [],\n config: configQuery.data ?? DEFAULT_LIMITS,\n loading: configQuery.isLoading || promptsQuery.isLoading,\n error,\n createPrompt,\n deletePrompt,\n refresh,\n };\n};\n"],"names":[],"mappings":";;;;;AA4BA,MAAM,cAAA,GAAqC;AAAA,EACzC,oBAAA,EAAsB,GAAA;AAAA,EACtB,uBAAA,EAAyB,GAAA;AAAA,EACzB,kBAAA,EAAoB;AACtB,CAAA;AAgBO,MAAM,kBAAkB,MAA6B;AAC1D,EAAA,MAAM,GAAA,GAAM,OAAO,gBAAgB,CAAA;AACnC,EAAA,MAAM,cAAc,cAAA,EAAe;AAEnC,EAAA,MAAM,cAAc,QAAA,CAAS;AAAA,IAC3B,QAAA,EAAU,CAAC,oBAAoB,CAAA;AAAA,IAC/B,SAAS,YAAY;AACnB,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,IAAI,qBAAA,EAAsB;AAAA,MACzC,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,cAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IACA,SAAA,EAAW;AAAA,GACZ,CAAA;AAED,EAAA,MAAM,eAAe,QAAA,CAAS;AAAA,IAC5B,QAAA,EAAU,CAAC,cAAc,CAAA;AAAA,IACzB,OAAA,EAAS,MAAM,GAAA,CAAI,eAAA,EAAgB;AAAA,IACnC,SAAA,EAAW,MAAO,EAAA,GAAK;AAAA,GACxB,CAAA;AAED,EAAA,MAAM,iBAAiB,WAAA,CAAY;AAAA,IACjC,UAAA,EAAY,CAAC,EAAE,IAAA,EAAM,OAAA,EAAQ,KAC3B,GAAA,CAAI,iBAAA,CAAkB,EAAE,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,IACzC,WAAW,YAAY;AACrB,MAAA,MAAM,YAAY,iBAAA,CAAkB,EAAE,UAAU,CAAC,cAAc,GAAG,CAAA;AAAA,IACpE;AAAA,GACD,CAAA;AAED,EAAA,MAAM,iBAAiB,WAAA,CAAY;AAAA,IACjC,UAAA,EAAY,CAAC,QAAA,KAAqB,GAAA,CAAI,kBAAkB,QAAQ,CAAA;AAAA,IAChE,WAAW,YAAY;AACrB,MAAA,MAAM,YAAY,iBAAA,CAAkB,EAAE,UAAU,CAAC,cAAc,GAAG,CAAA;AAAA,IACpE;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,OAAO,MAAc,OAAA,KAAoB;AACvC,MAAA,MAAM,cAAA,CAAe,WAAA,CAAY,EAAE,IAAA,EAAM,SAAS,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,CAAC,cAAc;AAAA,GACjB;AAEA,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,OAAO,QAAA,KAAqB;AAC1B,MAAA,MAAM,cAAA,CAAe,YAAY,QAAQ,CAAA;AAAA,IAC3C,CAAA;AAAA,IACA,CAAC,cAAc;AAAA,GACjB;AAEA,EAAA,MAAM,OAAA,GAAU,YAAY,MAAM;AAChC,IAAA,KAAK,YAAY,iBAAA,CAAkB,EAAE,UAAU,CAAC,cAAc,GAAG,CAAA;AAAA,EACnE,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,IAAI,KAAA,GAAuB,IAAA;AAC3B,EAAA,IAAI,YAAA,CAAa,iBAAiB,KAAA,EAAO;AACvC,IAAA,KAAA,GAAQ,aAAa,KAAA,CAAM,OAAA;AAAA,EAC7B,CAAA,MAAA,IAAW,aAAa,KAAA,EAAO;AAC7B,IAAA,KAAA,GAAQ,+BAAA;AAAA,EACV;AAEA,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,YAAA,CAAa,IAAA,IAAQ,EAAC;AAAA,IACpC,MAAA,EAAQ,YAAY,IAAA,IAAQ,cAAA;AAAA,IAC5B,OAAA,EAAS,WAAA,CAAY,SAAA,IAAa,YAAA,CAAa,SAAA;AAAA,IAC/C,KAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,65 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import { useApi, storageApiRef } from '@backstage/core-plugin-api';
3
+ import { isGuestUser } from '../utils/user-utils.esm.js';
4
+
5
+ const BUCKET_NAME = "lightspeed";
6
+ const SAVED_PROMPTS_ENABLED_KEY = "savedPromptsEnabled";
7
+ const useSavedPromptsSettings = (user) => {
8
+ const storageApi = useApi(storageApiRef);
9
+ const bucket = storageApi.forBucket(BUCKET_NAME);
10
+ const [isSavedPromptsEnabled, setIsSavedPromptsEnabled] = useState(true);
11
+ const shouldPersist = !isGuestUser(user);
12
+ useEffect(() => {
13
+ if (!user) {
14
+ setIsSavedPromptsEnabled(true);
15
+ return void 0;
16
+ }
17
+ if (isGuestUser(user)) {
18
+ setIsSavedPromptsEnabled(true);
19
+ return void 0;
20
+ }
21
+ try {
22
+ const enabledSnapshot = bucket.snapshot(
23
+ SAVED_PROMPTS_ENABLED_KEY
24
+ );
25
+ setIsSavedPromptsEnabled(enabledSnapshot.value ?? true);
26
+ } catch (error) {
27
+ console.error(
28
+ "Error reading saved prompts settings from storage:",
29
+ error
30
+ );
31
+ }
32
+ const enabledSubscription = bucket.observe$(SAVED_PROMPTS_ENABLED_KEY).subscribe({
33
+ next: (snapshot) => {
34
+ setIsSavedPromptsEnabled(snapshot.value ?? true);
35
+ },
36
+ error: (error) => {
37
+ console.error("Error observing savedPromptsEnabled:", error);
38
+ }
39
+ });
40
+ return () => {
41
+ enabledSubscription.unsubscribe();
42
+ };
43
+ }, [bucket, user]);
44
+ const handleSavedPromptsToggle = useCallback(
45
+ (enabled) => {
46
+ if (!user) return;
47
+ setIsSavedPromptsEnabled(enabled);
48
+ if (shouldPersist) {
49
+ try {
50
+ bucket.set(SAVED_PROMPTS_ENABLED_KEY, enabled);
51
+ } catch (error) {
52
+ console.error("Error saving saved prompts toggle state:", error);
53
+ }
54
+ }
55
+ },
56
+ [bucket, user, shouldPersist]
57
+ );
58
+ return {
59
+ isSavedPromptsEnabled,
60
+ handleSavedPromptsToggle
61
+ };
62
+ };
63
+
64
+ export { useSavedPromptsSettings };
65
+ //# sourceMappingURL=useSavedPromptsSettings.esm.js.map