UNPKG

@redocly/theme

Version:

Shared UI components lib

165 lines (164 loc) 8.19 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SearchAiDialog = SearchAiDialog; const react_1 = __importStar(require("react")); const styled_components_1 = __importDefault(require("styled-components")); const hooks_1 = require("../../core/hooks"); const Button_1 = require("../../components/Button/Button"); const SearchAiConversationInput_1 = require("../../components/Search/SearchAiConversationInput"); const constants_1 = require("../../core/constants"); const SearchAiMessage_1 = require("../../components/Search/SearchAiMessage"); const Admonition_1 = require("../../components/Admonition/Admonition"); const AiStarsIcon_1 = require("../../icons/AiStarsIcon/AiStarsIcon"); function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error, resources, onMessageSent, className, conversation, setConversation, }) { var _a; const { useTranslate } = (0, hooks_1.useThemeHooks)(); const { search } = (0, hooks_1.useThemeConfig)(); const { translate } = useTranslate(); const conversationEndRef = react_1.default.useRef(null); const suggestions = (_a = search === null || search === void 0 ? void 0 : search.ai) === null || _a === void 0 ? void 0 : _a.suggestions; const placeholder = isGeneratingResponse ? translate('search.ai.generatingResponse', 'Generating response...') : conversation.length > 0 ? translate('search.ai.followUpQuestion', 'Ask a follow up question?') : translate('search.ai.placeholder', 'Ask a question...'); const scrollToBottom = () => { var _a; (_a = conversationEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'end' }); }; const handleOnMessageSent = (message) => { if (!message.trim()) { return; } const mappedHistory = conversation.map(({ role, content }) => ({ role, content, })); onMessageSent(message, mappedHistory); setConversation((prev) => [...prev, { role: constants_1.AiSearchConversationRole.USER, content: message }]); }; (0, react_1.useEffect)(() => { if (!(initialMessage === null || initialMessage === void 0 ? void 0 : initialMessage.trim().length)) { return; } setConversation((prev) => [ ...prev, { role: constants_1.AiSearchConversationRole.USER, content: initialMessage }, ]); }, [initialMessage, setConversation]); (0, react_1.useEffect)(() => { if (response === undefined || conversation.length === 0 || error) { return; } setConversation((prev) => { const lastMessage = prev[prev.length - 1]; const content = response || ''; if (lastMessage && lastMessage.role === constants_1.AiSearchConversationRole.ASSISTANT) { return [ ...prev.slice(0, -1), { role: constants_1.AiSearchConversationRole.ASSISTANT, content, resources }, ]; } return [...prev, { role: constants_1.AiSearchConversationRole.ASSISTANT, content }]; }); }, [response, conversation.length, error, resources, setConversation]); (0, react_1.useEffect)(() => { if (error) { setConversation((prev) => prev.slice(0, -1)); } }, [error, setConversation]); (0, react_1.useEffect)(() => { scrollToBottom(); }, [conversation, isGeneratingResponse]); return (react_1.default.createElement(SearchAiDialogWrapper, { "data-component-name": "Search/SearchAiDialog", className: className }, !conversation.length && (react_1.default.createElement(WelcomeWrapper, null, react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { color: "var(--search-ai-icon-color)", size: "32px", background: "var(--search-ai-icon-bg-color)", borderRadius: "var(--border-radius-lg)", margin: "0 var(--spacing-xs) 0 0" }), translate('search.ai.welcomeText', 'Welcome to AI search! Feel free to ask me anything. How can I help you? '))), react_1.default.createElement(ConversationWrapper, null, conversation.map((item, index) => (react_1.default.createElement(SearchAiMessage_1.SearchAiMessage, { key: `search-ai-message-${index}`, role: item.role, content: item.content, isThinking: item.role === constants_1.AiSearchConversationRole.ASSISTANT && isGeneratingResponse && index === conversation.length - 1, resources: item.resources }))), error && (react_1.default.createElement(Admonition_1.Admonition, { type: "danger", name: translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].headerKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].headerDefault) }, translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].messageKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].messageDefault))), !conversation.length && !error && (react_1.default.createElement(SuggestionsWrapper, null, suggestions === null || suggestions === void 0 ? void 0 : suggestions.map((suggestion) => (react_1.default.createElement(Button_1.Button, { key: suggestion, variant: "outlined", onClick: () => handleOnMessageSent(suggestion) }, suggestion))))), react_1.default.createElement("div", { ref: conversationEndRef })), react_1.default.createElement(ConversationInputWrapper, null, react_1.default.createElement(SearchAiConversationInput_1.SearchAiConversationInput, { onMessageSent: handleOnMessageSent, isGeneratingResponse: isGeneratingResponse, placeholder: placeholder })))); } const SearchAiDialogWrapper = styled_components_1.default.div ` display: flex; flex-direction: column; flex: 1 1 auto; width: 100%; min-width: 0; min-height: 0; position: relative; background: var(--search-ai-dialog-bg-color); overflow: hidden; `; const ConversationWrapper = styled_components_1.default.div ` flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: var(--search-ai-dialog-body-padding); padding-bottom: 0; display: flex; flex-direction: column; align-items: stretch; gap: var(--search-ai-dialog-body-gap); min-height: 0; > :first-child { margin-top: auto; } > :last-child { margin-bottom: 0; gap: 0; } `; const SuggestionsWrapper = styled_components_1.default.div ` display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--search-ai-suggestions-gap); align-items: center; justify-content: center; `; const ConversationInputWrapper = styled_components_1.default.div ` padding: var(--search-ai-dialog-input-padding); border-top: var(--search-ai-dialog-input-border); background: var(--search-ai-dialog-input-bg-color); `; const WelcomeWrapper = styled_components_1.default.div ` display: flex; flex-direction: row; align-items: center; width: auto; margin: var(--search-ai-welcome-margin); position: relative; `; //# sourceMappingURL=SearchAiDialog.js.map