add full page chatbot and react chatbot
This commit is contained in:
parent
f4755947ff
commit
e554ac54dd
|
|
@ -13,6 +13,7 @@ export interface IChatFlow {
|
|||
deployed: boolean
|
||||
updatedDate: Date
|
||||
createdDate: Date
|
||||
chatbotConfig?: string
|
||||
}
|
||||
|
||||
export interface IChatMessage {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ export class ChatFlow implements IChatFlow {
|
|||
@Column()
|
||||
deployed: boolean
|
||||
|
||||
@Column({ nullable: true })
|
||||
chatbotConfig?: string
|
||||
|
||||
@CreateDateColumn()
|
||||
createdDate: Date
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
module.exports = {
|
||||
webpack: {
|
||||
configure: {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
resolve: {
|
||||
fullySpecified: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
"@mui/x-data-grid": "^6.8.0",
|
||||
"@tabler/icons": "^1.39.1",
|
||||
"clsx": "^1.1.1",
|
||||
"flowise-embed": "*",
|
||||
"flowise-embed-react": "*",
|
||||
"formik": "^2.2.6",
|
||||
"framer-motion": "^4.1.13",
|
||||
"history": "^5.0.0",
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
"prop-types": "^15.7.2",
|
||||
"react": "^18.2.0",
|
||||
"react-code-blocks": "^0.0.9-0",
|
||||
"react-color": "^2.19.3",
|
||||
"react-datepicker": "^4.8.0",
|
||||
"react-device-detect": "^1.17.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
|
@ -47,11 +50,11 @@
|
|||
"yup": "^0.32.9"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"dev": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
"start": "craco start",
|
||||
"dev": "craco start",
|
||||
"build": "craco build",
|
||||
"test": "craco test",
|
||||
"eject": "craco eject"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
|
|
@ -72,6 +75,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.15.8",
|
||||
"@craco/craco": "^7.1.0",
|
||||
"@testing-library/jest-dom": "^5.11.10",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
|
|
@ -0,0 +1,23 @@
|
|||
import { lazy } from 'react'
|
||||
|
||||
// project imports
|
||||
import Loadable from 'ui-component/loading/Loadable'
|
||||
import MinimalLayout from 'layout/MinimalLayout'
|
||||
|
||||
// canvas routing
|
||||
const ChatbotFull = Loadable(lazy(() => import('views/chatbot')))
|
||||
|
||||
// ==============================|| CANVAS ROUTING ||============================== //
|
||||
|
||||
const ChatbotRoutes = {
|
||||
path: '/',
|
||||
element: <MinimalLayout />,
|
||||
children: [
|
||||
{
|
||||
path: '/chatbot/:id',
|
||||
element: <ChatbotFull />
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default ChatbotRoutes
|
||||
|
|
@ -3,10 +3,11 @@ import { useRoutes } from 'react-router-dom'
|
|||
// routes
|
||||
import MainRoutes from './MainRoutes'
|
||||
import CanvasRoutes from './CanvasRoutes'
|
||||
import ChatbotRoutes from './ChatbotRoutes'
|
||||
import config from 'config'
|
||||
|
||||
// ==============================|| ROUTING RENDER ||============================== //
|
||||
|
||||
export default function ThemeRoutes() {
|
||||
return useRoutes([MainRoutes, CanvasRoutes], config.basename)
|
||||
return useRoutes([MainRoutes, CanvasRoutes, ChatbotRoutes], config.basename)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { IconSettings, IconChevronLeft, IconDeviceFloppy, IconPencil, IconCheck,
|
|||
// project imports
|
||||
import Settings from 'views/settings'
|
||||
import SaveChatflowDialog from 'ui-component/dialog/SaveChatflowDialog'
|
||||
import APICodeDialog from 'ui-component/dialog/APICodeDialog'
|
||||
import APICodeDialog from 'views/chatflows/APICodeDialog'
|
||||
|
||||
// API
|
||||
import chatflowsApi from 'api/chatflows'
|
||||
|
|
@ -107,7 +107,8 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||
title: 'Embed in website or use as API',
|
||||
chatflowid: chatflow.id,
|
||||
chatflowApiKeyId: chatflow.apikeyid,
|
||||
isFormDataRequired
|
||||
isFormDataRequired,
|
||||
chatbotConfig: chatflow.chatbotConfig
|
||||
})
|
||||
setAPIDialogOpen(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { baseURL } from 'store/constant'
|
||||
import axios from 'axios'
|
||||
import { FullPageChat } from 'flowise-embed-react'
|
||||
|
||||
// ==============================|| Chatbot ||============================== //
|
||||
|
||||
const fetchChatflow = async ({ chatflowId }) => {
|
||||
const username = localStorage.getItem('username')
|
||||
const password = localStorage.getItem('password')
|
||||
|
||||
let chatflow = await axios
|
||||
.get(`${baseURL}/api/v1/chatflows/${chatflowId}`, { auth: username && password ? { username, password } : undefined })
|
||||
.then(async function (response) {
|
||||
return response.data
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error)
|
||||
})
|
||||
return chatflow
|
||||
}
|
||||
|
||||
const ChatbotFull = () => {
|
||||
const URLpath = document.location.pathname.toString().split('/')
|
||||
const chatflowId = URLpath[URLpath.length - 1] === 'chatbot' ? '' : URLpath[URLpath.length - 1]
|
||||
|
||||
const [chatflow, setChatflow] = useState(null)
|
||||
const [chatbotTheme, setChatbotTheme] = useState({})
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
const fetchData = async () => {
|
||||
let response = await fetchChatflow({ chatflowId })
|
||||
setChatflow(response)
|
||||
if (response.chatbotConfig) {
|
||||
try {
|
||||
setChatbotTheme(JSON.parse(response.chatbotConfig))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
setChatbotTheme({})
|
||||
}
|
||||
}
|
||||
}
|
||||
fetchData()
|
||||
})()
|
||||
}, [chatflowId])
|
||||
|
||||
return (
|
||||
<>
|
||||
{!chatflow || chatflow.apikeyid ? (
|
||||
<p>Invalid Chatbot</p>
|
||||
) : (
|
||||
<FullPageChat chatflowid={chatflow.id} apiHost={baseURL} theme={{ chatWindow: chatbotTheme }} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChatbotFull
|
||||
|
|
@ -9,6 +9,8 @@ import { CopyBlock, atomOneDark } from 'react-code-blocks'
|
|||
|
||||
// Project import
|
||||
import { Dropdown } from 'ui-component/dropdown/Dropdown'
|
||||
import ShareChatbot from './ShareChatbot'
|
||||
import EmbedChat from './EmbedChat'
|
||||
|
||||
// Const
|
||||
import { baseURL } from 'store/constant'
|
||||
|
|
@ -19,6 +21,7 @@ import pythonSVG from 'assets/images/python.svg'
|
|||
import javascriptSVG from 'assets/images/javascript.svg'
|
||||
import cURLSVG from 'assets/images/cURL.svg'
|
||||
import EmbedSVG from 'assets/images/embed.svg'
|
||||
import ShareChatbotSVG from 'assets/images/sharing.png'
|
||||
|
||||
// API
|
||||
import apiKeyApi from 'api/apikey'
|
||||
|
|
@ -119,77 +122,19 @@ const getConfigExamplesForCurl = (configData, bodyType) => {
|
|||
return finalStr
|
||||
}
|
||||
|
||||
const embedCode = (chatflowid) => {
|
||||
return `<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.init({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const embedCodeCustomization = (chatflowid) => {
|
||||
return `<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.init({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
chatflowConfig: {
|
||||
// topK: 2
|
||||
},
|
||||
theme: {
|
||||
button: {
|
||||
backgroundColor: "#3B81F6",
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
size: "medium",
|
||||
iconColor: "white",
|
||||
customIconSrc: "https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/svg/google-messages.svg",
|
||||
},
|
||||
chatWindow: {
|
||||
welcomeMessage: "Hello! This is custom welcome message",
|
||||
backgroundColor: "#ffffff",
|
||||
height: 700,
|
||||
width: 400,
|
||||
fontSize: 16,
|
||||
poweredByTextColor: "#303235",
|
||||
botMessage: {
|
||||
backgroundColor: "#f7f8ff",
|
||||
textColor: "#303235",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png",
|
||||
},
|
||||
userMessage: {
|
||||
backgroundColor: "#3B81F6",
|
||||
textColor: "#ffffff",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/usericon.png",
|
||||
},
|
||||
textInput: {
|
||||
placeholder: "Type your question",
|
||||
backgroundColor: "#ffffff",
|
||||
textColor: "#303235",
|
||||
sendButtonColor: "#3B81F6",
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const APICodeDialog = ({ show, dialogProps, onCancel }) => {
|
||||
const portalElement = document.getElementById('portal')
|
||||
const navigate = useNavigate()
|
||||
const dispatch = useDispatch()
|
||||
const codes = ['Embed', 'Python', 'JavaScript', 'cURL']
|
||||
|
||||
const codes = ['Embed', 'Python', 'JavaScript', 'cURL', 'Share Chatbot']
|
||||
const [value, setValue] = useState(0)
|
||||
const [keyOptions, setKeyOptions] = useState([])
|
||||
const [apiKeys, setAPIKeys] = useState([])
|
||||
const [chatflowApiKeyId, setChatflowApiKeyId] = useState('')
|
||||
const [selectedApiKey, setSelectedApiKey] = useState({})
|
||||
const [checkboxVal, setCheckbox] = useState(false)
|
||||
const [embedChatCheckboxVal, setEmbedChatCheckbox] = useState(false)
|
||||
const [chatbotConfig, setChatbotConfig] = useState(null)
|
||||
|
||||
const getAllAPIKeysApi = useApi(apiKeyApi.getAllAPIKeys)
|
||||
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
|
||||
|
|
@ -203,10 +148,6 @@ const APICodeDialog = ({ show, dialogProps, onCancel }) => {
|
|||
}
|
||||
}
|
||||
|
||||
const onCheckBoxEmbedChatChanged = (newVal) => {
|
||||
setEmbedChatCheckbox(newVal)
|
||||
}
|
||||
|
||||
const onApiKeySelected = (keyValue) => {
|
||||
if (keyValue === 'addnewkey') {
|
||||
navigate('/apikey')
|
||||
|
|
@ -265,8 +206,6 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
|
||||
-X POST \\
|
||||
-d '{"question": "Hey, how are you?"}'`
|
||||
} else if (codeLang === 'Embed') {
|
||||
return embedCode(dialogProps.chatflowid)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
|
@ -309,8 +248,6 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||
-X POST \\
|
||||
-d '{"question": "Hey, how are you?"}' \\
|
||||
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
|
||||
} else if (codeLang === 'Embed') {
|
||||
return embedCode(dialogProps.chatflowid)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
|
@ -318,7 +255,7 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||
const getLang = (codeLang) => {
|
||||
if (codeLang === 'Python') {
|
||||
return 'python'
|
||||
} else if (codeLang === 'JavaScript' || codeLang === 'Embed') {
|
||||
} else if (codeLang === 'JavaScript') {
|
||||
return 'javascript'
|
||||
} else if (codeLang === 'cURL') {
|
||||
return 'bash'
|
||||
|
|
@ -335,6 +272,8 @@ query({"question": "Hey, how are you?"}).then((response) => {
|
|||
return EmbedSVG
|
||||
} else if (codeLang === 'cURL') {
|
||||
return cURLSVG
|
||||
} else if (codeLang === 'Share Chatbot') {
|
||||
return ShareChatbotSVG
|
||||
}
|
||||
return pythonSVG
|
||||
}
|
||||
|
|
@ -552,6 +491,12 @@ query({
|
|||
setChatflowApiKeyId(dialogProps.chatflowApiKeyId)
|
||||
setSelectedApiKey(getAllAPIKeysApi.data.find((key) => key.id === dialogProps.chatflowApiKeyId))
|
||||
}
|
||||
|
||||
if (dialogProps.chatbotConfig) {
|
||||
setChatbotConfig(JSON.parse(dialogProps.chatbotConfig))
|
||||
} else {
|
||||
setChatbotConfig(null)
|
||||
}
|
||||
}
|
||||
}, [dialogProps, getAllAPIKeysApi.data])
|
||||
|
||||
|
|
@ -593,92 +538,71 @@ query({
|
|||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
{value !== 0 && (
|
||||
<div style={{ flex: 20 }}>
|
||||
<Dropdown
|
||||
name='SelectKey'
|
||||
disableClearable={true}
|
||||
options={keyOptions}
|
||||
onSelect={(newValue) => onApiKeySelected(newValue)}
|
||||
value={dialogProps.chatflowApiKeyId ?? chatflowApiKeyId ?? 'Choose an API key'}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ flex: 20 }}>
|
||||
<Dropdown
|
||||
name='SelectKey'
|
||||
disableClearable={true}
|
||||
options={keyOptions}
|
||||
onSelect={(newValue) => onApiKeySelected(newValue)}
|
||||
value={dialogProps.chatflowApiKeyId ?? chatflowApiKeyId ?? 'Choose an API key'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginTop: 10 }}></div>
|
||||
{codes.map((codeLang, index) => (
|
||||
<TabPanel key={index} value={value} index={index}>
|
||||
{value === 0 && (
|
||||
{(codeLang === 'Embed' || codeLang === 'Share Chatbot') && chatflowApiKeyId && (
|
||||
<>
|
||||
<span>
|
||||
Paste this anywhere in the <code>{`<body>`}</code> tag of your html file.
|
||||
<p>
|
||||
You can also specify a
|
||||
<a
|
||||
rel='noreferrer'
|
||||
target='_blank'
|
||||
href='https://www.npmjs.com/package/flowise-embed?activeTab=versions'
|
||||
>
|
||||
version
|
||||
</a>
|
||||
: <code>{`https://cdn.jsdelivr.net/npm/flowise-embed@<version>/dist/web.js`}</code>
|
||||
</p>
|
||||
</span>
|
||||
<div style={{ height: 10 }}></div>
|
||||
<p>You cannot use API key while embedding/sharing chatbot.</p>
|
||||
<p>
|
||||
Please select <b>"No Authorization"</b> from the dropdown at the top right corner.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<CopyBlock
|
||||
theme={atomOneDark}
|
||||
text={chatflowApiKeyId ? getCodeWithAuthorization(codeLang) : getCode(codeLang)}
|
||||
language={getLang(codeLang)}
|
||||
showLineNumbers={false}
|
||||
wrapLines
|
||||
/>
|
||||
{value !== 0 && <CheckboxInput label='Show Input Config' value={checkboxVal} onChange={onCheckBoxChanged} />}
|
||||
{value !== 0 && checkboxVal && getConfigApi.data && getConfigApi.data.length > 0 && (
|
||||
{codeLang === 'Embed' && !chatflowApiKeyId && <EmbedChat chatflowid={dialogProps.chatflowid} />}
|
||||
{codeLang !== 'Embed' && codeLang !== 'Share Chatbot' && (
|
||||
<>
|
||||
<TableViewOnly rows={getConfigApi.data} columns={Object.keys(getConfigApi.data[0])} />
|
||||
<CopyBlock
|
||||
theme={atomOneDark}
|
||||
text={
|
||||
chatflowApiKeyId
|
||||
? dialogProps.isFormDataRequired
|
||||
? getConfigCodeWithFormDataWithAuth(codeLang, getConfigApi.data)
|
||||
: getConfigCodeWithAuthorization(codeLang, getConfigApi.data)
|
||||
: dialogProps.isFormDataRequired
|
||||
? getConfigCodeWithFormData(codeLang, getConfigApi.data)
|
||||
: getConfigCode(codeLang, getConfigApi.data)
|
||||
}
|
||||
text={chatflowApiKeyId ? getCodeWithAuthorization(codeLang) : getCode(codeLang)}
|
||||
language={getLang(codeLang)}
|
||||
showLineNumbers={false}
|
||||
wrapLines
|
||||
/>
|
||||
<CheckboxInput label='Show Input Config' value={checkboxVal} onChange={onCheckBoxChanged} />
|
||||
{checkboxVal && getConfigApi.data && getConfigApi.data.length > 0 && (
|
||||
<>
|
||||
<TableViewOnly rows={getConfigApi.data} columns={Object.keys(getConfigApi.data[0])} />
|
||||
<CopyBlock
|
||||
theme={atomOneDark}
|
||||
text={
|
||||
chatflowApiKeyId
|
||||
? dialogProps.isFormDataRequired
|
||||
? getConfigCodeWithFormDataWithAuth(codeLang, getConfigApi.data)
|
||||
: getConfigCodeWithAuthorization(codeLang, getConfigApi.data)
|
||||
: dialogProps.isFormDataRequired
|
||||
? getConfigCodeWithFormData(codeLang, getConfigApi.data)
|
||||
: getConfigCode(codeLang, getConfigApi.data)
|
||||
}
|
||||
language={getLang(codeLang)}
|
||||
showLineNumbers={false}
|
||||
wrapLines
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{getIsChatflowStreamingApi.data?.isStreaming && (
|
||||
<p>
|
||||
Read
|
||||
<a rel='noreferrer' target='_blank' href='https://docs.flowiseai.com/how-to-use#streaming'>
|
||||
here
|
||||
</a>
|
||||
on how to stream response back to application
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{value === 0 && (
|
||||
<CheckboxInput
|
||||
label='Show Embed Chat Config'
|
||||
value={embedChatCheckboxVal}
|
||||
onChange={onCheckBoxEmbedChatChanged}
|
||||
/>
|
||||
)}
|
||||
{value === 0 && embedChatCheckboxVal && (
|
||||
<CopyBlock
|
||||
theme={atomOneDark}
|
||||
text={embedCodeCustomization(dialogProps.chatflowid)}
|
||||
language={getLang('Embed')}
|
||||
showLineNumbers={false}
|
||||
wrapLines
|
||||
/>
|
||||
)}
|
||||
{value !== 0 && getIsChatflowStreamingApi.data?.isStreaming && (
|
||||
<p>
|
||||
Read
|
||||
<a rel='noreferrer' target='_blank' href='https://docs.flowiseai.com/how-to-use#streaming'>
|
||||
here
|
||||
</a>
|
||||
on how to stream response back to application
|
||||
</p>
|
||||
{codeLang === 'Share Chatbot' && !chatflowApiKeyId && (
|
||||
<ShareChatbot chatflowid={dialogProps.chatflowid} chatbotConfig={chatbotConfig} />
|
||||
)}
|
||||
</TabPanel>
|
||||
))}
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
import { useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { Tabs, Tab, Box } from '@mui/material'
|
||||
import { CopyBlock, atomOneDark } from 'react-code-blocks'
|
||||
|
||||
// Project import
|
||||
import { CheckboxInput } from 'ui-component/checkbox/Checkbox'
|
||||
|
||||
// Const
|
||||
import { baseURL } from 'store/constant'
|
||||
|
||||
function TabPanel(props) {
|
||||
const { children, value, index, ...other } = props
|
||||
return (
|
||||
<div
|
||||
role='tabpanel'
|
||||
hidden={value !== index}
|
||||
id={`attachment-tabpanel-${index}`}
|
||||
aria-labelledby={`attachment-tab-${index}`}
|
||||
{...other}
|
||||
>
|
||||
{value === index && <Box sx={{ p: 1 }}>{children}</Box>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
TabPanel.propTypes = {
|
||||
children: PropTypes.node,
|
||||
index: PropTypes.number.isRequired,
|
||||
value: PropTypes.number.isRequired
|
||||
}
|
||||
|
||||
function a11yProps(index) {
|
||||
return {
|
||||
id: `attachment-tab-${index}`,
|
||||
'aria-controls': `attachment-tabpanel-${index}`
|
||||
}
|
||||
}
|
||||
|
||||
const embedPopupHtmlCode = (chatflowid) => {
|
||||
return `<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.init({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const embedPopupReactCode = (chatflowid) => {
|
||||
return `import { BubbleChat } from 'flowise-embed-react'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<BubbleChat chatflowid="${chatflowid}" apiHost="${baseURL}" />
|
||||
);
|
||||
};`
|
||||
}
|
||||
|
||||
const embedFullpageHtmlCode = (chatflowid) => {
|
||||
return `<flowise-fullchatbot></flowise-fullchatbot>
|
||||
<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.initFull({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const embedFullpageReactCode = (chatflowid) => {
|
||||
return `import { FullPageChat } from "flowise-embed-react"
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<FullPageChat
|
||||
chatflowid="${chatflowid}"
|
||||
apiHost="${baseURL}"
|
||||
/>
|
||||
);
|
||||
};`
|
||||
}
|
||||
|
||||
const buttonConfig = (isReact = false) => {
|
||||
return isReact
|
||||
? `button: {
|
||||
backgroundColor: "#3B81F6",
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
size: "medium",
|
||||
iconColor: "white",
|
||||
customIconSrc: "https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/svg/google-messages.svg",
|
||||
}`
|
||||
: `button: {
|
||||
backgroundColor: "#3B81F6",
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
size: "medium",
|
||||
iconColor: "white",
|
||||
customIconSrc: "https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/svg/google-messages.svg",
|
||||
}`
|
||||
}
|
||||
|
||||
const chatwindowConfig = (isReact = false) => {
|
||||
return isReact
|
||||
? `chatWindow: {
|
||||
welcomeMessage: "Hello! This is custom welcome message",
|
||||
backgroundColor: "#ffffff",
|
||||
height: 700,
|
||||
width: 400,
|
||||
fontSize: 16,
|
||||
poweredByTextColor: "#303235",
|
||||
botMessage: {
|
||||
backgroundColor: "#f7f8ff",
|
||||
textColor: "#303235",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png",
|
||||
},
|
||||
userMessage: {
|
||||
backgroundColor: "#3B81F6",
|
||||
textColor: "#ffffff",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/usericon.png",
|
||||
},
|
||||
textInput: {
|
||||
placeholder: "Type your question",
|
||||
backgroundColor: "#ffffff",
|
||||
textColor: "#303235",
|
||||
sendButtonColor: "#3B81F6",
|
||||
}
|
||||
}`
|
||||
: `chatWindow: {
|
||||
welcomeMessage: "Hello! This is custom welcome message",
|
||||
backgroundColor: "#ffffff",
|
||||
height: 700,
|
||||
width: 400,
|
||||
fontSize: 16,
|
||||
poweredByTextColor: "#303235",
|
||||
botMessage: {
|
||||
backgroundColor: "#f7f8ff",
|
||||
textColor: "#303235",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png",
|
||||
},
|
||||
userMessage: {
|
||||
backgroundColor: "#3B81F6",
|
||||
textColor: "#ffffff",
|
||||
showAvatar: true,
|
||||
avatarSrc: "https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/usericon.png",
|
||||
},
|
||||
textInput: {
|
||||
placeholder: "Type your question",
|
||||
backgroundColor: "#ffffff",
|
||||
textColor: "#303235",
|
||||
sendButtonColor: "#3B81F6",
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
const embedPopupHtmlCodeCustomization = (chatflowid) => {
|
||||
return `<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.init({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
chatflowConfig: {
|
||||
// topK: 2
|
||||
},
|
||||
theme: {
|
||||
${buttonConfig()},
|
||||
${chatwindowConfig()}
|
||||
}
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const embedPopupReactCodeCustomization = (chatflowid) => {
|
||||
return `import { BubbleChat } from 'flowise-embed-react'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<BubbleChat
|
||||
chatflowid="${chatflowid}"
|
||||
apiHost="${baseURL}"
|
||||
theme={{
|
||||
${buttonConfig(true)},
|
||||
${chatwindowConfig(true)}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};`
|
||||
}
|
||||
|
||||
const embedFullpageHtmlCodeCustomization = (chatflowid) => {
|
||||
return `<flowise-fullchatbot></flowise-fullchatbot>
|
||||
<script type="module">
|
||||
import Chatbot from "https://cdn.jsdelivr.net/npm/flowise-embed/dist/web.js"
|
||||
Chatbot.initFull({
|
||||
chatflowid: "${chatflowid}",
|
||||
apiHost: "${baseURL}",
|
||||
theme: {
|
||||
${chatwindowConfig()}
|
||||
}
|
||||
})
|
||||
</script>`
|
||||
}
|
||||
|
||||
const embedFullpageReactCodeCustomization = (chatflowid) => {
|
||||
return `import { FullPageChat } from "flowise-embed-react"
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<FullPageChat
|
||||
chatflowid="${chatflowid}"
|
||||
apiHost="${baseURL}"
|
||||
theme={{
|
||||
${chatwindowConfig(true)}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};`
|
||||
}
|
||||
|
||||
const EmbedChat = ({ chatflowid }) => {
|
||||
const codes = ['Popup Html', 'Fullpage Html', 'Popup React', 'Fullpage React']
|
||||
const [value, setValue] = useState(0)
|
||||
const [embedChatCheckboxVal, setEmbedChatCheckbox] = useState(false)
|
||||
|
||||
const onCheckBoxEmbedChatChanged = (newVal) => {
|
||||
setEmbedChatCheckbox(newVal)
|
||||
}
|
||||
|
||||
const handleChange = (event, newValue) => {
|
||||
setValue(newValue)
|
||||
}
|
||||
|
||||
const getCode = (codeLang) => {
|
||||
switch (codeLang) {
|
||||
case 'Popup Html':
|
||||
return embedPopupHtmlCode(chatflowid)
|
||||
case 'Fullpage Html':
|
||||
return embedFullpageHtmlCode(chatflowid)
|
||||
case 'Popup React':
|
||||
return embedPopupReactCode(chatflowid)
|
||||
case 'Fullpage React':
|
||||
return embedFullpageReactCode(chatflowid)
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const getCodeCustomization = (codeLang) => {
|
||||
switch (codeLang) {
|
||||
case 'Popup Html':
|
||||
return embedPopupHtmlCodeCustomization(chatflowid)
|
||||
case 'Fullpage Html':
|
||||
return embedFullpageHtmlCodeCustomization(chatflowid)
|
||||
case 'Popup React':
|
||||
return embedPopupReactCodeCustomization(chatflowid)
|
||||
case 'Fullpage React':
|
||||
return embedFullpageReactCodeCustomization(chatflowid)
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
|
||||
<div style={{ flex: 80 }}>
|
||||
<Tabs value={value} onChange={handleChange} aria-label='tabs'>
|
||||
{codes.map((codeLang, index) => (
|
||||
<Tab key={index} label={codeLang} {...a11yProps(index)}></Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ marginTop: 10 }}></div>
|
||||
{codes.map((codeLang, index) => (
|
||||
<TabPanel key={index} value={value} index={index}>
|
||||
{(value === 0 || value === 1) && (
|
||||
<>
|
||||
<span>
|
||||
Paste this anywhere in the <code>{`<body>`}</code> tag of your html file.
|
||||
<p>
|
||||
You can also specify a
|
||||
<a
|
||||
rel='noreferrer'
|
||||
target='_blank'
|
||||
href='https://www.npmjs.com/package/flowise-embed?activeTab=versions'
|
||||
>
|
||||
version
|
||||
</a>
|
||||
: <code>{`https://cdn.jsdelivr.net/npm/flowise-embed@<version>/dist/web.js`}</code>
|
||||
</p>
|
||||
</span>
|
||||
<div style={{ height: 10 }}></div>
|
||||
</>
|
||||
)}
|
||||
<CopyBlock theme={atomOneDark} text={getCode(codeLang)} language='javascript' showLineNumbers={false} wrapLines />
|
||||
|
||||
<CheckboxInput label='Show Embed Chat Config' value={embedChatCheckboxVal} onChange={onCheckBoxEmbedChatChanged} />
|
||||
|
||||
{embedChatCheckboxVal && (
|
||||
<CopyBlock
|
||||
theme={atomOneDark}
|
||||
text={getCodeCustomization(codeLang)}
|
||||
language='javascript'
|
||||
showLineNumbers={false}
|
||||
wrapLines
|
||||
/>
|
||||
)}
|
||||
</TabPanel>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
EmbedChat.propTypes = {
|
||||
chatflowid: PropTypes.string
|
||||
}
|
||||
|
||||
export default EmbedChat
|
||||
|
|
@ -0,0 +1,420 @@
|
|||
import PropTypes from 'prop-types'
|
||||
import { useState } from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction } from 'store/actions'
|
||||
import { SketchPicker } from 'react-color'
|
||||
|
||||
import { Box, Typography, Button, Switch, OutlinedInput, Popover, Stack, IconButton } from '@mui/material'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
|
||||
// Project import
|
||||
import { StyledButton } from 'ui-component/button/StyledButton'
|
||||
|
||||
// Icons
|
||||
import { IconX, IconCopy, IconArrowUpRightCircle } from '@tabler/icons'
|
||||
|
||||
// API
|
||||
import chatflowsApi from 'api/chatflows'
|
||||
|
||||
// utils
|
||||
import useNotifier from 'utils/useNotifier'
|
||||
|
||||
// Const
|
||||
import { baseURL } from 'store/constant'
|
||||
|
||||
const defaultConfig = {
|
||||
backgroundColor: '#ffffff',
|
||||
fontSize: 16,
|
||||
poweredByTextColor: '#303235',
|
||||
botMessage: {
|
||||
backgroundColor: '#f7f8ff',
|
||||
textColor: '#303235'
|
||||
},
|
||||
userMessage: {
|
||||
backgroundColor: '#3B81F6',
|
||||
textColor: '#ffffff'
|
||||
},
|
||||
textInput: {
|
||||
backgroundColor: '#ffffff',
|
||||
textColor: '#303235',
|
||||
sendButtonColor: '#3B81F6'
|
||||
}
|
||||
}
|
||||
|
||||
const ShareChatbot = ({ chatflowid, chatbotConfig }) => {
|
||||
const dispatch = useDispatch()
|
||||
const theme = useTheme()
|
||||
|
||||
useNotifier()
|
||||
|
||||
const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
|
||||
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
|
||||
|
||||
const [welcomeMessage, setWelcomeMessage] = useState(chatbotConfig?.welcomeMessage ?? '')
|
||||
const [backgroundColor, setBackgroundColor] = useState(chatbotConfig?.backgroundColor ?? defaultConfig.backgroundColor)
|
||||
const [fontSize, setFontSize] = useState(chatbotConfig?.fontSize ?? defaultConfig.fontSize)
|
||||
const [poweredByTextColor, setPoweredByTextColor] = useState(chatbotConfig?.poweredByTextColor ?? defaultConfig.poweredByTextColor)
|
||||
|
||||
const [botMessageBackgroundColor, setBotMessageBackgroundColor] = useState(
|
||||
chatbotConfig?.botMessage?.backgroundColor ?? defaultConfig.botMessage.backgroundColor
|
||||
)
|
||||
const [botMessageTextColor, setBotMessageTextColor] = useState(
|
||||
chatbotConfig?.botMessage?.textColor ?? defaultConfig.botMessage.textColor
|
||||
)
|
||||
const [botMessageAvatarSrc, setBotMessageAvatarSrc] = useState(chatbotConfig?.botMessage?.avatarSrc ?? '')
|
||||
const [botMessageShowAvatar, setBotMessageShowAvatar] = useState(chatbotConfig?.botMessage?.showAvatar ?? false)
|
||||
|
||||
const [userMessageBackgroundColor, setUserMessageBackgroundColor] = useState(
|
||||
chatbotConfig?.userMessage?.backgroundColor ?? defaultConfig.userMessage.backgroundColor
|
||||
)
|
||||
const [userMessageTextColor, setUserMessageTextColor] = useState(
|
||||
chatbotConfig?.userMessage?.textColor ?? defaultConfig.userMessage.textColor
|
||||
)
|
||||
const [userMessageAvatarSrc, setUserMessageAvatarSrc] = useState(chatbotConfig?.userMessage?.avatarSrc ?? '')
|
||||
const [userMessageShowAvatar, setUserMessageShowAvatar] = useState(chatbotConfig?.userMessage?.showAvatar ?? false)
|
||||
|
||||
const [textInputBackgroundColor, setTextInputBackgroundColor] = useState(
|
||||
chatbotConfig?.textInput?.backgroundColor ?? defaultConfig.textInput.backgroundColor
|
||||
)
|
||||
const [textInputTextColor, setTextInputTextColor] = useState(chatbotConfig?.textInput?.textColor ?? defaultConfig.textInput.textColor)
|
||||
const [textInputPlaceholder, setTextInputPlaceholder] = useState(chatbotConfig?.textInput?.placeholder ?? '')
|
||||
const [textInputSendButtonColor, setTextInputSendButtonColor] = useState(
|
||||
chatbotConfig?.textInput?.sendButtonColor ?? defaultConfig.textInput.sendButtonColor
|
||||
)
|
||||
|
||||
const [colorAnchorEl, setColorAnchorEl] = useState(null)
|
||||
const [selectedColorConfig, setSelectedColorConfig] = useState('')
|
||||
const [sketchPickerColor, setSketchPickerColor] = useState('')
|
||||
const openColorPopOver = Boolean(colorAnchorEl)
|
||||
|
||||
const [copyAnchorEl, setCopyAnchorEl] = useState(null)
|
||||
const openCopyPopOver = Boolean(copyAnchorEl)
|
||||
|
||||
const formatObj = () => {
|
||||
const obj = {
|
||||
botMessage: {
|
||||
showAvatar: false
|
||||
},
|
||||
userMessage: {
|
||||
showAvatar: false
|
||||
},
|
||||
textInput: {}
|
||||
}
|
||||
if (welcomeMessage) obj.welcomeMessage = welcomeMessage
|
||||
if (backgroundColor) obj.backgroundColor = backgroundColor
|
||||
if (fontSize) obj.fontSize = fontSize
|
||||
if (poweredByTextColor) obj.poweredByTextColor = poweredByTextColor
|
||||
|
||||
if (botMessageBackgroundColor) obj.botMessage.backgroundColor = botMessageBackgroundColor
|
||||
if (botMessageTextColor) obj.botMessage.textColor = botMessageTextColor
|
||||
if (botMessageAvatarSrc) obj.botMessage.avatarSrc = botMessageAvatarSrc
|
||||
if (botMessageShowAvatar) obj.botMessage.showAvatar = botMessageShowAvatar
|
||||
|
||||
if (userMessageBackgroundColor) obj.userMessage.backgroundColor = userMessageBackgroundColor
|
||||
if (userMessageTextColor) obj.userMessage.textColor = userMessageTextColor
|
||||
if (userMessageAvatarSrc) obj.userMessage.avatarSrc = userMessageAvatarSrc
|
||||
if (userMessageShowAvatar) obj.userMessage.showAvatar = userMessageShowAvatar
|
||||
|
||||
if (textInputBackgroundColor) obj.textInput.backgroundColor = textInputBackgroundColor
|
||||
if (textInputTextColor) obj.textInput.textColor = textInputTextColor
|
||||
if (textInputPlaceholder) obj.textInput.placeholder = textInputPlaceholder
|
||||
if (textInputSendButtonColor) obj.textInput.sendButtonColor = textInputSendButtonColor
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
const onSave = async () => {
|
||||
try {
|
||||
const saveResp = await chatflowsApi.updateChatflow(chatflowid, {
|
||||
chatbotConfig: JSON.stringify(formatObj())
|
||||
})
|
||||
if (saveResp.data) {
|
||||
enqueueSnackbar({
|
||||
message: 'Chatbot Configuration Saved',
|
||||
options: {
|
||||
key: new Date().getTime() + Math.random(),
|
||||
variant: 'success',
|
||||
action: (key) => (
|
||||
<Button style={{ color: 'white' }} onClick={() => closeSnackbar(key)}>
|
||||
<IconX />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
|
||||
enqueueSnackbar({
|
||||
message: `Failed to save Chatbot Configuration: ${errorData}`,
|
||||
options: {
|
||||
key: new Date().getTime() + Math.random(),
|
||||
variant: 'error',
|
||||
persist: true,
|
||||
action: (key) => (
|
||||
<Button style={{ color: 'white' }} onClick={() => closeSnackbar(key)}>
|
||||
<IconX />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleClosePopOver = () => {
|
||||
setColorAnchorEl(null)
|
||||
}
|
||||
|
||||
const handleCloseCopyPopOver = () => {
|
||||
setCopyAnchorEl(null)
|
||||
}
|
||||
|
||||
const onColorSelected = (hexColor) => {
|
||||
switch (selectedColorConfig) {
|
||||
case 'backgroundColor':
|
||||
setBackgroundColor(hexColor)
|
||||
break
|
||||
case 'poweredByTextColor':
|
||||
setPoweredByTextColor(hexColor)
|
||||
break
|
||||
case 'botMessageBackgroundColor':
|
||||
setBotMessageBackgroundColor(hexColor)
|
||||
break
|
||||
case 'botMessageTextColor':
|
||||
setBotMessageTextColor(hexColor)
|
||||
break
|
||||
case 'userMessageBackgroundColor':
|
||||
setUserMessageBackgroundColor(hexColor)
|
||||
break
|
||||
case 'userMessageTextColor':
|
||||
setUserMessageTextColor(hexColor)
|
||||
break
|
||||
case 'textInputBackgroundColor':
|
||||
setTextInputBackgroundColor(hexColor)
|
||||
break
|
||||
case 'textInputTextColor':
|
||||
setTextInputTextColor(hexColor)
|
||||
break
|
||||
case 'textInputSendButtonColor':
|
||||
setTextInputSendButtonColor(hexColor)
|
||||
break
|
||||
}
|
||||
setSketchPickerColor(hexColor)
|
||||
}
|
||||
|
||||
const onTextChanged = (value, fieldName) => {
|
||||
switch (fieldName) {
|
||||
case 'welcomeMessage':
|
||||
setWelcomeMessage(value)
|
||||
break
|
||||
case 'fontSize':
|
||||
setFontSize(value)
|
||||
break
|
||||
case 'botMessageAvatarSrc':
|
||||
setBotMessageAvatarSrc(value)
|
||||
break
|
||||
case 'userMessageAvatarSrc':
|
||||
setUserMessageAvatarSrc(value)
|
||||
break
|
||||
case 'textInputPlaceholder':
|
||||
setTextInputPlaceholder(value)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const onBooleanChanged = (value, fieldName) => {
|
||||
switch (fieldName) {
|
||||
case 'botMessageShowAvatar':
|
||||
setBotMessageShowAvatar(value)
|
||||
break
|
||||
case 'userMessageShowAvatar':
|
||||
setUserMessageShowAvatar(value)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const colorField = (color, fieldName, fieldLabel) => {
|
||||
return (
|
||||
<Box sx={{ pt: 2, pb: 2 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<Typography sx={{ mb: 1 }}>{fieldLabel}</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
width: '30px',
|
||||
height: '30px',
|
||||
border: '1px solid #616161',
|
||||
marginRight: '10px',
|
||||
backgroundColor: color ?? '#ffffff',
|
||||
borderRadius: '5px'
|
||||
}}
|
||||
onClick={(event) => {
|
||||
setSelectedColorConfig(fieldName)
|
||||
setSketchPickerColor(color ?? '#ffffff')
|
||||
setColorAnchorEl(event.currentTarget)
|
||||
}}
|
||||
></Box>
|
||||
</div>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const booleanField = (value, fieldName, fieldLabel) => {
|
||||
return (
|
||||
<Box sx={{ pt: 2, pb: 2 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<Typography sx={{ mb: 1 }}>{fieldLabel}</Typography>
|
||||
<Switch
|
||||
id={fieldName}
|
||||
checked={value}
|
||||
onChange={(event) => {
|
||||
onBooleanChanged(event.target.checked, fieldName)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const textField = (message, fieldName, fieldLabel, fieldType = 'string', placeholder = '') => {
|
||||
return (
|
||||
<Box sx={{ pt: 2, pb: 2 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||
<Typography sx={{ mb: 1 }}>{fieldLabel}</Typography>
|
||||
<OutlinedInput
|
||||
id={fieldName}
|
||||
type={fieldType}
|
||||
fullWidth
|
||||
value={message}
|
||||
placeholder={placeholder}
|
||||
name={fieldName}
|
||||
onChange={(e) => {
|
||||
onTextChanged(e.target.value, fieldName)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack direction='row'>
|
||||
<Typography
|
||||
sx={{
|
||||
p: 1,
|
||||
borderRadius: 10,
|
||||
backgroundColor: theme.palette.primary.light,
|
||||
width: 'max-content',
|
||||
height: 'max-content'
|
||||
}}
|
||||
variant='h5'
|
||||
>
|
||||
{`${baseURL}/chatbot/${chatflowid}`}
|
||||
</Typography>
|
||||
<IconButton
|
||||
title='Copy Link'
|
||||
color='success'
|
||||
onClick={(event) => {
|
||||
navigator.clipboard.writeText(`${baseURL}/chatbot/${chatflowid}`)
|
||||
setCopyAnchorEl(event.currentTarget)
|
||||
setTimeout(() => {
|
||||
handleCloseCopyPopOver()
|
||||
}, 1500)
|
||||
}}
|
||||
>
|
||||
<IconCopy />
|
||||
</IconButton>
|
||||
<IconButton title='Open New Tab' color='primary' onClick={() => window.open(`${baseURL}/chatbot/${chatflowid}`, '_blank')}>
|
||||
<IconArrowUpRightCircle />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
{textField(welcomeMessage, 'welcomeMessage', 'Welcome Message', 'string', 'Hello! This is custom welcome message')}
|
||||
{colorField(backgroundColor, 'backgroundColor', 'Background Color')}
|
||||
{textField(fontSize, 'fontSize', 'Font Size', 'number')}
|
||||
{colorField(poweredByTextColor, 'poweredByTextColor', 'PoweredBy TextColor')}
|
||||
|
||||
{/*BOT Message*/}
|
||||
<Typography variant='h4' sx={{ mb: 1, mt: 2 }}>
|
||||
Bot Message
|
||||
</Typography>
|
||||
{colorField(botMessageBackgroundColor, 'botMessageBackgroundColor', 'Background Color')}
|
||||
{colorField(botMessageTextColor, 'botMessageTextColor', 'Text Color')}
|
||||
{textField(
|
||||
botMessageAvatarSrc,
|
||||
'botMessageAvatarSrc',
|
||||
'Avatar Link',
|
||||
'string',
|
||||
`https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/parroticon.png`
|
||||
)}
|
||||
{booleanField(botMessageShowAvatar, 'botMessageShowAvatar', 'Show Avatar')}
|
||||
|
||||
{/*USER Message*/}
|
||||
<Typography variant='h4' sx={{ mb: 1, mt: 2 }}>
|
||||
User Message
|
||||
</Typography>
|
||||
{colorField(userMessageBackgroundColor, 'userMessageBackgroundColor', 'Background Color')}
|
||||
{colorField(userMessageTextColor, 'userMessageTextColor', 'Text Color')}
|
||||
{textField(
|
||||
userMessageAvatarSrc,
|
||||
'userMessageAvatarSrc',
|
||||
'Avatar Link',
|
||||
'string',
|
||||
`https://raw.githubusercontent.com/zahidkhawaja/langchain-chat-nextjs/main/public/usericon.png`
|
||||
)}
|
||||
{booleanField(userMessageShowAvatar, 'userMessageShowAvatar', 'Show Avatar')}
|
||||
|
||||
{/*TEXT Input*/}
|
||||
<Typography variant='h4' sx={{ mb: 1, mt: 2 }}>
|
||||
Text Input
|
||||
</Typography>
|
||||
{colorField(textInputBackgroundColor, 'textInputBackgroundColor', 'Background Color')}
|
||||
{colorField(textInputTextColor, 'textInputTextColor', 'Text Color')}
|
||||
{textField(textInputPlaceholder, 'textInputPlaceholder', 'TextInput Placeholder', 'string', `Type question..`)}
|
||||
{colorField(textInputSendButtonColor, 'textInputSendButtonColor', 'TextIntput Send Button Color')}
|
||||
|
||||
<StyledButton style={{ marginBottom: 10, marginTop: 10 }} variant='contained' onClick={() => onSave()}>
|
||||
Save Changes
|
||||
</StyledButton>
|
||||
<Popover
|
||||
open={openColorPopOver}
|
||||
anchorEl={colorAnchorEl}
|
||||
onClose={handleClosePopOver}
|
||||
anchorOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right'
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'left'
|
||||
}}
|
||||
>
|
||||
<SketchPicker color={sketchPickerColor} onChange={(color) => onColorSelected(color.hex)} />
|
||||
</Popover>
|
||||
<Popover
|
||||
open={openCopyPopOver}
|
||||
anchorEl={copyAnchorEl}
|
||||
onClose={handleCloseCopyPopOver}
|
||||
anchorOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'right'
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'left'
|
||||
}}
|
||||
>
|
||||
<Typography variant='h6' sx={{ pl: 1, pr: 1, color: 'white', background: theme.palette.success.dark }}>
|
||||
Copied!
|
||||
</Typography>
|
||||
</Popover>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
ShareChatbot.propTypes = {
|
||||
chatflowid: PropTypes.string,
|
||||
chatbotConfig: PropTypes.object
|
||||
}
|
||||
|
||||
export default ShareChatbot
|
||||
Loading…
Reference in New Issue