import { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from '@/store/actions' import PropTypes from 'prop-types' import { Box, Typography, Button, OutlinedInput } from '@mui/material' // Project import import { StyledButton } from '@/ui-component/button/StyledButton' import { TooltipWithParser } from '@/ui-component/tooltip/TooltipWithParser' import { SwitchInput } from '@/ui-component/switch/Switch' // Icons import { IconX } from '@tabler/icons-react' // API import chatflowsApi from '@/api/chatflows' // utils import useNotifier from '@/utils/useNotifier' const RateLimit = () => { const dispatch = useDispatch() const chatflow = useSelector((state) => state.canvas.chatflow) const chatflowid = chatflow.id const apiConfig = chatflow.apiConfig ? JSON.parse(chatflow.apiConfig) : {} useNotifier() const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args)) const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args)) const [rateLimitStatus, setRateLimitStatus] = useState(false) const [limitMax, setLimitMax] = useState(apiConfig?.rateLimit?.limitMax ?? '') const [limitDuration, setLimitDuration] = useState(apiConfig?.rateLimit?.limitDuration ?? '') const [limitMsg, setLimitMsg] = useState(apiConfig?.rateLimit?.limitMsg ?? '') const formatObj = () => { const obj = { rateLimit: { status: rateLimitStatus } } if (rateLimitStatus) { const rateLimitValuesBoolean = [!limitMax, !limitDuration, !limitMsg] const rateLimitFilledValues = rateLimitValuesBoolean.filter((value) => value === false) if (rateLimitFilledValues.length >= 1 && rateLimitFilledValues.length <= 2) { throw new Error('Need to fill all rate limit input fields') } else if (rateLimitFilledValues.length === 3) { obj.rateLimit = { ...obj.rateLimit, limitMax, limitDuration, limitMsg } } } return obj } const handleChange = (value) => { setRateLimitStatus(value) } const checkDisabled = () => { if (rateLimitStatus) { if (limitMax === '' || limitDuration === '' || limitMsg === '') { return true } } return false } const onSave = async () => { try { const saveResp = await chatflowsApi.updateChatflow(chatflowid, { apiConfig: JSON.stringify(formatObj()) }) if (saveResp.data) { enqueueSnackbar({ message: 'Rate Limit Configuration Saved', options: { key: new Date().getTime() + Math.random(), variant: 'success', action: (key) => ( closeSnackbar(key)}> ) } }) dispatch({ type: SET_CHATFLOW, chatflow: saveResp.data }) } } catch (error) { enqueueSnackbar({ message: `Failed to save Rate Limit Configuration: ${ typeof error.response.data === 'object' ? error.response.data.message : error.response.data }`, options: { key: new Date().getTime() + Math.random(), variant: 'error', persist: true, action: (key) => ( closeSnackbar(key)}> ) } }) } } const onTextChanged = (value, fieldName) => { switch (fieldName) { case 'limitMax': setLimitMax(value) break case 'limitDuration': setLimitDuration(value) break case 'limitMsg': setLimitMsg(value) break } } const textField = (message, fieldName, fieldLabel, fieldType = 'string', placeholder = '') => { return ( {fieldLabel} { onTextChanged(e.target.value, fieldName) }} /> ) } return ( <> {/*Rate Limit*/} Rate Limit{' '} Rate Limit Setup Guide to set up Rate Limit correctly in your hosting environment.' } /> {rateLimitStatus && ( <> {textField(limitMax, 'limitMax', 'Message Limit per Duration', 'number', '5')} {textField(limitDuration, 'limitDuration', 'Duration in Second', 'number', '60')} {textField(limitMsg, 'limitMsg', 'Limit Message', 'string', 'You have reached the quota')} > )} onSave()} > Save Changes > ) } RateLimit.propTypes = { isSessionMemory: PropTypes.bool } export default RateLimit