@red-hat-developer-hub/backstage-plugin-lightspeed 1.1.2 → 1.2.1
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.
- package/CHANGELOG.md +28 -0
- package/README.md +27 -21
- package/dist/alpha.d.ts +24 -0
- package/dist/api/LightspeedApiClient.esm.js.map +1 -1
- package/dist/api/api.esm.js.map +1 -1
- package/dist/components/AttachmentContext.esm.js +12 -2
- package/dist/components/AttachmentContext.esm.js.map +1 -1
- package/dist/components/LightSpeedChat.esm.js +199 -39
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedChatBox.esm.js +74 -9
- package/dist/components/LightspeedChatBox.esm.js.map +1 -1
- package/dist/components/LightspeedChatBoxHeader.esm.js +84 -26
- package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
- package/dist/components/LightspeedChatContainer.esm.js +118 -0
- package/dist/components/LightspeedChatContainer.esm.js.map +1 -0
- package/dist/components/LightspeedDrawerContext.esm.js +6 -0
- package/dist/components/LightspeedDrawerContext.esm.js.map +1 -0
- package/dist/components/LightspeedDrawerProvider.esm.js +175 -0
- package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -0
- package/dist/components/LightspeedDrawerStateExposer.esm.js +28 -0
- package/dist/components/LightspeedDrawerStateExposer.esm.js.map +1 -0
- package/dist/components/LightspeedFAB.esm.js +68 -0
- package/dist/components/LightspeedFAB.esm.js.map +1 -0
- package/dist/components/LightspeedIcon.esm.js +23 -2
- package/dist/components/LightspeedIcon.esm.js.map +1 -1
- package/dist/components/LightspeedPage.esm.js +5 -110
- package/dist/components/LightspeedPage.esm.js.map +1 -1
- package/dist/components/Router.esm.js +19 -0
- package/dist/components/Router.esm.js.map +1 -0
- package/dist/components/ToolCallContent.esm.js +217 -0
- package/dist/components/ToolCallContent.esm.js.map +1 -0
- package/dist/hooks/useConversationMessages.esm.js +136 -20
- package/dist/hooks/useConversationMessages.esm.js.map +1 -1
- package/dist/hooks/useLightspeedDrawerContext.esm.js +15 -0
- package/dist/hooks/useLightspeedDrawerContext.esm.js.map +1 -0
- package/dist/hooks/usePinnedChatsSettings.esm.js +118 -0
- package/dist/hooks/usePinnedChatsSettings.esm.js.map +1 -0
- package/dist/hooks/useSortSettings.esm.js +60 -0
- package/dist/hooks/useSortSettings.esm.js.map +1 -0
- package/dist/images/logo-black.svg +22 -0
- package/dist/images/rounded-logo.svg +22 -0
- package/dist/index.d.ts +52 -2
- package/dist/index.esm.js +4 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +44 -5
- package/dist/plugin.esm.js.map +1 -1
- package/dist/routes.esm.js +7 -2
- package/dist/routes.esm.js.map +1 -1
- package/dist/translations/de.esm.js +29 -1
- package/dist/translations/de.esm.js.map +1 -1
- package/dist/translations/es.esm.js +29 -1
- package/dist/translations/es.esm.js.map +1 -1
- package/dist/translations/fr.esm.js +29 -1
- package/dist/translations/fr.esm.js.map +1 -1
- package/dist/translations/it.esm.js +22 -1
- package/dist/translations/it.esm.js.map +1 -1
- package/dist/translations/ja.esm.js +22 -1
- package/dist/translations/ja.esm.js.map +1 -1
- package/dist/translations/ref.esm.js +29 -1
- package/dist/translations/ref.esm.js.map +1 -1
- package/dist/types.esm.js.map +1 -1
- package/dist/utils/lightspeed-chatbox-utils.esm.js +24 -5
- package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
- package/dist/utils/reasoningParser.esm.js +46 -0
- package/dist/utils/reasoningParser.esm.js.map +1 -0
- package/dist/utils/toolCallMapper.esm.js +15 -0
- package/dist/utils/toolCallMapper.esm.js.map +1 -0
- package/dist/utils/user-utils.esm.js +7 -0
- package/dist/utils/user-utils.esm.js.map +1 -0
- package/package.json +10 -5
- package/app-config.yaml +0 -18
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
3
|
+
import { useNavigate, useLocation, useMatch } from 'react-router-dom';
|
|
4
|
+
import { makeStyles } from '@mui/styles';
|
|
5
|
+
import { ChatbotDisplayMode, ChatbotModal } from '@patternfly/chatbot';
|
|
6
|
+
import { LightspeedChatContainer } from './LightspeedChatContainer.esm.js';
|
|
7
|
+
import { LightspeedDrawerContext } from './LightspeedDrawerContext.esm.js';
|
|
8
|
+
|
|
9
|
+
const useStyles = makeStyles((theme) => ({
|
|
10
|
+
chatbotModal: {
|
|
11
|
+
boxShadow: "0 14px 20px -7px rgba(0, 0, 0, 0.22), 0 32px 50px 6px rgba(0, 0, 0, 0.16), 0 12px 60px 12px rgba(0, 0, 0, 0.14) !important",
|
|
12
|
+
bottom: `calc(${theme?.spacing?.(2) ?? "16px"} + 5em)`,
|
|
13
|
+
right: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`
|
|
14
|
+
}
|
|
15
|
+
}));
|
|
16
|
+
const LightspeedDrawerProvider = ({ children }) => {
|
|
17
|
+
const classes = useStyles();
|
|
18
|
+
const navigate = useNavigate();
|
|
19
|
+
const location = useLocation();
|
|
20
|
+
const [displayModeState, setDisplayModeState] = useState(
|
|
21
|
+
ChatbotDisplayMode.default
|
|
22
|
+
);
|
|
23
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
24
|
+
const [drawerWidth, setDrawerWidth] = useState(400);
|
|
25
|
+
const [currentConversationIdState, setCurrentConversationIdState] = useState(undefined);
|
|
26
|
+
const [draftMessage, setDraftMessageState] = useState("");
|
|
27
|
+
const [draftFileContents, setDraftFileContentsState] = useState([]);
|
|
28
|
+
const openedViaFABRef = useRef(false);
|
|
29
|
+
const isLightspeedRoute = location.pathname.startsWith("/lightspeed");
|
|
30
|
+
const conversationMatch = useMatch(
|
|
31
|
+
"/lightspeed/conversation/:conversationId"
|
|
32
|
+
);
|
|
33
|
+
const conversationId = conversationMatch?.params?.conversationId;
|
|
34
|
+
const navigateBackOrGoToCatalog = useCallback(() => {
|
|
35
|
+
if (!openedViaFABRef.current) {
|
|
36
|
+
navigate("/catalog");
|
|
37
|
+
openedViaFABRef.current = true;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
navigate(-1);
|
|
41
|
+
}, [navigate]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (isLightspeedRoute) {
|
|
44
|
+
if (conversationId) {
|
|
45
|
+
setCurrentConversationIdState(conversationId);
|
|
46
|
+
} else {
|
|
47
|
+
setCurrentConversationIdState(undefined);
|
|
48
|
+
}
|
|
49
|
+
setDisplayModeState((prev) => {
|
|
50
|
+
if (prev === ChatbotDisplayMode.docked) {
|
|
51
|
+
return prev;
|
|
52
|
+
}
|
|
53
|
+
return ChatbotDisplayMode.embedded;
|
|
54
|
+
});
|
|
55
|
+
setIsOpen(true);
|
|
56
|
+
} else {
|
|
57
|
+
setDisplayModeState((prev) => {
|
|
58
|
+
if (prev === ChatbotDisplayMode.embedded) {
|
|
59
|
+
return ChatbotDisplayMode.default;
|
|
60
|
+
}
|
|
61
|
+
return prev;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}, [conversationId, isLightspeedRoute]);
|
|
65
|
+
const openChatbot = useCallback(() => {
|
|
66
|
+
openedViaFABRef.current = true;
|
|
67
|
+
setDisplayModeState(ChatbotDisplayMode.default);
|
|
68
|
+
setIsOpen(true);
|
|
69
|
+
}, []);
|
|
70
|
+
const closeChatbot = useCallback(() => {
|
|
71
|
+
if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {
|
|
72
|
+
navigateBackOrGoToCatalog();
|
|
73
|
+
}
|
|
74
|
+
setIsOpen(false);
|
|
75
|
+
setDisplayModeState(ChatbotDisplayMode.default);
|
|
76
|
+
}, [displayModeState, isLightspeedRoute, navigateBackOrGoToCatalog]);
|
|
77
|
+
const toggleChatbot = useCallback(() => {
|
|
78
|
+
if (isOpen) {
|
|
79
|
+
closeChatbot();
|
|
80
|
+
} else {
|
|
81
|
+
openChatbot();
|
|
82
|
+
}
|
|
83
|
+
}, [isOpen, openChatbot, closeChatbot]);
|
|
84
|
+
const setCurrentConversationId = useCallback(
|
|
85
|
+
(id) => {
|
|
86
|
+
setCurrentConversationIdState(id);
|
|
87
|
+
if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {
|
|
88
|
+
const path = id ? `/lightspeed/conversation/${id}` : "/lightspeed";
|
|
89
|
+
navigate(path, { replace: true });
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
[displayModeState, isLightspeedRoute, navigate]
|
|
93
|
+
);
|
|
94
|
+
const setDraftMessage = useCallback((message) => {
|
|
95
|
+
setDraftMessageState(message);
|
|
96
|
+
}, []);
|
|
97
|
+
const setDraftFileContents = useCallback((files) => {
|
|
98
|
+
setDraftFileContentsState(files);
|
|
99
|
+
}, []);
|
|
100
|
+
const setDisplayMode = useCallback(
|
|
101
|
+
(mode, conversationIdParam) => {
|
|
102
|
+
if (mode === displayModeState) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
setDisplayModeState(mode);
|
|
106
|
+
if (mode === ChatbotDisplayMode.embedded) {
|
|
107
|
+
const convId = conversationIdParam ?? currentConversationIdState;
|
|
108
|
+
const path = convId ? `/lightspeed/conversation/${convId}` : "/lightspeed";
|
|
109
|
+
navigate(path);
|
|
110
|
+
setIsOpen(true);
|
|
111
|
+
} else {
|
|
112
|
+
if (isLightspeedRoute) {
|
|
113
|
+
navigateBackOrGoToCatalog();
|
|
114
|
+
}
|
|
115
|
+
setIsOpen(true);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
[
|
|
119
|
+
navigate,
|
|
120
|
+
isLightspeedRoute,
|
|
121
|
+
currentConversationIdState,
|
|
122
|
+
displayModeState,
|
|
123
|
+
navigateBackOrGoToCatalog
|
|
124
|
+
]
|
|
125
|
+
);
|
|
126
|
+
const shouldRenderOverlayModal = isOpen && displayModeState === ChatbotDisplayMode.default && !isLightspeedRoute;
|
|
127
|
+
const contextValue = useMemo(
|
|
128
|
+
() => ({
|
|
129
|
+
isChatbotActive: isOpen,
|
|
130
|
+
toggleChatbot,
|
|
131
|
+
displayMode: displayModeState,
|
|
132
|
+
setDisplayMode,
|
|
133
|
+
drawerWidth,
|
|
134
|
+
setDrawerWidth,
|
|
135
|
+
currentConversationId: currentConversationIdState,
|
|
136
|
+
setCurrentConversationId,
|
|
137
|
+
draftMessage,
|
|
138
|
+
setDraftMessage,
|
|
139
|
+
draftFileContents,
|
|
140
|
+
setDraftFileContents
|
|
141
|
+
}),
|
|
142
|
+
[
|
|
143
|
+
isOpen,
|
|
144
|
+
toggleChatbot,
|
|
145
|
+
displayModeState,
|
|
146
|
+
setDisplayMode,
|
|
147
|
+
drawerWidth,
|
|
148
|
+
setDrawerWidth,
|
|
149
|
+
currentConversationIdState,
|
|
150
|
+
setCurrentConversationId,
|
|
151
|
+
draftMessage,
|
|
152
|
+
setDraftMessage,
|
|
153
|
+
draftFileContents,
|
|
154
|
+
setDraftFileContents
|
|
155
|
+
]
|
|
156
|
+
);
|
|
157
|
+
return /* @__PURE__ */ jsxs(LightspeedDrawerContext.Provider, { value: contextValue, children: [
|
|
158
|
+
children,
|
|
159
|
+
shouldRenderOverlayModal && /* @__PURE__ */ jsx(
|
|
160
|
+
ChatbotModal,
|
|
161
|
+
{
|
|
162
|
+
isOpen: true,
|
|
163
|
+
displayMode: displayModeState,
|
|
164
|
+
onClose: closeChatbot,
|
|
165
|
+
ouiaId: "LightspeedChatbotModal",
|
|
166
|
+
"aria-labelledby": "lightspeed-chatpopup-modal",
|
|
167
|
+
className: classes.chatbotModal,
|
|
168
|
+
children: /* @__PURE__ */ jsx(LightspeedChatContainer, {})
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] });
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export { LightspeedDrawerProvider };
|
|
175
|
+
//# sourceMappingURL=LightspeedDrawerProvider.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedDrawerProvider.esm.js","sources":["../../src/components/LightspeedDrawerProvider.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useLocation, useMatch, useNavigate } from 'react-router-dom';\n\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode, ChatbotModal } from '@patternfly/chatbot';\n\nimport { FileContent } from '../types';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\nimport { LightspeedDrawerContext } from './LightspeedDrawerContext';\n\nconst useStyles = makeStyles(theme => ({\n chatbotModal: {\n boxShadow:\n '0 14px 20px -7px rgba(0, 0, 0, 0.22), 0 32px 50px 6px rgba(0, 0, 0, 0.16), 0 12px 60px 12px rgba(0, 0, 0, 0.14) !important',\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n },\n}));\n\n/**\n * @public\n */\nexport const LightspeedDrawerProvider = ({ children }: PropsWithChildren) => {\n const classes = useStyles();\n const navigate = useNavigate();\n const location = useLocation();\n\n const [displayModeState, setDisplayModeState] = useState<ChatbotDisplayMode>(\n ChatbotDisplayMode.default,\n );\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [drawerWidth, setDrawerWidth] = useState<number>(400);\n const [currentConversationIdState, setCurrentConversationIdState] = useState<\n string | undefined\n >(undefined);\n const [draftMessage, setDraftMessageState] = useState<string>('');\n const [draftFileContents, setDraftFileContentsState] = useState<\n FileContent[]\n >([]);\n const openedViaFABRef = useRef<boolean>(false);\n\n const isLightspeedRoute = location.pathname.startsWith('/lightspeed');\n\n const conversationMatch = useMatch(\n '/lightspeed/conversation/:conversationId',\n );\n\n const conversationId = conversationMatch?.params?.conversationId;\n\n const navigateBackOrGoToCatalog = useCallback(() => {\n // go to catalog page, if the user opens the lightspeed route via a new tab\n if (!openedViaFABRef.current) {\n navigate('/catalog');\n openedViaFABRef.current = true;\n return;\n }\n navigate(-1);\n }, [navigate]);\n\n useEffect(() => {\n if (isLightspeedRoute) {\n if (conversationId) {\n setCurrentConversationIdState(conversationId);\n } else {\n setCurrentConversationIdState(undefined);\n }\n // Update this to fullscreen only when it is not already in the docked mode\n setDisplayModeState(prev => {\n if (prev === ChatbotDisplayMode.docked) {\n return prev; // Don't override docked mode\n }\n return ChatbotDisplayMode.embedded;\n });\n setIsOpen(true);\n } else {\n // When leaving lightspeed route, update this only when the current mode is fullscreen\n setDisplayModeState(prev => {\n if (prev === ChatbotDisplayMode.embedded) {\n return ChatbotDisplayMode.default;\n }\n return prev;\n });\n }\n }, [conversationId, isLightspeedRoute]);\n\n // Open chatbot in overlay mode\n const openChatbot = useCallback(() => {\n openedViaFABRef.current = true;\n setDisplayModeState(ChatbotDisplayMode.default);\n setIsOpen(true);\n }, []);\n\n // Close chatbot\n const closeChatbot = useCallback(() => {\n // If in embedded mode on the lightspeed route, navigate back\n if (displayModeState === ChatbotDisplayMode.embedded && isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n setIsOpen(false);\n setDisplayModeState(ChatbotDisplayMode.default);\n }, [displayModeState, isLightspeedRoute, navigateBackOrGoToCatalog]);\n\n const toggleChatbot = useCallback(() => {\n if (isOpen) {\n closeChatbot();\n } else {\n openChatbot();\n }\n }, [isOpen, openChatbot, closeChatbot]);\n\n const setCurrentConversationId = useCallback(\n (id: string | undefined) => {\n setCurrentConversationIdState(id);\n\n // Update route if in embedded mode\n if (\n displayModeState === ChatbotDisplayMode.embedded &&\n isLightspeedRoute\n ) {\n const path = id ? `/lightspeed/conversation/${id}` : '/lightspeed';\n navigate(path, { replace: true });\n }\n },\n [displayModeState, isLightspeedRoute, navigate],\n );\n\n const setDraftMessage = useCallback((message: string) => {\n setDraftMessageState(message);\n }, []);\n\n const setDraftFileContents = useCallback((files: FileContent[]) => {\n setDraftFileContentsState(files);\n }, []);\n\n // Set display mode with route handling for embedded/fullscreen\n const setDisplayMode = useCallback(\n (mode: ChatbotDisplayMode, conversationIdParam?: string) => {\n if (mode === displayModeState) {\n return;\n }\n\n setDisplayModeState(mode);\n\n // Navigate to fullscreen route with conversation ID if available\n if (mode === ChatbotDisplayMode.embedded) {\n const convId = conversationIdParam ?? currentConversationIdState;\n const path = convId\n ? `/lightspeed/conversation/${convId}`\n : '/lightspeed';\n navigate(path);\n setIsOpen(true);\n } else {\n if (isLightspeedRoute) {\n navigateBackOrGoToCatalog();\n }\n setIsOpen(true);\n }\n },\n [\n navigate,\n isLightspeedRoute,\n currentConversationIdState,\n displayModeState,\n navigateBackOrGoToCatalog,\n ],\n );\n\n // Only render ChatbotModal for overlay mode\n // Docked mode is handled by ApplicationDrawer in Root\n // Embedded mode is handled by LightspeedPage route\n const shouldRenderOverlayModal =\n isOpen &&\n displayModeState === ChatbotDisplayMode.default &&\n !isLightspeedRoute;\n\n const contextValue = useMemo(\n () => ({\n isChatbotActive: isOpen,\n toggleChatbot,\n displayMode: displayModeState,\n setDisplayMode,\n drawerWidth,\n setDrawerWidth,\n currentConversationId: currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n }),\n [\n isOpen,\n toggleChatbot,\n displayModeState,\n setDisplayMode,\n drawerWidth,\n setDrawerWidth,\n currentConversationIdState,\n setCurrentConversationId,\n draftMessage,\n setDraftMessage,\n draftFileContents,\n setDraftFileContents,\n ],\n );\n\n return (\n <LightspeedDrawerContext.Provider value={contextValue}>\n {children}\n {shouldRenderOverlayModal && (\n <ChatbotModal\n isOpen\n displayMode={displayModeState}\n onClose={closeChatbot}\n ouiaId=\"LightspeedChatbotModal\"\n aria-labelledby=\"lightspeed-chatpopup-modal\"\n className={classes.chatbotModal}\n >\n <LightspeedChatContainer />\n </ChatbotModal>\n )}\n </LightspeedDrawerContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAiCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,YAAc,EAAA;AAAA,IACZ,SACE,EAAA,4HAAA;AAAA,IACF,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,OAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA;AAAA;AAEhD,CAAE,CAAA,CAAA;AAKK,MAAM,wBAA2B,GAAA,CAAC,EAAE,QAAA,EAAkC,KAAA;AAC3E,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,WAAW,WAAY,EAAA;AAE7B,EAAM,MAAA,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAA,QAAA;AAAA,IAC9C,kBAAmB,CAAA;AAAA,GACrB;AACA,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAkB,KAAK,CAAA;AACnD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAiB,GAAG,CAAA;AAC1D,EAAA,MAAM,CAAC,0BAAA,EAA4B,6BAA6B,CAAA,GAAI,SAElE,SAAS,CAAA;AACX,EAAA,MAAM,CAAC,YAAA,EAAc,oBAAoB,CAAA,GAAI,SAAiB,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,iBAAmB,EAAA,yBAAyB,CAAI,GAAA,QAAA,CAErD,EAAE,CAAA;AACJ,EAAM,MAAA,eAAA,GAAkB,OAAgB,KAAK,CAAA;AAE7C,EAAA,MAAM,iBAAoB,GAAA,QAAA,CAAS,QAAS,CAAA,UAAA,CAAW,aAAa,CAAA;AAEpE,EAAA,MAAM,iBAAoB,GAAA,QAAA;AAAA,IACxB;AAAA,GACF;AAEA,EAAM,MAAA,cAAA,GAAiB,mBAAmB,MAAQ,EAAA,cAAA;AAElD,EAAM,MAAA,yBAAA,GAA4B,YAAY,MAAM;AAElD,IAAI,IAAA,CAAC,gBAAgB,OAAS,EAAA;AAC5B,MAAA,QAAA,CAAS,UAAU,CAAA;AACnB,MAAA,eAAA,CAAgB,OAAU,GAAA,IAAA;AAC1B,MAAA;AAAA;AAEF,IAAA,QAAA,CAAS,EAAE,CAAA;AAAA,GACb,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,iBAAmB,EAAA;AACrB,MAAA,IAAI,cAAgB,EAAA;AAClB,QAAA,6BAAA,CAA8B,cAAc,CAAA;AAAA,OACvC,MAAA;AACL,QAAA,6BAAA,CAA8B,SAAS,CAAA;AAAA;AAGzC,MAAA,mBAAA,CAAoB,CAAQ,IAAA,KAAA;AAC1B,QAAI,IAAA,IAAA,KAAS,mBAAmB,MAAQ,EAAA;AACtC,UAAO,OAAA,IAAA;AAAA;AAET,QAAA,OAAO,kBAAmB,CAAA,QAAA;AAAA,OAC3B,CAAA;AACD,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,KACT,MAAA;AAEL,MAAA,mBAAA,CAAoB,CAAQ,IAAA,KAAA;AAC1B,QAAI,IAAA,IAAA,KAAS,mBAAmB,QAAU,EAAA;AACxC,UAAA,OAAO,kBAAmB,CAAA,OAAA;AAAA;AAE5B,QAAO,OAAA,IAAA;AAAA,OACR,CAAA;AAAA;AACH,GACC,EAAA,CAAC,cAAgB,EAAA,iBAAiB,CAAC,CAAA;AAGtC,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,eAAA,CAAgB,OAAU,GAAA,IAAA;AAC1B,IAAA,mBAAA,CAAoB,mBAAmB,OAAO,CAAA;AAC9C,IAAA,SAAA,CAAU,IAAI,CAAA;AAAA,GAChB,EAAG,EAAE,CAAA;AAGL,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AAErC,IAAI,IAAA,gBAAA,KAAqB,kBAAmB,CAAA,QAAA,IAAY,iBAAmB,EAAA;AACzE,MAA0B,yBAAA,EAAA;AAAA;AAE5B,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,mBAAA,CAAoB,mBAAmB,OAAO,CAAA;AAAA,GAC7C,EAAA,CAAC,gBAAkB,EAAA,iBAAA,EAAmB,yBAAyB,CAAC,CAAA;AAEnE,EAAM,MAAA,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAA,IAAI,MAAQ,EAAA;AACV,MAAa,YAAA,EAAA;AAAA,KACR,MAAA;AACL,MAAY,WAAA,EAAA;AAAA;AACd,GACC,EAAA,CAAC,MAAQ,EAAA,WAAA,EAAa,YAAY,CAAC,CAAA;AAEtC,EAAA,MAAM,wBAA2B,GAAA,WAAA;AAAA,IAC/B,CAAC,EAA2B,KAAA;AAC1B,MAAA,6BAAA,CAA8B,EAAE,CAAA;AAGhC,MACE,IAAA,gBAAA,KAAqB,kBAAmB,CAAA,QAAA,IACxC,iBACA,EAAA;AACA,QAAA,MAAM,IAAO,GAAA,EAAA,GAAK,CAA4B,yBAAA,EAAA,EAAE,CAAK,CAAA,GAAA,aAAA;AACrD,QAAA,QAAA,CAAS,IAAM,EAAA,EAAE,OAAS,EAAA,IAAA,EAAM,CAAA;AAAA;AAClC,KACF;AAAA,IACA,CAAC,gBAAkB,EAAA,iBAAA,EAAmB,QAAQ;AAAA,GAChD;AAEA,EAAM,MAAA,eAAA,GAAkB,WAAY,CAAA,CAAC,OAAoB,KAAA;AACvD,IAAA,oBAAA,CAAqB,OAAO,CAAA;AAAA,GAC9B,EAAG,EAAE,CAAA;AAEL,EAAM,MAAA,oBAAA,GAAuB,WAAY,CAAA,CAAC,KAAyB,KAAA;AACjE,IAAA,yBAAA,CAA0B,KAAK,CAAA;AAAA,GACjC,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,cAAiB,GAAA,WAAA;AAAA,IACrB,CAAC,MAA0B,mBAAiC,KAAA;AAC1D,MAAA,IAAI,SAAS,gBAAkB,EAAA;AAC7B,QAAA;AAAA;AAGF,MAAA,mBAAA,CAAoB,IAAI,CAAA;AAGxB,MAAI,IAAA,IAAA,KAAS,mBAAmB,QAAU,EAAA;AACxC,QAAA,MAAM,SAAS,mBAAuB,IAAA,0BAAA;AACtC,QAAA,MAAM,IAAO,GAAA,MAAA,GACT,CAA4B,yBAAA,EAAA,MAAM,CAClC,CAAA,GAAA,aAAA;AACJ,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,SAAA,CAAU,IAAI,CAAA;AAAA,OACT,MAAA;AACL,QAAA,IAAI,iBAAmB,EAAA;AACrB,UAA0B,yBAAA,EAAA;AAAA;AAE5B,QAAA,SAAA,CAAU,IAAI,CAAA;AAAA;AAChB,KACF;AAAA,IACA;AAAA,MACE,QAAA;AAAA,MACA,iBAAA;AAAA,MACA,0BAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA;AACF,GACF;AAKA,EAAA,MAAM,wBACJ,GAAA,MAAA,IACA,gBAAqB,KAAA,kBAAA,CAAmB,WACxC,CAAC,iBAAA;AAEH,EAAA,MAAM,YAAe,GAAA,OAAA;AAAA,IACnB,OAAO;AAAA,MACL,eAAiB,EAAA,MAAA;AAAA,MACjB,aAAA;AAAA,MACA,WAAa,EAAA,gBAAA;AAAA,MACb,cAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,qBAAuB,EAAA,0BAAA;AAAA,MACvB,wBAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,MAAA;AAAA,MACA,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,0BAAA;AAAA,MACA,wBAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,uBACG,IAAA,CAAA,uBAAA,CAAwB,QAAxB,EAAA,EAAiC,OAAO,YACtC,EAAA,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACA,wBACC,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAM,EAAA,IAAA;AAAA,QACN,WAAa,EAAA,gBAAA;AAAA,QACb,OAAS,EAAA,YAAA;AAAA,QACT,MAAO,EAAA,wBAAA;AAAA,QACP,iBAAgB,EAAA,4BAAA;AAAA,QAChB,WAAW,OAAQ,CAAA,YAAA;AAAA,QAEnB,8BAAC,uBAAwB,EAAA,EAAA;AAAA;AAAA;AAC3B,GAEJ,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
import { ChatbotDisplayMode } from '@patternfly/chatbot';
|
|
3
|
+
import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
|
|
4
|
+
|
|
5
|
+
const LightspeedDrawerStateExposer = ({
|
|
6
|
+
onStateChange
|
|
7
|
+
}) => {
|
|
8
|
+
const { displayMode, drawerWidth, setDrawerWidth, toggleChatbot } = useLightspeedDrawerContext();
|
|
9
|
+
const isDrawerOpen = displayMode === ChatbotDisplayMode.docked;
|
|
10
|
+
const toggleChatbotRef = useRef(toggleChatbot);
|
|
11
|
+
toggleChatbotRef.current = toggleChatbot;
|
|
12
|
+
const closeDrawer = useCallback(() => {
|
|
13
|
+
toggleChatbotRef.current();
|
|
14
|
+
}, []);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
onStateChange({
|
|
17
|
+
id: "lightspeed",
|
|
18
|
+
isDrawerOpen,
|
|
19
|
+
drawerWidth,
|
|
20
|
+
setDrawerWidth,
|
|
21
|
+
closeDrawer
|
|
22
|
+
});
|
|
23
|
+
}, [isDrawerOpen, drawerWidth, setDrawerWidth, closeDrawer, onStateChange]);
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { LightspeedDrawerStateExposer };
|
|
28
|
+
//# sourceMappingURL=LightspeedDrawerStateExposer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedDrawerStateExposer.esm.js","sources":["../../src/components/LightspeedDrawerStateExposer.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\n\n/**\n * @public\n * Partial Lightspeed drawer state exposed to the ApplicationDrawer\n */\nexport type DrawerState = {\n id: string;\n isDrawerOpen: boolean;\n drawerWidth: number;\n setDrawerWidth: (width: number) => void;\n closeDrawer: () => void;\n};\n\n/**\n * @public\n * Props for drawer state exposer components\n */\nexport type DrawerStateExposerProps = {\n /**\n * Callback called whenever the drawer state changes\n */\n onStateChange: (state: DrawerState) => void;\n};\n\n/**\n * @public\n * This exposes LightspeedDrawer's partial context to the ApplicationDrawer\n *\n * It reads the LightspeedDrawerContext and calls the onStateChange callback with the\n * partial state (id, isDrawerOpen, drawerWidth, setDrawerWidth).\n \n */\nexport const LightspeedDrawerStateExposer = ({\n onStateChange,\n}: DrawerStateExposerProps) => {\n const { displayMode, drawerWidth, setDrawerWidth, toggleChatbot } =\n useLightspeedDrawerContext();\n\n const isDrawerOpen = displayMode === ChatbotDisplayMode.docked;\n\n const toggleChatbotRef = useRef(toggleChatbot);\n toggleChatbotRef.current = toggleChatbot;\n\n const closeDrawer = useCallback(() => {\n toggleChatbotRef.current();\n }, []);\n\n useEffect(() => {\n onStateChange({\n id: 'lightspeed',\n isDrawerOpen,\n drawerWidth,\n setDrawerWidth,\n closeDrawer,\n });\n }, [isDrawerOpen, drawerWidth, setDrawerWidth, closeDrawer, onStateChange]);\n\n return null;\n};\n"],"names":[],"mappings":";;;;AAqDO,MAAM,+BAA+B,CAAC;AAAA,EAC3C;AACF,CAA+B,KAAA;AAC7B,EAAA,MAAM,EAAE,WAAa,EAAA,WAAA,EAAa,cAAgB,EAAA,aAAA,KAChD,0BAA2B,EAAA;AAE7B,EAAM,MAAA,YAAA,GAAe,gBAAgB,kBAAmB,CAAA,MAAA;AAExD,EAAM,MAAA,gBAAA,GAAmB,OAAO,aAAa,CAAA;AAC7C,EAAA,gBAAA,CAAiB,OAAU,GAAA,aAAA;AAE3B,EAAM,MAAA,WAAA,GAAc,YAAY,MAAM;AACpC,IAAA,gBAAA,CAAiB,OAAQ,EAAA;AAAA,GAC3B,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAc,aAAA,CAAA;AAAA,MACZ,EAAI,EAAA,YAAA;AAAA,MACJ,YAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,KACA,CAAC,YAAA,EAAc,aAAa,cAAgB,EAAA,WAAA,EAAa,aAAa,CAAC,CAAA;AAE1E,EAAO,OAAA,IAAA;AACT;;;;"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
+
import Fab from '@mui/material/Fab';
|
|
4
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
5
|
+
import { makeStyles } from '@mui/styles';
|
|
6
|
+
import { ChatbotDisplayMode } from '@patternfly/chatbot';
|
|
7
|
+
import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
|
|
8
|
+
import { LightspeedFABIcon } from './LightspeedIcon.esm.js';
|
|
9
|
+
|
|
10
|
+
const useStyles = makeStyles((theme) => ({
|
|
11
|
+
fab: {
|
|
12
|
+
opacity: "1 !important",
|
|
13
|
+
backgroundColor: `${theme?.palette?.primary?.main ?? "#1976d2"} !important`,
|
|
14
|
+
color: `${theme?.palette?.primary?.contrastText ?? "#fff"} !important`,
|
|
15
|
+
boxShadow: `${theme?.shadows?.[6] ?? "0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)"} !important`
|
|
16
|
+
},
|
|
17
|
+
"fab-button": {
|
|
18
|
+
bottom: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`,
|
|
19
|
+
right: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`,
|
|
20
|
+
alignItems: "end",
|
|
21
|
+
zIndex: 200,
|
|
22
|
+
display: "flex",
|
|
23
|
+
position: "fixed",
|
|
24
|
+
// When drawer is docked, adjust margin
|
|
25
|
+
".docked-drawer-open &": {
|
|
26
|
+
transition: "margin-right 0.3s ease",
|
|
27
|
+
marginRight: "var(--docked-drawer-width, 500px) "
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
const LightspeedFAB = () => {
|
|
32
|
+
const { isChatbotActive, toggleChatbot, displayMode } = useLightspeedDrawerContext();
|
|
33
|
+
const fabButton = useStyles();
|
|
34
|
+
if (displayMode === ChatbotDisplayMode.embedded) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
className: fabButton["fab-button"],
|
|
41
|
+
id: "lightspeed-fab",
|
|
42
|
+
"data-testid": "lightspeed-fab",
|
|
43
|
+
children: /* @__PURE__ */ jsx(
|
|
44
|
+
Tooltip,
|
|
45
|
+
{
|
|
46
|
+
title: isChatbotActive ? "Close Lightspeed" : "Open Lightspeed",
|
|
47
|
+
placement: "left",
|
|
48
|
+
children: /* @__PURE__ */ jsx(
|
|
49
|
+
Fab,
|
|
50
|
+
{
|
|
51
|
+
color: "primary",
|
|
52
|
+
variant: "circular",
|
|
53
|
+
size: "small",
|
|
54
|
+
onClick: toggleChatbot,
|
|
55
|
+
"aria-label": isChatbotActive ? "lightspeed-open" : "lightspeed-close",
|
|
56
|
+
className: fabButton.fab,
|
|
57
|
+
sx: { borderRadius: "100% !important" },
|
|
58
|
+
children: isChatbotActive ? /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(LightspeedFABIcon, {})
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { LightspeedFAB };
|
|
68
|
+
//# sourceMappingURL=LightspeedFAB.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedFAB.esm.js","sources":["../../src/components/LightspeedFAB.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Close from '@mui/icons-material/Close';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\nimport { LightspeedFABIcon } from './LightspeedIcon';\n\nconst useStyles = makeStyles(theme => ({\n fab: {\n opacity: '1 !important',\n backgroundColor: `${theme?.palette?.primary?.main ?? '#1976d2'} !important`,\n color: `${theme?.palette?.primary?.contrastText ?? '#fff'} !important`,\n boxShadow: `${\n theme?.shadows?.[6] ??\n '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)'\n } !important`,\n },\n 'fab-button': {\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n alignItems: 'end',\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n\n // When drawer is docked, adjust margin\n '.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: 'var(--docked-drawer-width, 500px) ',\n },\n },\n}));\n\n/**\n * @public\n * Lightspeed Floating action button to open/close the lightspeed chatbot\n */\n\nexport const LightspeedFAB = () => {\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const fabButton = useStyles();\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n return (\n <div\n className={fabButton['fab-button']}\n id=\"lightspeed-fab\"\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}\n placement=\"left\"\n >\n <Fab\n color=\"primary\"\n variant=\"circular\"\n size=\"small\"\n onClick={toggleChatbot}\n aria-label={isChatbotActive ? 'lightspeed-open' : 'lightspeed-close'}\n className={fabButton.fab}\n sx={{ borderRadius: '100% !important' }}\n >\n {isChatbotActive ? <Close fontSize=\"small\" /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </div>\n );\n};\n"],"names":["Close"],"mappings":";;;;;;;;;AAyBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,GAAK,EAAA;AAAA,IACH,OAAS,EAAA,cAAA;AAAA,IACT,iBAAiB,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,QAAQ,SAAS,CAAA,WAAA,CAAA;AAAA,IAC9D,OAAO,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAgB,MAAM,CAAA,WAAA,CAAA;AAAA,IACzD,WAAW,CACT,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAClB,wGACF,CAAA,WAAA;AAAA,GACF;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC5C,UAAY,EAAA,KAAA;AAAA,IACZ,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA;AAAA,IAGV,uBAAyB,EAAA;AAAA,MACvB,UAAY,EAAA,wBAAA;AAAA,MACZ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAOK,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAe,EAAA,WAAA,KACtC,0BAA2B,EAAA;AAC7B,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAI,IAAA,WAAA,KAAgB,mBAAmB,QAAU,EAAA;AAC/C,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAU,YAAY,CAAA;AAAA,MACjC,EAAG,EAAA,gBAAA;AAAA,MACH,aAAY,EAAA,gBAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,UAC9C,SAAU,EAAA,MAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,KAAM,EAAA,SAAA;AAAA,cACN,OAAQ,EAAA,UAAA;AAAA,cACR,IAAK,EAAA,OAAA;AAAA,cACL,OAAS,EAAA,aAAA;AAAA,cACT,YAAA,EAAY,kBAAkB,iBAAoB,GAAA,kBAAA;AAAA,cAClD,WAAW,SAAU,CAAA,GAAA;AAAA,cACrB,EAAA,EAAI,EAAE,YAAA,EAAc,iBAAkB,EAAA;AAAA,cAErC,4CAAmB,GAAA,CAAAA,SAAA,EAAA,EAAM,UAAS,OAAQ,EAAA,CAAA,uBAAM,iBAAkB,EAAA,EAAA;AAAA;AAAA;AACrE;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useTheme } from '@mui/material/styles';
|
|
2
3
|
import { useTranslation } from '../hooks/useTranslation.esm.js';
|
|
4
|
+
import logoDark from '../images/logo-black.svg';
|
|
3
5
|
import logo from '../images/logo-white.svg';
|
|
6
|
+
import roundedLogo from '../images/rounded-logo.svg';
|
|
4
7
|
|
|
5
8
|
const LightspeedIcon = () => {
|
|
6
9
|
const { t } = useTranslation();
|
|
10
|
+
const theme = useTheme();
|
|
11
|
+
const isDarkTheme = theme.palette.mode === "dark";
|
|
7
12
|
return /* @__PURE__ */ jsx(
|
|
8
13
|
"img",
|
|
9
14
|
{
|
|
10
|
-
src: logo,
|
|
15
|
+
src: isDarkTheme ? logo : logoDark,
|
|
11
16
|
alt: t("icon.lightspeed.alt"),
|
|
12
17
|
style: { height: "25px" }
|
|
13
18
|
}
|
|
14
19
|
);
|
|
15
20
|
};
|
|
21
|
+
const LightspeedFABIcon = () => {
|
|
22
|
+
const { t } = useTranslation();
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
"img",
|
|
25
|
+
{
|
|
26
|
+
"data-testid": "lightspeed-fab-icon",
|
|
27
|
+
src: roundedLogo,
|
|
28
|
+
alt: t("icon.lightspeed.alt"),
|
|
29
|
+
style: {
|
|
30
|
+
width: "100%",
|
|
31
|
+
height: "100%",
|
|
32
|
+
display: "block"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
};
|
|
16
37
|
|
|
17
|
-
export { LightspeedIcon };
|
|
38
|
+
export { LightspeedFABIcon, LightspeedIcon };
|
|
18
39
|
//# sourceMappingURL=LightspeedIcon.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedIcon.esm.js","sources":["../../src/components/LightspeedIcon.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport logo from '../images/logo-white.svg';\n\n/**\n * @public\n * Lightspeed Icon\n */\nexport const LightspeedIcon = () => {\n const { t } = useTranslation();\n\n return (\n <img\n src={logo as any}\n alt={t('icon.lightspeed.alt')}\n style={{ height: '25px' }}\n />\n );\n};\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LightspeedIcon.esm.js","sources":["../../src/components/LightspeedIcon.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useTheme } from '@mui/material/styles';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport logoDark from '../images/logo-black.svg';\nimport logo from '../images/logo-white.svg';\nimport roundedLogo from '../images/rounded-logo.svg';\n\n/**\n * @public\n * Lightspeed Icon\n */\nexport const LightspeedIcon = () => {\n const { t } = useTranslation();\n const theme = useTheme();\n const isDarkTheme = theme.palette.mode === 'dark';\n\n return (\n <img\n src={(isDarkTheme ? logo : logoDark) as any}\n alt={t('icon.lightspeed.alt')}\n style={{ height: '25px' }}\n />\n );\n};\n\n/**\n * @public\n * Lightspeed FAB Icon */\nexport const LightspeedFABIcon = () => {\n const { t } = useTranslation();\n\n return (\n <img\n data-testid=\"lightspeed-fab-icon\"\n src={roundedLogo as any}\n alt={t('icon.lightspeed.alt')}\n style={{\n width: '100%',\n height: '100%',\n display: 'block',\n }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2BO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,WAAA,GAAc,KAAM,CAAA,OAAA,CAAQ,IAAS,KAAA,MAAA;AAE3C,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAM,cAAc,IAAO,GAAA,QAAA;AAAA,MAC3B,GAAA,EAAK,EAAE,qBAAqB,CAAA;AAAA,MAC5B,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAO;AAAA;AAAA,GAC1B;AAEJ;AAKO,MAAM,oBAAoB,MAAM;AACrC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,qBAAA;AAAA,MACZ,GAAK,EAAA,WAAA;AAAA,MACL,GAAA,EAAK,EAAE,qBAAqB,CAAA;AAAA,MAC5B,KAAO,EAAA;AAAA,QACL,KAAO,EAAA,MAAA;AAAA,QACP,MAAQ,EAAA,MAAA;AAAA,QACR,OAAS,EAAA;AAAA;AACX;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useState, useMemo, useEffect } from 'react';
|
|
3
|
-
import { useAsync } from 'react-use';
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
2
|
import { Page, Header, Content } from '@backstage/core-components';
|
|
5
|
-
import {
|
|
6
|
-
import { makeStyles, createStyles, useTheme } from '@material-ui/core/styles';
|
|
7
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
8
|
-
import { useAllModels } from '../hooks/useAllModels.esm.js';
|
|
9
|
-
import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
|
|
10
|
-
import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
|
|
3
|
+
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
|
11
4
|
import { useTranslation } from '../hooks/useTranslation.esm.js';
|
|
12
|
-
import
|
|
13
|
-
import FileAttachmentContextProvider from './AttachmentContext.esm.js';
|
|
14
|
-
import { LightspeedChat } from './LightSpeedChat.esm.js';
|
|
15
|
-
import PermissionRequiredState from './PermissionRequiredState.esm.js';
|
|
5
|
+
import { LightspeedChatContainer } from './LightspeedChatContainer.esm.js';
|
|
16
6
|
|
|
17
7
|
const useStyles = makeStyles(
|
|
18
8
|
() => createStyles({
|
|
@@ -21,84 +11,9 @@ const useStyles = makeStyles(
|
|
|
21
11
|
}
|
|
22
12
|
})
|
|
23
13
|
);
|
|
24
|
-
const
|
|
25
|
-
const THEME_DARK_CLASS = "pf-v6-theme-dark";
|
|
26
|
-
const LAST_SELECTED_MODEL_KEY = "lastSelectedModel";
|
|
27
|
-
const LightspeedPageInner = () => {
|
|
14
|
+
const LightspeedPage = () => {
|
|
28
15
|
const classes = useStyles();
|
|
29
16
|
const { t } = useTranslation();
|
|
30
|
-
const {
|
|
31
|
-
palette: { type }
|
|
32
|
-
} = useTheme();
|
|
33
|
-
const identityApi = useApi(identityApiRef);
|
|
34
|
-
const { data: models } = useAllModels();
|
|
35
|
-
const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();
|
|
36
|
-
const { value: profile, loading: profileLoading } = useAsync(
|
|
37
|
-
async () => await identityApi.getProfileInfo()
|
|
38
|
-
);
|
|
39
|
-
const [selectedModel, setSelectedModel] = useState("");
|
|
40
|
-
const [selectedProvider, setSelectedProvider] = useState("");
|
|
41
|
-
const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();
|
|
42
|
-
const modelsItems = useMemo(
|
|
43
|
-
() => models ? models.filter((model) => model.model_type === "llm").map((m) => ({
|
|
44
|
-
label: m.provider_resource_id,
|
|
45
|
-
value: m.provider_resource_id,
|
|
46
|
-
provider: m.provider_id
|
|
47
|
-
})) : [],
|
|
48
|
-
[models]
|
|
49
|
-
);
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
const htmlTagElement = document.documentElement;
|
|
52
|
-
if (type === THEME_DARK) {
|
|
53
|
-
htmlTagElement.classList.add(THEME_DARK_CLASS);
|
|
54
|
-
} else {
|
|
55
|
-
htmlTagElement.classList.remove(THEME_DARK_CLASS);
|
|
56
|
-
}
|
|
57
|
-
}, [type]);
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (modelsItems.length > 0) {
|
|
60
|
-
try {
|
|
61
|
-
const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);
|
|
62
|
-
const parsedData = storedData ? JSON.parse(storedData) : null;
|
|
63
|
-
const storedModel = parsedData?.model ? modelsItems.find((m) => m.value === parsedData.model) : null;
|
|
64
|
-
if (storedModel) {
|
|
65
|
-
setSelectedModel(storedModel.value);
|
|
66
|
-
setSelectedProvider(storedModel.provider);
|
|
67
|
-
} else {
|
|
68
|
-
setSelectedModel(modelsItems[0].value);
|
|
69
|
-
setSelectedProvider(modelsItems[0].provider);
|
|
70
|
-
}
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.error(
|
|
73
|
-
"Error loading last selected model from localStorage:",
|
|
74
|
-
error
|
|
75
|
-
);
|
|
76
|
-
setSelectedModel(modelsItems[0].value);
|
|
77
|
-
setSelectedProvider(modelsItems[0].provider);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}, [modelsItems]);
|
|
81
|
-
useEffect(() => {
|
|
82
|
-
if (selectedModel && selectedProvider) {
|
|
83
|
-
try {
|
|
84
|
-
localStorage.setItem(
|
|
85
|
-
LAST_SELECTED_MODEL_KEY,
|
|
86
|
-
JSON.stringify({
|
|
87
|
-
model: selectedModel,
|
|
88
|
-
provider: selectedProvider
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(
|
|
93
|
-
"Error saving last selected model to localStorage:",
|
|
94
|
-
error
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}, [selectedModel, selectedProvider]);
|
|
99
|
-
if (loading) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
17
|
return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
|
|
103
18
|
/* @__PURE__ */ jsx(
|
|
104
19
|
Header,
|
|
@@ -108,29 +23,9 @@ const LightspeedPageInner = () => {
|
|
|
108
23
|
pageTitleOverride: t("page.title")
|
|
109
24
|
}
|
|
110
25
|
),
|
|
111
|
-
/* @__PURE__ */ jsx(Content, { className: classes.container, children:
|
|
112
|
-
LightspeedChat,
|
|
113
|
-
{
|
|
114
|
-
selectedModel,
|
|
115
|
-
selectedProvider,
|
|
116
|
-
topicRestrictionEnabled: topicRestrictionEnabled ?? false,
|
|
117
|
-
handleSelectedModel: (item) => {
|
|
118
|
-
setSelectedModel(item);
|
|
119
|
-
setSelectedProvider(
|
|
120
|
-
modelsItems.find((m) => m.value === item)?.provider || ""
|
|
121
|
-
);
|
|
122
|
-
},
|
|
123
|
-
models: modelsItems,
|
|
124
|
-
userName: profile?.displayName,
|
|
125
|
-
avatar: profile?.picture,
|
|
126
|
-
profileLoading
|
|
127
|
-
}
|
|
128
|
-
) }) })
|
|
26
|
+
/* @__PURE__ */ jsx(Content, { className: classes.container, children: /* @__PURE__ */ jsx(LightspeedChatContainer, {}) })
|
|
129
27
|
] });
|
|
130
28
|
};
|
|
131
|
-
const LightspeedPage = () => {
|
|
132
|
-
return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(LightspeedPageInner, {}) });
|
|
133
|
-
};
|
|
134
29
|
|
|
135
30
|
export { LightspeedPage };
|
|
136
31
|
//# sourceMappingURL=LightspeedPage.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {
|
|
1
|
+
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Content, Header, Page } from '@backstage/core-components';\n\nimport { createStyles, makeStyles } from '@material-ui/core/styles';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { LightspeedChatContainer } from './LightspeedChatContainer';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\n/**\n * Lightspeed Page - Routable fullscreen/embedded mode\n * @public\n */\nexport const LightspeedPage = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n\n return (\n <Page themeId=\"tool\">\n <Header\n title={t('page.title')}\n style={{ display: 'none' }}\n pageTitleOverride={t('page.title')}\n />\n <Content className={classes.container}>\n <LightspeedChatContainer />\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;;AAuBA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,SAAW,EAAA;AAAA,MACT,OAAS,EAAA;AAAA;AACX,GACD;AACH,CAAA;AAMO,MAAM,iBAAiB,MAAM;AAClC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,uBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,MACZ,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,YAAY,CAAA;AAAA,QACrB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAO,EAAA;AAAA,QACzB,iBAAA,EAAmB,EAAE,YAAY;AAAA;AAAA,KACnC;AAAA,wBACC,OAAQ,EAAA,EAAA,SAAA,EAAW,QAAQ,SAC1B,EAAA,QAAA,kBAAA,GAAA,CAAC,2BAAwB,CAC3B,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Routes, Route } from 'react-router-dom';
|
|
3
|
+
import { LightspeedPage } from './LightspeedPage.esm.js';
|
|
4
|
+
|
|
5
|
+
const Router = () => {
|
|
6
|
+
return /* @__PURE__ */ jsxs(Routes, { children: [
|
|
7
|
+
/* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(LightspeedPage, {}) }),
|
|
8
|
+
/* @__PURE__ */ jsx(
|
|
9
|
+
Route,
|
|
10
|
+
{
|
|
11
|
+
path: "/conversation/:conversationId",
|
|
12
|
+
element: /* @__PURE__ */ jsx(LightspeedPage, {})
|
|
13
|
+
}
|
|
14
|
+
)
|
|
15
|
+
] });
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { Router };
|
|
19
|
+
//# sourceMappingURL=Router.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Router.esm.js","sources":["../../src/components/Router.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Route, Routes } from 'react-router-dom';\n\nimport { LightspeedPage } from './LightspeedPage';\n\n/**\n * @public\n */\nexport const Router = () => {\n return (\n <Routes>\n <Route path=\"/\" element={<LightspeedPage />} />\n <Route\n path=\"/conversation/:conversationId\"\n element={<LightspeedPage />}\n />\n </Routes>\n );\n};\n"],"names":[],"mappings":";;;;AAuBO,MAAM,SAAS,MAAM;AAC1B,EAAA,4BACG,MACC,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAM,IAAK,EAAA,GAAA,EAAI,OAAS,kBAAA,GAAA,CAAC,kBAAe,CAAI,EAAA,CAAA;AAAA,oBAC7C,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,+BAAA;AAAA,QACL,OAAA,sBAAU,cAAe,EAAA,EAAA;AAAA;AAAA;AAC3B,GACF,EAAA,CAAA;AAEJ;;;;"}
|