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, IconCode } from '@tabler/icons' // project imports import Settings from 'views/settings' import SaveChatflowDialog from 'ui-component/dialog/SaveChatflowDialog' import APICodeDialog from 'ui-component/dialog/APICodeDialog' // API import chatflowsApi from 'api/chatflows' // Hooks import useApi from 'hooks/useApi' // utils import { generateExportFlowData } from 'utils/genericHelper' import { uiBaseURL } from 'store/constant' // ==============================|| 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 [apiDialogOpen, setAPIDialogOpen] = useState(false) const [apiDialogProps, setAPIDialogProps] = useState({}) const updateChatflowApi = useApi(chatflowsApi.updateChatflow) const canvas = useSelector((state) => state.canvas) const onSettingsItemClick = (setting) => { setSettingsOpen(false) if (setting === 'deleteChatflow') { handleDeleteFlow() } else if (setting === 'duplicateChatflow') { try { localStorage.setItem('duplicatedFlowData', chatflow.flowData) window.open(`${uiBaseURL}/canvas`, '_blank') } catch (e) { console.error(e) } } 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 onAPIDialogClick = () => { let isFormDataRequired = false try { const flowData = JSON.parse(chatflow.flowData) const nodes = flowData.nodes for (const node of nodes) { if (node.data.inputParams.find((param) => param.type === 'file')) { isFormDataRequired = true break } } } catch (e) { console.error(e) } setAPIDialogProps({ title: 'Embed in website or use as API', chatflowid: chatflow.id, chatflowApiKeyId: chatflow.apikeyid, isFormDataRequired }) setAPIDialogOpen(true) } const onSaveChatflowClick = () => { if (chatflow.id) handleSaveFlow(flowName) 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 ( <> window.history.state && window.history.state.idx > 0 ? navigate(-1) : navigate('/', { replace: true }) } > {!isEditingFlowName && ( {canvas.isDirty && *} {flowName} {chatflow?.id && ( setEditingFlowName(true)} > )} )} {isEditingFlowName && ( setEditingFlowName(false)} > )} {chatflow?.id && ( )} setSettingsOpen(!isSettingsOpen)} > setSettingsOpen(false)} onSettingsItemClick={onSettingsItemClick} onUploadFile={onUploadFile} /> setFlowDialogOpen(false)} onConfirm={onConfirmSaveName} /> setAPIDialogOpen(false)} /> ) } CanvasHeader.propTypes = { chatflow: PropTypes.object, handleSaveFlow: PropTypes.func, handleDeleteFlow: PropTypes.func, handleLoadFlow: PropTypes.func } export default CanvasHeader