mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 21:00:58 +03:00
Initial push
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
// material-ui
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
import { Avatar, Box, ButtonBase, Typography, Stack, TextField } from '@mui/material'
|
||||
|
||||
// icons
|
||||
import { IconSettings, IconChevronLeft, IconDeviceFloppy, IconPencil, IconCheck, IconX } from '@tabler/icons'
|
||||
|
||||
// project imports
|
||||
import Settings from 'views/settings'
|
||||
import SaveChatflowDialog from 'ui-component/dialog/SaveChatflowDialog'
|
||||
|
||||
// API
|
||||
import chatflowsApi from 'api/chatflows'
|
||||
|
||||
// Hooks
|
||||
import useApi from 'hooks/useApi'
|
||||
|
||||
// utils
|
||||
import { generateExportFlowData } from 'utils/genericHelper'
|
||||
|
||||
// ==============================|| CANVAS HEADER ||============================== //
|
||||
|
||||
const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFlow }) => {
|
||||
const theme = useTheme()
|
||||
const navigate = useNavigate()
|
||||
const flowNameRef = useRef()
|
||||
const settingsRef = useRef()
|
||||
|
||||
const [isEditingFlowName, setEditingFlowName] = useState(null)
|
||||
const [flowName, setFlowName] = useState('')
|
||||
const [isSettingsOpen, setSettingsOpen] = useState(false)
|
||||
const [flowDialogOpen, setFlowDialogOpen] = useState(false)
|
||||
|
||||
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
|
||||
const canvas = useSelector((state) => state.canvas)
|
||||
|
||||
const onSettingsItemClick = (setting) => {
|
||||
setSettingsOpen(false)
|
||||
|
||||
if (setting === 'deleteChatflow') {
|
||||
handleDeleteFlow()
|
||||
} else if (setting === 'exportChatflow') {
|
||||
try {
|
||||
const flowData = JSON.parse(chatflow.flowData)
|
||||
let dataStr = JSON.stringify(generateExportFlowData(flowData))
|
||||
let dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr)
|
||||
|
||||
let exportFileDefaultName = `${chatflow.name} Chatflow.json`
|
||||
|
||||
let linkElement = document.createElement('a')
|
||||
linkElement.setAttribute('href', dataUri)
|
||||
linkElement.setAttribute('download', exportFileDefaultName)
|
||||
linkElement.click()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onUploadFile = (file) => {
|
||||
setSettingsOpen(false)
|
||||
handleLoadFlow(file)
|
||||
}
|
||||
|
||||
const submitFlowName = () => {
|
||||
if (chatflow.id) {
|
||||
const updateBody = {
|
||||
name: flowNameRef.current.value
|
||||
}
|
||||
updateChatflowApi.request(chatflow.id, updateBody)
|
||||
}
|
||||
}
|
||||
|
||||
const onSaveChatflowClick = () => {
|
||||
if (chatflow.id) handleSaveFlow(chatflow.name)
|
||||
else setFlowDialogOpen(true)
|
||||
}
|
||||
|
||||
const onConfirmSaveName = (flowName) => {
|
||||
setFlowDialogOpen(false)
|
||||
handleSaveFlow(flowName)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (updateChatflowApi.data) {
|
||||
setFlowName(updateChatflowApi.data.name)
|
||||
}
|
||||
setEditingFlowName(false)
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [updateChatflowApi.data])
|
||||
|
||||
useEffect(() => {
|
||||
if (chatflow) {
|
||||
setFlowName(chatflow.name)
|
||||
}
|
||||
}, [chatflow])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<ButtonBase title='Back' sx={{ borderRadius: '50%' }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.secondary.light,
|
||||
color: theme.palette.secondary.dark,
|
||||
'&:hover': {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.light
|
||||
}
|
||||
}}
|
||||
color='inherit'
|
||||
onClick={() => navigate(-1)}
|
||||
>
|
||||
<IconChevronLeft stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
{!isEditingFlowName && (
|
||||
<Stack flexDirection='row'>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: '1.5rem',
|
||||
fontWeight: 600,
|
||||
ml: 2
|
||||
}}
|
||||
>
|
||||
{canvas.isDirty && <strong style={{ color: theme.palette.orange.main }}>*</strong>} {flowName}
|
||||
</Typography>
|
||||
{chatflow?.id && (
|
||||
<ButtonBase title='Edit Name' sx={{ borderRadius: '50%' }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
ml: 1,
|
||||
background: theme.palette.secondary.light,
|
||||
color: theme.palette.secondary.dark,
|
||||
'&:hover': {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.light
|
||||
}
|
||||
}}
|
||||
color='inherit'
|
||||
onClick={() => setEditingFlowName(true)}
|
||||
>
|
||||
<IconPencil stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{isEditingFlowName && (
|
||||
<Stack flexDirection='row'>
|
||||
<TextField
|
||||
size='small'
|
||||
inputRef={flowNameRef}
|
||||
sx={{
|
||||
width: '50%',
|
||||
ml: 2
|
||||
}}
|
||||
defaultValue={flowName}
|
||||
/>
|
||||
<ButtonBase title='Save Name' sx={{ borderRadius: '50%' }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.success.light,
|
||||
color: theme.palette.success.dark,
|
||||
ml: 1,
|
||||
'&:hover': {
|
||||
background: theme.palette.success.dark,
|
||||
color: theme.palette.success.light
|
||||
}
|
||||
}}
|
||||
color='inherit'
|
||||
onClick={submitFlowName}
|
||||
>
|
||||
<IconCheck stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
<ButtonBase title='Cancel' sx={{ borderRadius: '50%' }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.error.light,
|
||||
color: theme.palette.error.dark,
|
||||
ml: 1,
|
||||
'&:hover': {
|
||||
background: theme.palette.error.dark,
|
||||
color: theme.palette.error.light
|
||||
}
|
||||
}}
|
||||
color='inherit'
|
||||
onClick={() => setEditingFlowName(false)}
|
||||
>
|
||||
<IconX stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Box>
|
||||
<ButtonBase title='Save Chatflow' sx={{ borderRadius: '50%', mr: 2 }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.canvasHeader.saveLight,
|
||||
color: theme.palette.canvasHeader.saveDark,
|
||||
'&:hover': {
|
||||
background: theme.palette.canvasHeader.saveDark,
|
||||
color: theme.palette.canvasHeader.saveLight
|
||||
}
|
||||
}}
|
||||
color='inherit'
|
||||
onClick={onSaveChatflowClick}
|
||||
>
|
||||
<IconDeviceFloppy stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
<ButtonBase ref={settingsRef} title='Settings' sx={{ borderRadius: '50%' }}>
|
||||
<Avatar
|
||||
variant='rounded'
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.canvasHeader.settingsLight,
|
||||
color: theme.palette.canvasHeader.settingsDark,
|
||||
'&:hover': {
|
||||
background: theme.palette.canvasHeader.settingsDark,
|
||||
color: theme.palette.canvasHeader.settingsLight
|
||||
}
|
||||
}}
|
||||
onClick={() => setSettingsOpen(!isSettingsOpen)}
|
||||
>
|
||||
<IconSettings stroke={1.5} size='1.3rem' />
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
<Settings
|
||||
chatflow={chatflow}
|
||||
isSettingsOpen={isSettingsOpen}
|
||||
anchorEl={settingsRef.current}
|
||||
onClose={() => setSettingsOpen(false)}
|
||||
onSettingsItemClick={onSettingsItemClick}
|
||||
onUploadFile={onUploadFile}
|
||||
/>
|
||||
<SaveChatflowDialog
|
||||
show={flowDialogOpen}
|
||||
dialogProps={{
|
||||
title: `Save New Chatflow`,
|
||||
confirmButtonName: 'Save',
|
||||
cancelButtonName: 'Cancel'
|
||||
}}
|
||||
onCancel={() => setFlowDialogOpen(false)}
|
||||
onConfirm={onConfirmSaveName}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
CanvasHeader.propTypes = {
|
||||
chatflow: PropTypes.object,
|
||||
handleSaveFlow: PropTypes.func,
|
||||
handleDeleteFlow: PropTypes.func,
|
||||
handleLoadFlow: PropTypes.func
|
||||
}
|
||||
|
||||
export default CanvasHeader
|
||||
Reference in New Issue
Block a user