add fix where tags are not added when submit is clicked without enter

This commit is contained in:
Henry 2023-11-17 12:35:01 +00:00
parent 213fade6fa
commit 5d7febc5c6
3 changed files with 75 additions and 47 deletions

View File

@ -1,4 +1,7 @@
import * as React from 'react' import { useState } from 'react'
import { useDispatch } from 'react-redux'
import PropTypes from 'prop-types'
import { styled, alpha } from '@mui/material/styles' import { styled, alpha } from '@mui/material/styles'
import Menu from '@mui/material/Menu' import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem' import MenuItem from '@mui/material/MenuItem'
@ -10,21 +13,22 @@ import FileDeleteIcon from '@mui/icons-material/Delete'
import FileCategoryIcon from '@mui/icons-material/Category' import FileCategoryIcon from '@mui/icons-material/Category'
import Button from '@mui/material/Button' import Button from '@mui/material/Button'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import PropTypes from 'prop-types'
import { uiBaseURL } from '../../store/constant'
import { generateExportFlowData } from '../../utils/genericHelper'
import chatflowsApi from 'api/chatflows'
import useConfirm from 'hooks/useConfirm'
import useNotifier from '../../utils/useNotifier'
import { closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackbarAction } from '../../store/actions'
import { IconX } from '@tabler/icons' import { IconX } from '@tabler/icons'
import { useDispatch } from 'react-redux'
import chatflowsApi from 'api/chatflows'
import useApi from '../../hooks/useApi'
import useConfirm from 'hooks/useConfirm'
import { uiBaseURL } from '../../store/constant'
import { closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackbarAction } from '../../store/actions'
import ConfirmDialog from '../dialog/ConfirmDialog' import ConfirmDialog from '../dialog/ConfirmDialog'
import SaveChatflowDialog from '../dialog/SaveChatflowDialog' import SaveChatflowDialog from '../dialog/SaveChatflowDialog'
import { useState } from 'react'
import useApi from '../../hooks/useApi'
import TagDialog from '../dialog/TagDialog' import TagDialog from '../dialog/TagDialog'
import { generateExportFlowData } from '../../utils/genericHelper'
import useNotifier from '../../utils/useNotifier'
const StyledMenu = styled((props) => ( const StyledMenu = styled((props) => (
<Menu <Menu
elevation={0} elevation={0}
@ -64,28 +68,31 @@ const StyledMenu = styled((props) => (
export default function FlowListMenu({ chatflow, updateFlowsApi }) { export default function FlowListMenu({ chatflow, updateFlowsApi }) {
const { confirm } = useConfirm() const { confirm } = useConfirm()
const dispatch = useDispatch() const dispatch = useDispatch()
const [flowDialogOpen, setFlowDialogOpen] = useState(false)
const [categoryValues, setCategoryValues] = useState([])
const [categoryDialogOpen, setCategoryDialogOpen] = useState(false)
const updateChatflowApi = useApi(chatflowsApi.updateChatflow) const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
// ==============================|| Snackbar ||============================== //
useNotifier() useNotifier()
const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args)) const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args)) const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
const [anchorEl, setAnchorEl] = React.useState(null)
const [flowDialogOpen, setFlowDialogOpen] = useState(false)
const [categoryDialogOpen, setCategoryDialogOpen] = useState(false)
const [categoryDialogProps, setCategoryDialogProps] = useState({})
const [anchorEl, setAnchorEl] = useState(null)
const open = Boolean(anchorEl) const open = Boolean(anchorEl)
const handleClick = (event) => { const handleClick = (event) => {
setAnchorEl(event.currentTarget) setAnchorEl(event.currentTarget)
} }
const handleClose = () => { const handleClose = () => {
setAnchorEl(null) setAnchorEl(null)
} }
const handleFlowRename = () => { const handleFlowRename = () => {
setAnchorEl(null) setAnchorEl(null)
setFlowDialogOpen(true) setFlowDialogOpen(true)
} }
const saveFlowRename = async (chatflowName) => { const saveFlowRename = async (chatflowName) => {
const updateBody = { const updateBody = {
name: chatflowName, name: chatflowName,
@ -111,13 +118,19 @@ export default function FlowListMenu({ chatflow, updateFlowsApi }) {
}) })
} }
} }
const handleFlowCategory = () => { const handleFlowCategory = () => {
setAnchorEl(null) setAnchorEl(null)
if (chatflow.category) setCategoryValues(chatflow.category.split(';')) if (chatflow.category) {
else setCategoryValues([]) setCategoryDialogProps({
category: chatflow.category.split(';')
})
}
setCategoryDialogOpen(true) setCategoryDialogOpen(true)
} }
const saveFlowCategory = async (categories) => { const saveFlowCategory = async (categories) => {
setCategoryDialogOpen(false)
// save categories as string // save categories as string
const categoryTags = categories.join(';') const categoryTags = categories.join(';')
const updateBody = { const updateBody = {
@ -144,6 +157,7 @@ export default function FlowListMenu({ chatflow, updateFlowsApi }) {
}) })
} }
} }
const handleDelete = async () => { const handleDelete = async () => {
setAnchorEl(null) setAnchorEl(null)
const confirmPayload = { const confirmPayload = {
@ -176,6 +190,7 @@ export default function FlowListMenu({ chatflow, updateFlowsApi }) {
} }
} }
} }
const handleDuplicate = () => { const handleDuplicate = () => {
setAnchorEl(null) setAnchorEl(null)
try { try {
@ -185,6 +200,7 @@ export default function FlowListMenu({ chatflow, updateFlowsApi }) {
console.error(e) console.error(e)
} }
} }
const handleExport = () => { const handleExport = () => {
setAnchorEl(null) setAnchorEl(null)
try { try {
@ -261,9 +277,8 @@ export default function FlowListMenu({ chatflow, updateFlowsApi }) {
/> />
<TagDialog <TagDialog
isOpen={categoryDialogOpen} isOpen={categoryDialogOpen}
dialogProps={categoryDialogProps}
onClose={() => setCategoryDialogOpen(false)} onClose={() => setCategoryDialogOpen(false)}
tags={categoryValues}
setTags={setCategoryValues}
onSubmit={saveFlowCategory} onSubmit={saveFlowCategory}
/> />
</div> </div>

View File

@ -1,4 +1,4 @@
import { useState } from 'react' import { useState, useEffect } from 'react'
import Dialog from '@mui/material/Dialog' import Dialog from '@mui/material/Dialog'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Button from '@mui/material/Button' import Button from '@mui/material/Button'
@ -7,8 +7,9 @@ import Chip from '@mui/material/Chip'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { DialogActions, DialogContent, DialogTitle, Typography } from '@mui/material' import { DialogActions, DialogContent, DialogTitle, Typography } from '@mui/material'
const TagDialog = ({ isOpen, onClose, tags, setTags, onSubmit }) => { const TagDialog = ({ isOpen, dialogProps, onClose, onSubmit }) => {
const [inputValue, setInputValue] = useState('') const [inputValue, setInputValue] = useState('')
const [categoryValues, setCategoryValues] = useState([])
const handleInputChange = (event) => { const handleInputChange = (event) => {
setInputValue(event.target.value) setInputValue(event.target.value)
@ -17,34 +18,44 @@ const TagDialog = ({ isOpen, onClose, tags, setTags, onSubmit }) => {
const handleInputKeyDown = (event) => { const handleInputKeyDown = (event) => {
if (event.key === 'Enter' && inputValue.trim()) { if (event.key === 'Enter' && inputValue.trim()) {
event.preventDefault() event.preventDefault()
if (!tags.includes(inputValue)) { if (!categoryValues.includes(inputValue)) {
setTags([...tags, inputValue]) setCategoryValues([...categoryValues, inputValue])
setInputValue('') setInputValue('')
} }
} }
} }
const handleDeleteTag = (tagToDelete) => { const handleDeleteTag = (categoryToDelete) => {
setTags(tags.filter((tag) => tag !== tagToDelete)) setCategoryValues(categoryValues.filter((category) => category !== categoryToDelete))
} }
const handleSubmit = (event) => { const handleSubmit = (event) => {
event.preventDefault() event.preventDefault()
if (inputValue.trim() && !tags.includes(inputValue)) { let newCategories = [...categoryValues]
setTags([...tags, inputValue]) if (inputValue.trim() && !categoryValues.includes(inputValue)) {
newCategories = [...newCategories, inputValue]
setCategoryValues(newCategories)
} }
onSubmit(tags) onSubmit(newCategories)
onClose()
} }
useEffect(() => {
if (dialogProps.category) setCategoryValues(dialogProps.category)
return () => {
setInputValue('')
setCategoryValues([])
}
}, [dialogProps])
return ( return (
<Dialog <Dialog
fullWidth fullWidth
maxWidth='xs' maxWidth='xs'
open={isOpen} open={isOpen}
onClose={onClose} onClose={onClose}
aria-labelledby='tag-dialog-title' aria-labelledby='category-dialog-title'
aria-describedby='tag-dialog-description' aria-describedby='category-dialog-description'
> >
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'> <DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
Set Chatflow Category Tags Set Chatflow Category Tags
@ -52,17 +63,20 @@ const TagDialog = ({ isOpen, onClose, tags, setTags, onSubmit }) => {
<DialogContent> <DialogContent>
<Box> <Box>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div style={{ marginBottom: 20 }}> {categoryValues.length > 0 && (
{tags.map((tag, index) => ( <div style={{ marginBottom: 10 }}>
{categoryValues.map((category, index) => (
<Chip <Chip
key={index} key={index}
label={tag} label={category}
onDelete={() => handleDeleteTag(tag)} onDelete={() => handleDeleteTag(category)}
style={{ marginRight: 5, marginBottom: 5 }} style={{ marginRight: 5, marginBottom: 5 }}
/> />
))} ))}
</div> </div>
)}
<TextField <TextField
sx={{ mt: 2 }}
fullWidth fullWidth
value={inputValue} value={inputValue}
onChange={handleInputChange} onChange={handleInputChange}
@ -70,7 +84,7 @@ const TagDialog = ({ isOpen, onClose, tags, setTags, onSubmit }) => {
label='Add a tag' label='Add a tag'
variant='outlined' variant='outlined'
/> />
<Typography variant='body2' sx={{ fontStyle: 'italic' }} color='text.secondary'> <Typography variant='body2' sx={{ fontStyle: 'italic', mt: 1 }} color='text.secondary'>
Enter a tag and press enter to add it to the list. You can add as many tags as you want. Enter a tag and press enter to add it to the list. You can add as many tags as you want.
</Typography> </Typography>
</form> </form>
@ -88,9 +102,8 @@ const TagDialog = ({ isOpen, onClose, tags, setTags, onSubmit }) => {
TagDialog.propTypes = { TagDialog.propTypes = {
isOpen: PropTypes.bool, isOpen: PropTypes.bool,
dialogProps: PropTypes.object,
onClose: PropTypes.func, onClose: PropTypes.func,
tags: PropTypes.array,
setTags: PropTypes.func,
onSubmit: PropTypes.func onSubmit: PropTypes.func
} }

View File

@ -9,9 +9,9 @@ import TableContainer from '@mui/material/TableContainer'
import TableHead from '@mui/material/TableHead' import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow' import TableRow from '@mui/material/TableRow'
import Paper from '@mui/material/Paper' import Paper from '@mui/material/Paper'
import Chip from '@mui/material/Chip'
import { Button, Stack, Typography } from '@mui/material' import { Button, Stack, Typography } from '@mui/material'
import FlowListMenu from '../button/FlowListMenu' import FlowListMenu from '../button/FlowListMenu'
import Chip from '@mui/material/Chip'
const StyledTableCell = styled(TableCell)(({ theme }) => ({ const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: { [`&.${tableCellClasses.head}`]: {