mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 23:01:09 +03:00
Add chatflow config dialog
This commit is contained in:
@@ -7,11 +7,20 @@ import {
|
|||||||
IconSearch,
|
IconSearch,
|
||||||
IconMessage,
|
IconMessage,
|
||||||
IconPictureInPictureOff,
|
IconPictureInPictureOff,
|
||||||
IconMicrophone
|
IconAdjustmentsHorizontal
|
||||||
} from '@tabler/icons'
|
} from '@tabler/icons'
|
||||||
|
|
||||||
// constant
|
// constant
|
||||||
const icons = { IconTrash, IconFileUpload, IconFileExport, IconCopy, IconSearch, IconMessage, IconPictureInPictureOff, IconMicrophone }
|
const icons = {
|
||||||
|
IconTrash,
|
||||||
|
IconFileUpload,
|
||||||
|
IconFileExport,
|
||||||
|
IconCopy,
|
||||||
|
IconSearch,
|
||||||
|
IconMessage,
|
||||||
|
IconPictureInPictureOff,
|
||||||
|
IconAdjustmentsHorizontal
|
||||||
|
}
|
||||||
|
|
||||||
// ==============================|| SETTINGS MENU ITEMS ||============================== //
|
// ==============================|| SETTINGS MENU ITEMS ||============================== //
|
||||||
|
|
||||||
@@ -35,11 +44,11 @@ const settings = {
|
|||||||
icon: icons.IconMessage
|
icon: icons.IconMessage
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'enableSpeechToText',
|
id: 'chatflowConfiguration',
|
||||||
title: 'Speech to Text',
|
title: 'Configuration',
|
||||||
type: 'item',
|
type: 'item',
|
||||||
url: '',
|
url: '',
|
||||||
icon: icons.IconMicrophone
|
icon: icons.IconAdjustmentsHorizontal
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'duplicateChatflow',
|
id: 'duplicateChatflow',
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { createPortal } from 'react-dom'
|
||||||
|
import { Box, Dialog, DialogContent, DialogTitle, Tabs, Tab } from '@mui/material'
|
||||||
|
import SpeechToText from './SpeechToTextDialog'
|
||||||
|
import Configuration from 'views/chatflows/Configuration'
|
||||||
|
|
||||||
|
const CHATFLOW_CONFIGURATION_TABS = [
|
||||||
|
{
|
||||||
|
label: 'Rate Limiting',
|
||||||
|
id: 'rateLimiting'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Speech to Text',
|
||||||
|
id: 'speechToText'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Chat Feedback',
|
||||||
|
id: 'chatFeedback'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Allowed Domains',
|
||||||
|
id: 'allowedDomains'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
function TabPanel(props) {
|
||||||
|
const { children, value, index, ...other } = props
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role='tabpanel'
|
||||||
|
hidden={value !== index}
|
||||||
|
id={`chatflow-config-tabpanel-${index}`}
|
||||||
|
aria-labelledby={`chatflow-config-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: `chatflow-config-tab-${index}`,
|
||||||
|
'aria-controls': `chatflow-config-tabpanel-${index}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChatflowConfigurationDialog = ({ show, dialogProps, onCancel }) => {
|
||||||
|
const portalElement = document.getElementById('portal')
|
||||||
|
const [tabValue, setTabValue] = useState(0)
|
||||||
|
|
||||||
|
const component = show ? (
|
||||||
|
<Dialog
|
||||||
|
onClose={onCancel}
|
||||||
|
open={show}
|
||||||
|
fullWidth
|
||||||
|
maxWidth={'md'}
|
||||||
|
aria-labelledby='alert-dialog-title'
|
||||||
|
aria-describedby='alert-dialog-description'
|
||||||
|
>
|
||||||
|
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'row' }}>{dialogProps.title}</div>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Tabs
|
||||||
|
sx={{ position: 'relative', minHeight: '50px', height: '50px' }}
|
||||||
|
variant='fullWidth'
|
||||||
|
value={tabValue}
|
||||||
|
onChange={(event, value) => setTabValue(value)}
|
||||||
|
aria-label='tabs'
|
||||||
|
>
|
||||||
|
{CHATFLOW_CONFIGURATION_TABS.map((item, index) => (
|
||||||
|
<Tab sx={{ minHeight: '50px', height: '50px' }} key={index} label={item.label} {...a11yProps(index)}></Tab>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
{CHATFLOW_CONFIGURATION_TABS.map((item, index) => (
|
||||||
|
<TabPanel key={index} value={tabValue} index={index}>
|
||||||
|
{item.id === 'rateLimiting' && <Configuration />}
|
||||||
|
{item.id === 'speechToText' ? <SpeechToText dialogProps={dialogProps} /> : null}
|
||||||
|
</TabPanel>
|
||||||
|
))}
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
) : null
|
||||||
|
|
||||||
|
return createPortal(component, portalElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatflowConfigurationDialog.propTypes = {
|
||||||
|
show: PropTypes.bool,
|
||||||
|
dialogProps: PropTypes.object,
|
||||||
|
onCancel: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChatflowConfigurationDialog
|
||||||
@@ -1,25 +1,10 @@
|
|||||||
import { createPortal } from 'react-dom'
|
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions'
|
import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions'
|
||||||
|
|
||||||
// material-ui
|
// material-ui
|
||||||
import {
|
import { Typography, Box, Button, FormControl, ListItem, ListItemAvatar, ListItemText, MenuItem, Select } from '@mui/material'
|
||||||
Typography,
|
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
DialogActions,
|
|
||||||
FormControl,
|
|
||||||
ListItem,
|
|
||||||
ListItemAvatar,
|
|
||||||
ListItemText,
|
|
||||||
MenuItem,
|
|
||||||
Select
|
|
||||||
} from '@mui/material'
|
|
||||||
import { IconX } from '@tabler/icons'
|
import { IconX } from '@tabler/icons'
|
||||||
|
|
||||||
// Project import
|
// Project import
|
||||||
@@ -33,7 +18,6 @@ import openAISVG from 'assets/images/openai.svg'
|
|||||||
import assemblyAIPng from 'assets/images/assemblyai.png'
|
import assemblyAIPng from 'assets/images/assemblyai.png'
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
|
|
||||||
import useNotifier from 'utils/useNotifier'
|
import useNotifier from 'utils/useNotifier'
|
||||||
|
|
||||||
// API
|
// API
|
||||||
@@ -95,8 +79,7 @@ const speechToTextProviders = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
|
const SpeechToText = ({ dialogProps }) => {
|
||||||
const portalElement = document.getElementById('portal')
|
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
useNotifier()
|
useNotifier()
|
||||||
@@ -128,7 +111,6 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
|
|||||||
})
|
})
|
||||||
dispatch({ type: SET_CHATFLOW, chatflow: saveResp.data })
|
dispatch({ type: SET_CHATFLOW, chatflow: saveResp.data })
|
||||||
}
|
}
|
||||||
onCancel()
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
|
const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}`
|
||||||
enqueueSnackbar({
|
enqueueSnackbar({
|
||||||
@@ -199,25 +181,8 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
|
|||||||
}
|
}
|
||||||
}, [dialogProps])
|
}, [dialogProps])
|
||||||
|
|
||||||
useEffect(() => {
|
return (
|
||||||
if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
|
<>
|
||||||
else dispatch({ type: HIDE_CANVAS_DIALOG })
|
|
||||||
return () => dispatch({ type: HIDE_CANVAS_DIALOG })
|
|
||||||
}, [show, dispatch])
|
|
||||||
|
|
||||||
const component = (
|
|
||||||
<Dialog
|
|
||||||
onClose={onCancel}
|
|
||||||
open={show}
|
|
||||||
fullWidth
|
|
||||||
maxWidth='sm'
|
|
||||||
aria-labelledby='alert-dialog-title'
|
|
||||||
aria-describedby='alert-dialog-description'
|
|
||||||
>
|
|
||||||
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
|
|
||||||
Speech To Text Configuration
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<Box fullWidth sx={{ my: 2, display: 'flex', flexDirection: 'column', gap: 1 }}>
|
<Box fullWidth sx={{ my: 2, display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||||
<Typography>Speech To Text Providers</Typography>
|
<Typography>Speech To Text Providers</Typography>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
@@ -323,8 +288,6 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
|
|||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<StyledButton
|
<StyledButton
|
||||||
disabled={selectedProvider !== 'none' && !speechToText[selectedProvider]?.credentialId}
|
disabled={selectedProvider !== 'none' && !speechToText[selectedProvider]?.credentialId}
|
||||||
variant='contained'
|
variant='contained'
|
||||||
@@ -332,17 +295,12 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
|
|||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</DialogActions>
|
</>
|
||||||
</Dialog>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return createPortal(component, portalElement)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeechToTextDialog.propTypes = {
|
SpeechToText.propTypes = {
|
||||||
show: PropTypes.bool,
|
dialogProps: PropTypes.object
|
||||||
dialogProps: PropTypes.object,
|
|
||||||
onCancel: PropTypes.func
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SpeechToTextDialog
|
export default SpeechToText
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import useApi from 'hooks/useApi'
|
|||||||
import { generateExportFlowData } from 'utils/genericHelper'
|
import { generateExportFlowData } from 'utils/genericHelper'
|
||||||
import { uiBaseURL } from 'store/constant'
|
import { uiBaseURL } from 'store/constant'
|
||||||
import { SET_CHATFLOW } from 'store/actions'
|
import { SET_CHATFLOW } from 'store/actions'
|
||||||
import SpeechToTextDialog from '../../ui-component/dialog/SpeechToTextDialog'
|
import ChatflowConfigurationDialog from 'ui-component/dialog/ChatflowConfigurationDialog'
|
||||||
|
|
||||||
// ==============================|| CANVAS HEADER ||============================== //
|
// ==============================|| CANVAS HEADER ||============================== //
|
||||||
|
|
||||||
@@ -47,12 +47,12 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
const [apiDialogProps, setAPIDialogProps] = useState({})
|
const [apiDialogProps, setAPIDialogProps] = useState({})
|
||||||
const [analyseDialogOpen, setAnalyseDialogOpen] = useState(false)
|
const [analyseDialogOpen, setAnalyseDialogOpen] = useState(false)
|
||||||
const [analyseDialogProps, setAnalyseDialogProps] = useState({})
|
const [analyseDialogProps, setAnalyseDialogProps] = useState({})
|
||||||
const [speechToAudioDialogOpen, setSpeechToAudioDialogOpen] = useState(false)
|
|
||||||
const [speechToAudioDialogProps, setSpeechToAudioialogProps] = useState({})
|
|
||||||
const [conversationStartersDialogOpen, setConversationStartersDialogOpen] = useState(false)
|
const [conversationStartersDialogOpen, setConversationStartersDialogOpen] = useState(false)
|
||||||
const [conversationStartersDialogProps, setConversationStartersDialogProps] = useState({})
|
const [conversationStartersDialogProps, setConversationStartersDialogProps] = useState({})
|
||||||
const [viewMessagesDialogOpen, setViewMessagesDialogOpen] = useState(false)
|
const [viewMessagesDialogOpen, setViewMessagesDialogOpen] = useState(false)
|
||||||
const [viewMessagesDialogProps, setViewMessagesDialogProps] = useState({})
|
const [viewMessagesDialogProps, setViewMessagesDialogProps] = useState({})
|
||||||
|
const [chatflowConfigurationDialogOpen, setChatflowConfigurationDialogOpen] = useState(false)
|
||||||
|
const [chatflowConfigurationDialogProps, setChatflowConfigurationDialogProps] = useState({})
|
||||||
|
|
||||||
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
|
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
|
||||||
const canvas = useSelector((state) => state.canvas)
|
const canvas = useSelector((state) => state.canvas)
|
||||||
@@ -74,18 +74,18 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
chatflow: chatflow
|
chatflow: chatflow
|
||||||
})
|
})
|
||||||
setAnalyseDialogOpen(true)
|
setAnalyseDialogOpen(true)
|
||||||
} else if (setting === 'enableSpeechToText') {
|
|
||||||
setSpeechToAudioialogProps({
|
|
||||||
title: 'Speech to Text',
|
|
||||||
chatflow: chatflow
|
|
||||||
})
|
|
||||||
setSpeechToAudioDialogOpen(true)
|
|
||||||
} else if (setting === 'viewMessages') {
|
} else if (setting === 'viewMessages') {
|
||||||
setViewMessagesDialogProps({
|
setViewMessagesDialogProps({
|
||||||
title: 'View Messages',
|
title: 'View Messages',
|
||||||
chatflow: chatflow
|
chatflow: chatflow
|
||||||
})
|
})
|
||||||
setViewMessagesDialogOpen(true)
|
setViewMessagesDialogOpen(true)
|
||||||
|
} else if (setting === 'chatflowConfiguration') {
|
||||||
|
setChatflowConfigurationDialogProps({
|
||||||
|
title: 'Chatflow Configuration',
|
||||||
|
chatflow: chatflow
|
||||||
|
})
|
||||||
|
setChatflowConfigurationDialogOpen(true)
|
||||||
} else if (setting === 'duplicateChatflow') {
|
} else if (setting === 'duplicateChatflow') {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem('duplicatedFlowData', chatflow.flowData)
|
localStorage.setItem('duplicatedFlowData', chatflow.flowData)
|
||||||
@@ -394,11 +394,6 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
/>
|
/>
|
||||||
<APICodeDialog show={apiDialogOpen} dialogProps={apiDialogProps} onCancel={() => setAPIDialogOpen(false)} />
|
<APICodeDialog show={apiDialogOpen} dialogProps={apiDialogProps} onCancel={() => setAPIDialogOpen(false)} />
|
||||||
<AnalyseFlowDialog show={analyseDialogOpen} dialogProps={analyseDialogProps} onCancel={() => setAnalyseDialogOpen(false)} />
|
<AnalyseFlowDialog show={analyseDialogOpen} dialogProps={analyseDialogProps} onCancel={() => setAnalyseDialogOpen(false)} />
|
||||||
<SpeechToTextDialog
|
|
||||||
show={speechToAudioDialogOpen}
|
|
||||||
dialogProps={speechToAudioDialogProps}
|
|
||||||
onCancel={() => setSpeechToAudioDialogOpen(false)}
|
|
||||||
/>
|
|
||||||
<StarterPromptsDialog
|
<StarterPromptsDialog
|
||||||
show={conversationStartersDialogOpen}
|
show={conversationStartersDialogOpen}
|
||||||
dialogProps={conversationStartersDialogProps}
|
dialogProps={conversationStartersDialogProps}
|
||||||
@@ -410,6 +405,11 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl
|
|||||||
dialogProps={viewMessagesDialogProps}
|
dialogProps={viewMessagesDialogProps}
|
||||||
onCancel={() => setViewMessagesDialogOpen(false)}
|
onCancel={() => setViewMessagesDialogOpen(false)}
|
||||||
/>
|
/>
|
||||||
|
<ChatflowConfigurationDialog
|
||||||
|
show={chatflowConfigurationDialogOpen}
|
||||||
|
dialogProps={chatflowConfigurationDialogProps}
|
||||||
|
onCancel={() => setChatflowConfigurationDialogOpen(false)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
|||||||
import { Dropdown } from 'ui-component/dropdown/Dropdown'
|
import { Dropdown } from 'ui-component/dropdown/Dropdown'
|
||||||
import ShareChatbot from './ShareChatbot'
|
import ShareChatbot from './ShareChatbot'
|
||||||
import EmbedChat from './EmbedChat'
|
import EmbedChat from './EmbedChat'
|
||||||
import Configuration from './Configuration'
|
|
||||||
|
|
||||||
// Const
|
// Const
|
||||||
import { baseURL } from 'store/constant'
|
import { baseURL } from 'store/constant'
|
||||||
@@ -84,7 +83,7 @@ const APICodeDialog = ({ show, dialogProps, onCancel }) => {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const codes = ['Embed', 'Python', 'JavaScript', 'cURL', 'Share Chatbot', 'Configuration']
|
const codes = ['Embed', 'Python', 'JavaScript', 'cURL', 'Share Chatbot']
|
||||||
const [value, setValue] = useState(0)
|
const [value, setValue] = useState(0)
|
||||||
const [keyOptions, setKeyOptions] = useState([])
|
const [keyOptions, setKeyOptions] = useState([])
|
||||||
const [apiKeys, setAPIKeys] = useState([])
|
const [apiKeys, setAPIKeys] = useState([])
|
||||||
@@ -721,7 +720,6 @@ formData.append("openAIApiKey[openAIEmbeddings_0]", "sk-my-openai-2nd-key")`
|
|||||||
{codeLang === 'Share Chatbot' && !chatflowApiKeyId && (
|
{codeLang === 'Share Chatbot' && !chatflowApiKeyId && (
|
||||||
<ShareChatbot isSessionMemory={dialogProps.isSessionMemory} />
|
<ShareChatbot isSessionMemory={dialogProps.isSessionMemory} />
|
||||||
)}
|
)}
|
||||||
{codeLang === 'Configuration' && <Configuration />}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
))}
|
))}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const Settings = ({ chatflow, isSettingsOpen, anchorEl, onSettingsItemClick, onU
|
|||||||
width: customization.isOpen.findIndex((id) => id === menu?.id) > -1 ? 8 : 6,
|
width: customization.isOpen.findIndex((id) => id === menu?.id) > -1 ? 8 : 6,
|
||||||
height: customization.isOpen.findIndex((id) => id === menu?.id) > -1 ? 8 : 6
|
height: customization.isOpen.findIndex((id) => id === menu?.id) > -1 ? 8 : 6
|
||||||
}}
|
}}
|
||||||
fontSize={level > 0 ? 'inherit' : 'medium'}
|
fontSize={'inherit'}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user