Update UI of speech to text dialog

This commit is contained in:
Ilango
2024-02-19 11:49:01 +05:30
parent 10fc1bf08d
commit 81c07dc8c1
3 changed files with 145 additions and 158 deletions
@@ -13,14 +13,13 @@ import {
DialogContent, DialogContent,
DialogTitle, DialogTitle,
DialogActions, DialogActions,
Accordion, FormControl,
AccordionSummary,
AccordionDetails,
ListItem, ListItem,
ListItemAvatar, ListItemAvatar,
ListItemText ListItemText,
MenuItem,
Select
} from '@mui/material' } from '@mui/material'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import { IconX } from '@tabler/icons' import { IconX } from '@tabler/icons'
// Project import // Project import
@@ -40,8 +39,8 @@ import useNotifier from 'utils/useNotifier'
// API // API
import chatflowsApi from 'api/chatflows' import chatflowsApi from 'api/chatflows'
const speechToTextProviders = [ const speechToTextProviders = {
{ openAIWhisper: {
label: 'OpenAI Whisper', label: 'OpenAI Whisper',
name: 'openAIWhisper', name: 'openAIWhisper',
icon: openAISVG, icon: openAISVG,
@@ -77,16 +76,10 @@ const speechToTextProviders = [
step: 0.1, step: 0.1,
description: `The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.`, description: `The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.`,
optional: true optional: true
},
{
label: 'On/Off',
name: 'status',
type: 'boolean',
optional: true
} }
] ]
}, },
{ assemblyAiTranscribe: {
label: 'Assembly AI', label: 'Assembly AI',
name: 'assemblyAiTranscribe', name: 'assemblyAiTranscribe',
icon: assemblyAIPng, icon: assemblyAIPng,
@@ -97,16 +90,10 @@ const speechToTextProviders = [
name: 'credential', name: 'credential',
type: 'credential', type: 'credential',
credentialNames: ['assemblyAIApi'] credentialNames: ['assemblyAIApi']
},
{
label: 'On/Off',
name: 'status',
type: 'boolean',
optional: true
} }
] ]
} }
] }
const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => { const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
const portalElement = document.getElementById('portal') const portalElement = document.getElementById('portal')
@@ -118,7 +105,7 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args)) const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
const [speechToText, setSpeechToText] = useState({}) const [speechToText, setSpeechToText] = useState({})
const [providerExpanded, setProviderExpanded] = useState({}) const [selectedProvider, setSelectedProvider] = useState('openAIWhisper')
const onSave = async () => { const onSave = async () => {
try { try {
@@ -169,8 +156,9 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
newVal[providerName][inputParamName] = value newVal[providerName][inputParamName] = value
if (inputParamName === 'status' && value === true) { if (inputParamName === 'status' && value === true) {
//ensure that the others are turned off // ensure that the others are turned off
speechToTextProviders.forEach((provider) => { Object.keys(speechToTextProviders).forEach((key) => {
const provider = speechToTextProviders[key]
if (provider.name !== providerName) { if (provider.name !== providerName) {
newVal[provider.name] = { ...speechToText[provider.name], status: false } newVal[provider.name] = { ...speechToText[provider.name], status: false }
} }
@@ -179,10 +167,9 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
setSpeechToText(newVal) setSpeechToText(newVal)
} }
const handleAccordionChange = (providerName) => (event, isExpanded) => { const handleProviderChange = (event) => {
const accordionProviders = { ...providerExpanded } setSelectedProvider(event.target.value)
accordionProviders[providerName] = isExpanded setValue(true, event.target.value, 'status')
setProviderExpanded(accordionProviders)
} }
useEffect(() => { useEffect(() => {
@@ -197,7 +184,6 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
return () => { return () => {
setSpeechToText({}) setSpeechToText({})
setProviderExpanded({})
} }
}, [dialogProps]) }, [dialogProps])
@@ -220,14 +206,16 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
Speech To Text Configuration Speech To Text Configuration
</DialogTitle> </DialogTitle>
<DialogContent> <DialogContent>
{speechToTextProviders.map((provider, index) => ( <Box fullWidth sx={{ my: 2, display: 'flex', flexDirection: 'column', gap: 1 }}>
<Accordion <Typography>Speech To Text Providers</Typography>
expanded={providerExpanded[provider.name] || false} <FormControl fullWidth>
onChange={handleAccordionChange(provider.name)} <Select value={selectedProvider} onChange={handleProviderChange}>
disableGutters <MenuItem value='openAIWhisper'>OpenAI Whisper</MenuItem>
key={index} <MenuItem value='assemblyAiTranscribe'>Assembly AI</MenuItem>
> </Select>
<AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls={provider.name} id={provider.name}> </FormControl>
</Box>
<>
<ListItem style={{ padding: 0, margin: 0 }} alignItems='center'> <ListItem style={{ padding: 0, margin: 0 }} alignItems='center'>
<ListItemAvatar> <ListItemAvatar>
<div <div
@@ -246,20 +234,20 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
objectFit: 'contain' objectFit: 'contain'
}} }}
alt='AI' alt='AI'
src={provider.icon} src={speechToTextProviders[selectedProvider].icon}
/> />
</div> </div>
</ListItemAvatar> </ListItemAvatar>
<ListItemText <ListItemText
sx={{ ml: 1 }} sx={{ ml: 1 }}
primary={provider.label} primary={speechToTextProviders[selectedProvider].label}
secondary={ secondary={
<a target='_blank' rel='noreferrer' href={provider.url}> <a target='_blank' rel='noreferrer' href={speechToTextProviders[selectedProvider].url}>
{provider.url} {speechToTextProviders[selectedProvider].url}
</a> </a>
} }
/> />
{speechToText[provider.name] && speechToText[provider.name].status && ( {speechToText[selectedProvider] && speechToText[selectedProvider].status && (
<div <div
style={{ style={{
display: 'flex', display: 'flex',
@@ -286,9 +274,7 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
</div> </div>
)} )}
</ListItem> </ListItem>
</AccordionSummary> {speechToTextProviders[selectedProvider].inputs.map((inputParam, index) => (
<AccordionDetails>
{provider.inputs.map((inputParam, index) => (
<Box key={index} sx={{ p: 2 }}> <Box key={index} sx={{ p: 2 }}>
<div style={{ display: 'flex', flexDirection: 'row' }}> <div style={{ display: 'flex', flexDirection: 'row' }}>
<Typography> <Typography>
@@ -299,57 +285,50 @@ const SpeechToTextDialog = ({ show, dialogProps, onCancel }) => {
)} )}
</Typography> </Typography>
</div> </div>
{providerExpanded[provider.name] && inputParam.type === 'credential' && ( {inputParam.type === 'credential' && (
<CredentialInputHandler <CredentialInputHandler
data={ data={speechToText[selectedProvider] ? { credential: speechToText[selectedProvider].credentialId } : {}}
speechToText[provider.name] ? { credential: speechToText[provider.name].credentialId } : {}
}
inputParam={inputParam} inputParam={inputParam}
onSelect={(newValue) => setValue(newValue, provider.name, 'credentialId')} onSelect={(newValue) => setValue(newValue, selectedProvider, 'credentialId')}
/> />
)} )}
{inputParam.type === 'boolean' && ( {inputParam.type === 'boolean' && (
<SwitchInput <SwitchInput
onChange={(newValue) => setValue(newValue, provider.name, inputParam.name)} onChange={(newValue) => setValue(newValue, selectedProvider, inputParam.name)}
value={ value={
speechToText[provider.name] speechToText[selectedProvider]
? speechToText[provider.name][inputParam.name] ? speechToText[selectedProvider][inputParam.name]
: inputParam.default ?? false : inputParam.default ?? false
} }
/> />
)} )}
{providerExpanded[provider.name] && {(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && (
(inputParam.type === 'string' ||
inputParam.type === 'password' ||
inputParam.type === 'number') && (
<Input <Input
inputParam={inputParam} inputParam={inputParam}
onChange={(newValue) => setValue(newValue, provider.name, inputParam.name)} onChange={(newValue) => setValue(newValue, selectedProvider, inputParam.name)}
value={ value={
speechToText[provider.name] speechToText[selectedProvider]
? speechToText[provider.name][inputParam.name] ? speechToText[selectedProvider][inputParam.name]
: inputParam.default ?? '' : inputParam.default ?? ''
} }
/> />
)} )}
{providerExpanded[provider.name] && inputParam.type === 'options' && ( {inputParam.type === 'options' && (
<Dropdown <Dropdown
name={inputParam.name} name={inputParam.name}
options={inputParam.options} options={inputParam.options}
onSelect={(newValue) => setValue(newValue, provider.name, inputParam.name)} onSelect={(newValue) => setValue(newValue, selectedProvider, inputParam.name)}
value={ value={
speechToText[provider.name] speechToText[selectedProvider]
? speechToText[provider.name][inputParam.name] ? speechToText[selectedProvider][inputParam.name]
: inputParam.default ?? 'choose an option' : inputParam.default ?? 'choose an option'
} }
/> />
)} )}
</Box> </Box>
))} ))}
</AccordionDetails> </>
</Accordion>
))}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<StyledButton variant='contained' onClick={onSave}> <StyledButton variant='contained' onClick={onSave}>
@@ -105,7 +105,11 @@ export const AsyncDropdown = ({
})() })()
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [credentialNames])
useEffect(() => {
setInternalValue(value)
}, [value])
return ( return (
<> <>
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
// material-ui // material-ui
import { IconButton } from '@mui/material' import { IconButton } from '@mui/material'
@@ -88,6 +88,10 @@ const CredentialInputHandler = ({ inputParam, data, onSelect, disabled = false }
setShowSpecificCredentialDialog(true) setShowSpecificCredentialDialog(true)
} }
useEffect(() => {
setCredentialId(data?.credential ?? '')
}, [data])
return ( return (
<div ref={ref}> <div ref={ref}>
{inputParam && ( {inputParam && (