Feature: define a custom error message for allowed domains (#2194)
* Add a field for custom error message in allowed domains configuration * enhance UI for more consistency * update pnpm version * update pnpm version --------- Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
parent
b7e4fc9517
commit
f4c7887e50
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v3
|
- uses: pnpm/action-setup@v3
|
||||||
with:
|
with:
|
||||||
version: 9.0.3
|
version: 9.0.4
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
"turbo": "1.10.16",
|
"turbo": "1.10.16",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@9.0.3",
|
"packageManager": "pnpm@9.0.4",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"faiss-node",
|
"faiss-node",
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ 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 { Button, IconButton, OutlinedInput, Box, List, InputAdornment } from '@mui/material'
|
import { Button, IconButton, OutlinedInput, Box, List, InputAdornment, Typography } from '@mui/material'
|
||||||
import { IconX, IconTrash, IconPlus } from '@tabler/icons'
|
import { IconX, IconTrash, IconPlus } from '@tabler/icons'
|
||||||
|
|
||||||
// Project import
|
// Project import
|
||||||
import { StyledButton } from '@/ui-component/button/StyledButton'
|
import { StyledButton } from '@/ui-component/button/StyledButton'
|
||||||
|
import { TooltipWithParser } from '@/ui-component/tooltip/TooltipWithParser'
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import useNotifier from '@/utils/useNotifier'
|
import useNotifier from '@/utils/useNotifier'
|
||||||
|
|
@ -25,6 +26,7 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
|
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
|
||||||
|
|
||||||
const [inputFields, setInputFields] = useState([''])
|
const [inputFields, setInputFields] = useState([''])
|
||||||
|
const [errorMessage, setErrorMessage] = useState('')
|
||||||
|
|
||||||
const [chatbotConfig, setChatbotConfig] = useState({})
|
const [chatbotConfig, setChatbotConfig] = useState({})
|
||||||
|
|
||||||
|
|
@ -47,9 +49,12 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
const onSave = async () => {
|
const onSave = async () => {
|
||||||
try {
|
try {
|
||||||
let value = {
|
let value = {
|
||||||
allowedOrigins: [...inputFields]
|
allowedOrigins: [...inputFields],
|
||||||
|
allowedOriginsError: errorMessage
|
||||||
}
|
}
|
||||||
chatbotConfig.allowedOrigins = value.allowedOrigins
|
chatbotConfig.allowedOrigins = value.allowedOrigins
|
||||||
|
chatbotConfig.allowedOriginsError = value.allowedOriginsError
|
||||||
|
|
||||||
const saveResp = await chatflowsApi.updateChatflow(dialogProps.chatflow.id, {
|
const saveResp = await chatflowsApi.updateChatflow(dialogProps.chatflow.id, {
|
||||||
chatbotConfig: JSON.stringify(chatbotConfig)
|
chatbotConfig: JSON.stringify(chatbotConfig)
|
||||||
})
|
})
|
||||||
|
|
@ -98,8 +103,14 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
} else {
|
} else {
|
||||||
setInputFields([''])
|
setInputFields([''])
|
||||||
}
|
}
|
||||||
|
if (chatbotConfig.allowedOriginsError) {
|
||||||
|
setErrorMessage(chatbotConfig.allowedOriginsError)
|
||||||
|
} else {
|
||||||
|
setErrorMessage('')
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setInputFields([''])
|
setInputFields([''])
|
||||||
|
setErrorMessage('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,15 +119,21 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<Box>
|
||||||
style={{
|
<Box
|
||||||
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column'
|
flexDirection: 'column'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>Your chatbot will only work when used from the following domains.</span>
|
<Typography sx={{ mb: 1 }}>
|
||||||
</div>
|
Allowed Domains
|
||||||
<Box sx={{ '& > :not(style)': { m: 1 }, pt: 2 }}>
|
<TooltipWithParser
|
||||||
|
style={{ mb: 1, mt: 2, marginLeft: 10 }}
|
||||||
|
title={'Your chatbot will only work when used from the following domains.'}
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
<List>
|
<List>
|
||||||
{inputFields.map((origin, index) => {
|
{inputFields.map((origin, index) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -130,6 +147,7 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
size='small'
|
size='small'
|
||||||
value={origin}
|
value={origin}
|
||||||
name='origin'
|
name='origin'
|
||||||
|
placeholder='https://example.com'
|
||||||
endAdornment={
|
endAdornment={
|
||||||
<InputAdornment position='end' sx={{ padding: '2px' }}>
|
<InputAdornment position='end' sx={{ padding: '2px' }}>
|
||||||
{inputFields.length > 1 && (
|
{inputFields.length > 1 && (
|
||||||
|
|
@ -160,6 +178,28 @@ const AllowedDomains = ({ dialogProps }) => {
|
||||||
})}
|
})}
|
||||||
</List>
|
</List>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box sx={{ pt: 2, pb: 2 }}>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
||||||
|
<Typography sx={{ mb: 1 }}>
|
||||||
|
Error Message
|
||||||
|
<TooltipWithParser
|
||||||
|
style={{ mb: 1, mt: 2, marginLeft: 10 }}
|
||||||
|
title={'Custom error message that will be shown when for unauthorized domain'}
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
<OutlinedInput
|
||||||
|
sx={{ width: '100%' }}
|
||||||
|
type='text'
|
||||||
|
size='small'
|
||||||
|
fullWidth
|
||||||
|
placeholder='Unauthorized domain!'
|
||||||
|
value={errorMessage}
|
||||||
|
onChange={(e) => {
|
||||||
|
setErrorMessage(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
<StyledButton variant='contained' onClick={onSave}>
|
<StyledButton variant='contained' onClick={onSave}>
|
||||||
Save
|
Save
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { Box, Typography, Button, OutlinedInput } from '@mui/material'
|
||||||
|
|
||||||
// Project import
|
// Project import
|
||||||
import { StyledButton } from '@/ui-component/button/StyledButton'
|
import { StyledButton } from '@/ui-component/button/StyledButton'
|
||||||
|
import { TooltipWithParser } from '@/ui-component/tooltip/TooltipWithParser'
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
import { IconX } from '@tabler/icons'
|
import { IconX } from '@tabler/icons'
|
||||||
|
|
@ -16,7 +17,6 @@ import chatflowsApi from '@/api/chatflows'
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
import useNotifier from '@/utils/useNotifier'
|
import useNotifier from '@/utils/useNotifier'
|
||||||
import { TooltipWithParser } from '@/ui-component/tooltip/TooltipWithParser'
|
|
||||||
|
|
||||||
const RateLimit = () => {
|
const RateLimit = () => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
@ -117,6 +117,7 @@ const RateLimit = () => {
|
||||||
value={message}
|
value={message}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
|
size='small'
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onTextChanged(e.target.value, fieldName)
|
onTextChanged(e.target.value, fieldName)
|
||||||
}}
|
}}
|
||||||
|
|
@ -138,9 +139,9 @@ const RateLimit = () => {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
{textField(limitMax, 'limitMax', 'Message Limit per Duration', 'number')}
|
{textField(limitMax, 'limitMax', 'Message Limit per Duration', 'number', '5')}
|
||||||
{textField(limitDuration, 'limitDuration', 'Duration in Second', 'number')}
|
{textField(limitDuration, 'limitDuration', 'Duration in Second', 'number', '60')}
|
||||||
{textField(limitMsg, 'limitMsg', 'Limit Message', 'string')}
|
{textField(limitMsg, 'limitMsg', 'Limit Message', 'string', 'You have reached the quota')}
|
||||||
|
|
||||||
<StyledButton style={{ marginBottom: 10, marginTop: 10 }} variant='contained' onClick={() => onSave()}>
|
<StyledButton style={{ marginBottom: 10, marginTop: 10 }} variant='contained' onClick={() => onSave()}>
|
||||||
Save Changes
|
Save Changes
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ const SpeechToText = ({ dialogProps }) => {
|
||||||
Providers
|
Providers
|
||||||
</Typography>
|
</Typography>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<Select value={selectedProvider} onChange={handleProviderChange}>
|
<Select size='small' value={selectedProvider} onChange={handleProviderChange}>
|
||||||
<MenuItem value='none'>None</MenuItem>
|
<MenuItem value='none'>None</MenuItem>
|
||||||
<MenuItem value='openAIWhisper'>OpenAI Whisper</MenuItem>
|
<MenuItem value='openAIWhisper'>OpenAI Whisper</MenuItem>
|
||||||
<MenuItem value='assemblyAiTranscribe'>Assembly AI</MenuItem>
|
<MenuItem value='assemblyAiTranscribe'>Assembly AI</MenuItem>
|
||||||
|
|
@ -198,7 +198,7 @@ const SpeechToText = ({ dialogProps }) => {
|
||||||
</Box>
|
</Box>
|
||||||
{selectedProvider !== 'none' && (
|
{selectedProvider !== 'none' && (
|
||||||
<>
|
<>
|
||||||
<ListItem style={{ padding: 0, margin: 0 }} alignItems='center'>
|
<ListItem sx={{ mt: 3 }} alignItems='center'>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ const ShareChatbot = ({ isSessionMemory }) => {
|
||||||
const [titleAvatarSrc, setTitleAvatarSrc] = useState(chatbotConfig?.titleAvatarSrc ?? '')
|
const [titleAvatarSrc, setTitleAvatarSrc] = useState(chatbotConfig?.titleAvatarSrc ?? '')
|
||||||
|
|
||||||
const [welcomeMessage, setWelcomeMessage] = useState(chatbotConfig?.welcomeMessage ?? '')
|
const [welcomeMessage, setWelcomeMessage] = useState(chatbotConfig?.welcomeMessage ?? '')
|
||||||
|
const [errorMessage, setErrorMessage] = useState(chatbotConfig?.errorMessage ?? '')
|
||||||
const [backgroundColor, setBackgroundColor] = useState(chatbotConfig?.backgroundColor ?? defaultConfig.backgroundColor)
|
const [backgroundColor, setBackgroundColor] = useState(chatbotConfig?.backgroundColor ?? defaultConfig.backgroundColor)
|
||||||
const [fontSize, setFontSize] = useState(chatbotConfig?.fontSize ?? defaultConfig.fontSize)
|
const [fontSize, setFontSize] = useState(chatbotConfig?.fontSize ?? defaultConfig.fontSize)
|
||||||
const [poweredByTextColor, setPoweredByTextColor] = useState(chatbotConfig?.poweredByTextColor ?? defaultConfig.poweredByTextColor)
|
const [poweredByTextColor, setPoweredByTextColor] = useState(chatbotConfig?.poweredByTextColor ?? defaultConfig.poweredByTextColor)
|
||||||
|
|
@ -114,6 +115,7 @@ const ShareChatbot = ({ isSessionMemory }) => {
|
||||||
if (title) obj.title = title
|
if (title) obj.title = title
|
||||||
if (titleAvatarSrc) obj.titleAvatarSrc = titleAvatarSrc
|
if (titleAvatarSrc) obj.titleAvatarSrc = titleAvatarSrc
|
||||||
if (welcomeMessage) obj.welcomeMessage = welcomeMessage
|
if (welcomeMessage) obj.welcomeMessage = welcomeMessage
|
||||||
|
if (errorMessage) obj.errorMessage = errorMessage
|
||||||
if (backgroundColor) obj.backgroundColor = backgroundColor
|
if (backgroundColor) obj.backgroundColor = backgroundColor
|
||||||
if (fontSize) obj.fontSize = fontSize
|
if (fontSize) obj.fontSize = fontSize
|
||||||
if (poweredByTextColor) obj.poweredByTextColor = poweredByTextColor
|
if (poweredByTextColor) obj.poweredByTextColor = poweredByTextColor
|
||||||
|
|
@ -268,6 +270,9 @@ const ShareChatbot = ({ isSessionMemory }) => {
|
||||||
case 'welcomeMessage':
|
case 'welcomeMessage':
|
||||||
setWelcomeMessage(value)
|
setWelcomeMessage(value)
|
||||||
break
|
break
|
||||||
|
case 'errorMessage':
|
||||||
|
setErrorMessage(value)
|
||||||
|
break
|
||||||
case 'fontSize':
|
case 'fontSize':
|
||||||
setFontSize(value)
|
setFontSize(value)
|
||||||
break
|
break
|
||||||
|
|
@ -417,6 +422,7 @@ const ShareChatbot = ({ isSessionMemory }) => {
|
||||||
`https://raw.githubusercontent.com/FlowiseAI/Flowise/main/assets/FloWiseAI_dark.png`
|
`https://raw.githubusercontent.com/FlowiseAI/Flowise/main/assets/FloWiseAI_dark.png`
|
||||||
)}
|
)}
|
||||||
{textField(welcomeMessage, 'welcomeMessage', 'Welcome Message', 'string', 'Hello! This is custom welcome message')}
|
{textField(welcomeMessage, 'welcomeMessage', 'Welcome Message', 'string', 'Hello! This is custom welcome message')}
|
||||||
|
{textField(errorMessage, 'errorMessage', 'Error Message', 'string', 'This is custom error message')}
|
||||||
{colorField(backgroundColor, 'backgroundColor', 'Background Color')}
|
{colorField(backgroundColor, 'backgroundColor', 'Background Color')}
|
||||||
{textField(fontSize, 'fontSize', 'Font Size', 'number')}
|
{textField(fontSize, 'fontSize', 'Font Size', 'number')}
|
||||||
{colorField(poweredByTextColor, 'poweredByTextColor', 'PoweredBy TextColor')}
|
{colorField(poweredByTextColor, 'poweredByTextColor', 'PoweredBy TextColor')}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue