diff --git a/packages/ui/src/menu-items/settings.js b/packages/ui/src/menu-items/settings.js index af45fba7..3e43d025 100644 --- a/packages/ui/src/menu-items/settings.js +++ b/packages/ui/src/menu-items/settings.js @@ -7,11 +7,20 @@ import { IconSearch, IconMessage, IconPictureInPictureOff, - IconMicrophone + IconAdjustmentsHorizontal } from '@tabler/icons' // constant -const icons = { IconTrash, IconFileUpload, IconFileExport, IconCopy, IconSearch, IconMessage, IconPictureInPictureOff, IconMicrophone } +const icons = { + IconTrash, + IconFileUpload, + IconFileExport, + IconCopy, + IconSearch, + IconMessage, + IconPictureInPictureOff, + IconAdjustmentsHorizontal +} // ==============================|| SETTINGS MENU ITEMS ||============================== // @@ -35,11 +44,11 @@ const settings = { icon: icons.IconMessage }, { - id: 'enableSpeechToText', - title: 'Speech to Text', + id: 'chatflowConfiguration', + title: 'Configuration', type: 'item', url: '', - icon: icons.IconMicrophone + icon: icons.IconAdjustmentsHorizontal }, { id: 'duplicateChatflow', diff --git a/packages/ui/src/ui-component/dialog/ChatflowConfigurationDialog.js b/packages/ui/src/ui-component/dialog/ChatflowConfigurationDialog.js new file mode 100644 index 00000000..5f5b78a7 --- /dev/null +++ b/packages/ui/src/ui-component/dialog/ChatflowConfigurationDialog.js @@ -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 ( + + ) +} + +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 ? ( + + +
{dialogProps.title}
+
+ + setTabValue(value)} + aria-label='tabs' + > + {CHATFLOW_CONFIGURATION_TABS.map((item, index) => ( + + ))} + + {CHATFLOW_CONFIGURATION_TABS.map((item, index) => ( + + {item.id === 'rateLimiting' && } + {item.id === 'speechToText' ? : null} + + ))} + +
+ ) : null + + return createPortal(component, portalElement) +} + +ChatflowConfigurationDialog.propTypes = { + show: PropTypes.bool, + dialogProps: PropTypes.object, + onCancel: PropTypes.func +} + +export default ChatflowConfigurationDialog diff --git a/packages/ui/src/ui-component/dialog/SpeechToTextDialog.js b/packages/ui/src/ui-component/dialog/SpeechToTextDialog.js index 489d4335..7199bf8c 100644 --- a/packages/ui/src/ui-component/dialog/SpeechToTextDialog.js +++ b/packages/ui/src/ui-component/dialog/SpeechToTextDialog.js @@ -1,25 +1,10 @@ -import { createPortal } from 'react-dom' import { useDispatch } from 'react-redux' import { useState, useEffect } from 'react' import PropTypes from 'prop-types' import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions' // material-ui -import { - Typography, - Box, - Button, - Dialog, - DialogContent, - DialogTitle, - DialogActions, - FormControl, - ListItem, - ListItemAvatar, - ListItemText, - MenuItem, - Select -} from '@mui/material' +import { Typography, Box, Button, FormControl, ListItem, ListItemAvatar, ListItemText, MenuItem, Select } from '@mui/material' import { IconX } from '@tabler/icons' // Project import @@ -33,7 +18,6 @@ import openAISVG from 'assets/images/openai.svg' import assemblyAIPng from 'assets/images/assemblyai.png' // store -import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions' import useNotifier from 'utils/useNotifier' // API @@ -95,8 +79,7 @@ const speechToTextProviders = { } } -const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => { - const portalElement = document.getElementById('portal') +const SpeechToText = ({ dialogProps }) => { const dispatch = useDispatch() useNotifier() @@ -128,7 +111,6 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => { }) dispatch({ type: SET_CHATFLOW, chatflow: saveResp.data }) } - onCancel() } catch (error) { const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}` enqueueSnackbar({ @@ -199,150 +181,126 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => { } }, [dialogProps]) - useEffect(() => { - if (show) dispatch({ type: SHOW_CANVAS_DIALOG }) - else dispatch({ type: HIDE_CANVAS_DIALOG }) - return () => dispatch({ type: HIDE_CANVAS_DIALOG }) - }, [show, dispatch]) - - const component = ( - - - Speech To Text Configuration - - - - Speech To Text Providers - - - - - {selectedProvider !== 'none' && ( - <> - - -
+ + Speech To Text Providers + + + + + {selectedProvider !== 'none' && ( + <> + + +
+ - AI -
-
- - {speechToTextProviders[selectedProvider].url} - - } - /> -
- {speechToTextProviders[selectedProvider].inputs.map((inputParam, index) => ( - -
- - {inputParam.label} - {!inputParam.optional &&  *} - {inputParam.description && ( - - )} - -
- {inputParam.type === 'credential' && ( - setValue(newValue, selectedProvider, 'credentialId')} - /> - )} - {inputParam.type === 'boolean' && ( - setValue(newValue, selectedProvider, inputParam.name)} - value={ - speechToText[selectedProvider] - ? speechToText[selectedProvider][inputParam.name] - : inputParam.default ?? false - } - /> - )} - {(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && ( - setValue(newValue, selectedProvider, inputParam.name)} - value={ - speechToText[selectedProvider] - ? speechToText[selectedProvider][inputParam.name] - : inputParam.default ?? '' - } - /> - )} + alt='AI' + src={speechToTextProviders[selectedProvider].icon} + /> +
+
+ + {speechToTextProviders[selectedProvider].url} + + } + /> +
+ {speechToTextProviders[selectedProvider].inputs.map((inputParam, index) => ( + +
+ + {inputParam.label} + {!inputParam.optional &&  *} + {inputParam.description && ( + + )} + +
+ {inputParam.type === 'credential' && ( + setValue(newValue, selectedProvider, 'credentialId')} + /> + )} + {inputParam.type === 'boolean' && ( + setValue(newValue, selectedProvider, inputParam.name)} + value={ + speechToText[selectedProvider] + ? speechToText[selectedProvider][inputParam.name] + : inputParam.default ?? false + } + /> + )} + {(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && ( + setValue(newValue, selectedProvider, inputParam.name)} + value={ + speechToText[selectedProvider] + ? speechToText[selectedProvider][inputParam.name] + : inputParam.default ?? '' + } + /> + )} - {inputParam.type === 'options' && ( - setValue(newValue, selectedProvider, inputParam.name)} - value={ - speechToText[selectedProvider] - ? speechToText[selectedProvider][inputParam.name] - : inputParam.default ?? 'choose an option' - } - /> - )} -
- ))} - - )} -
- - - Save - - -
+ {inputParam.type === 'options' && ( + setValue(newValue, selectedProvider, inputParam.name)} + value={ + speechToText[selectedProvider] + ? speechToText[selectedProvider][inputParam.name] + : inputParam.default ?? 'choose an option' + } + /> + )} + + ))} + + )} + + Save + + ) - - return createPortal(component, portalElement) } -SpeechToTextDialog.propTypes = { - show: PropTypes.bool, - dialogProps: PropTypes.object, - onCancel: PropTypes.func +SpeechToText.propTypes = { + dialogProps: PropTypes.object } -export default SpeechToTextDialog +export default SpeechToText diff --git a/packages/ui/src/views/canvas/CanvasHeader.js b/packages/ui/src/views/canvas/CanvasHeader.js index a8589f48..d9f54d19 100644 --- a/packages/ui/src/views/canvas/CanvasHeader.js +++ b/packages/ui/src/views/canvas/CanvasHeader.js @@ -28,7 +28,7 @@ import useApi from 'hooks/useApi' import { generateExportFlowData } from 'utils/genericHelper' import { uiBaseURL } from 'store/constant' import { SET_CHATFLOW } from 'store/actions' -import SpeechToTextDialog from '../../ui-component/dialog/SpeechToTextDialog' +import ChatflowConfigurationDialog from 'ui-component/dialog/ChatflowConfigurationDialog' // ==============================|| CANVAS HEADER ||============================== // @@ -47,12 +47,12 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl const [apiDialogProps, setAPIDialogProps] = useState({}) const [analyseDialogOpen, setAnalyseDialogOpen] = useState(false) const [analyseDialogProps, setAnalyseDialogProps] = useState({}) - const [speechToAudioDialogOpen, setSpeechToAudioDialogOpen] = useState(false) - const [speechToAudioDialogProps, setSpeechToAudioialogProps] = useState({}) const [conversationStartersDialogOpen, setConversationStartersDialogOpen] = useState(false) const [conversationStartersDialogProps, setConversationStartersDialogProps] = useState({}) const [viewMessagesDialogOpen, setViewMessagesDialogOpen] = useState(false) const [viewMessagesDialogProps, setViewMessagesDialogProps] = useState({}) + const [chatflowConfigurationDialogOpen, setChatflowConfigurationDialogOpen] = useState(false) + const [chatflowConfigurationDialogProps, setChatflowConfigurationDialogProps] = useState({}) const updateChatflowApi = useApi(chatflowsApi.updateChatflow) const canvas = useSelector((state) => state.canvas) @@ -74,18 +74,18 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl chatflow: chatflow }) setAnalyseDialogOpen(true) - } else if (setting === 'enableSpeechToText') { - setSpeechToAudioialogProps({ - title: 'Speech to Text', - chatflow: chatflow - }) - setSpeechToAudioDialogOpen(true) } else if (setting === 'viewMessages') { setViewMessagesDialogProps({ title: 'View Messages', chatflow: chatflow }) setViewMessagesDialogOpen(true) + } else if (setting === 'chatflowConfiguration') { + setChatflowConfigurationDialogProps({ + title: 'Chatflow Configuration', + chatflow: chatflow + }) + setChatflowConfigurationDialogOpen(true) } else if (setting === 'duplicateChatflow') { try { localStorage.setItem('duplicatedFlowData', chatflow.flowData) @@ -394,11 +394,6 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl /> setAPIDialogOpen(false)} /> setAnalyseDialogOpen(false)} /> - setSpeechToAudioDialogOpen(false)} - /> setViewMessagesDialogOpen(false)} /> + setChatflowConfigurationDialogOpen(false)} + /> ) } diff --git a/packages/ui/src/views/chatflows/APICodeDialog.js b/packages/ui/src/views/chatflows/APICodeDialog.js index 34c2281f..8889f4ee 100644 --- a/packages/ui/src/views/chatflows/APICodeDialog.js +++ b/packages/ui/src/views/chatflows/APICodeDialog.js @@ -23,7 +23,6 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import { Dropdown } from 'ui-component/dropdown/Dropdown' import ShareChatbot from './ShareChatbot' import EmbedChat from './EmbedChat' -import Configuration from './Configuration' // Const import { baseURL } from 'store/constant' @@ -84,7 +83,7 @@ const APICodeDialog = ({ show, dialogProps, onCancel }) => { const navigate = useNavigate() 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 [keyOptions, setKeyOptions] = useState([]) const [apiKeys, setAPIKeys] = useState([]) @@ -721,7 +720,6 @@ formData.append("openAIApiKey[openAIEmbeddings_0]", "sk-my-openai-2nd-key")` {codeLang === 'Share Chatbot' && !chatflowApiKeyId && ( )} - {codeLang === 'Configuration' && } ))} diff --git a/packages/ui/src/views/settings/index.js b/packages/ui/src/views/settings/index.js index f7019b68..c5171d5e 100644 --- a/packages/ui/src/views/settings/index.js +++ b/packages/ui/src/views/settings/index.js @@ -65,7 +65,7 @@ const Settings = ({ chatflow, isSettingsOpen, anchorEl, onSettingsItemClick, onU width: 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 (