mirror of https://github.com/langgenius/dify.git
Merge upstream/feat/vibe-wf: keep clickOutsideNotClose and z-index fix
This commit is contained in:
commit
88148f7a27
|
|
@ -10,9 +10,15 @@ type VersionSelectorProps = {
|
||||||
versionLen: number
|
versionLen: number
|
||||||
value: number
|
value: number
|
||||||
onChange: (index: number) => void
|
onChange: (index: number) => void
|
||||||
|
contentClassName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const VersionSelector: React.FC<VersionSelectorProps> = ({ versionLen, value, onChange }) => {
|
const VersionSelector: React.FC<VersionSelectorProps> = ({
|
||||||
|
versionLen,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
contentClassName,
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [isOpen, {
|
const [isOpen, {
|
||||||
setFalse: handleOpenFalse,
|
setFalse: handleOpenFalse,
|
||||||
|
|
@ -64,6 +70,7 @@ const VersionSelector: React.FC<VersionSelectorProps> = ({ versionLen, value, on
|
||||||
</PortalToFollowElemTrigger>
|
</PortalToFollowElemTrigger>
|
||||||
<PortalToFollowElemContent className={cn(
|
<PortalToFollowElemContent className={cn(
|
||||||
'z-[99]',
|
'z-[99]',
|
||||||
|
contentClassName,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import type { ToolDefaultValue } from '../block-selector/types'
|
import type { ToolDefaultValue } from '../block-selector/types'
|
||||||
|
import type { FlowGraph } from '../store/workflow/vibe-workflow-slice'
|
||||||
import type { Edge, Node, ToolWithProvider } from '../types'
|
import type { Edge, Node, ToolWithProvider } from '../types'
|
||||||
import type { Tool } from '@/app/components/tools/types'
|
import type { Tool } from '@/app/components/tools/types'
|
||||||
import type { Model } from '@/types/app'
|
import type { Model } from '@/types/app'
|
||||||
import { useSessionStorageState } from 'ahooks'
|
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useStoreApi } from 'reactflow'
|
import { useStoreApi } from 'reactflow'
|
||||||
|
|
@ -30,7 +30,7 @@ import {
|
||||||
VIBE_COMMAND_EVENT,
|
VIBE_COMMAND_EVENT,
|
||||||
} from '../constants'
|
} from '../constants'
|
||||||
import { useHooksStore } from '../hooks-store'
|
import { useHooksStore } from '../hooks-store'
|
||||||
import { useWorkflowStore } from '../store'
|
import { useStore, useWorkflowStore } from '../store'
|
||||||
import { BlockEnum } from '../types'
|
import { BlockEnum } from '../types'
|
||||||
import {
|
import {
|
||||||
generateNewNode,
|
generateNewNode,
|
||||||
|
|
@ -77,11 +77,6 @@ type ParseResult = {
|
||||||
edges: ParsedEdge[]
|
edges: ParsedEdge[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type FlowGraph = {
|
|
||||||
nodes: Node[]
|
|
||||||
edges: Edge[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const NODE_DECLARATION = /^([A-Z][\w-]*)\s*\[(?:"([^"]+)"|([^\]]+))\]\s*$/i
|
const NODE_DECLARATION = /^([A-Z][\w-]*)\s*\[(?:"([^"]+)"|([^\]]+))\]\s*$/i
|
||||||
const EDGE_DECLARATION = /^(.+?)\s*-->\s*(?:\|([^|]+)\|\s*)?(.+)$/
|
const EDGE_DECLARATION = /^(.+?)\s*-->\s*(?:\|([^|]+)\|\s*)?(.+)$/
|
||||||
|
|
||||||
|
|
@ -282,67 +277,92 @@ const buildToolParams = (parameters?: Tool['parameters']) => {
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
type UseVibeFlowDataParams = {
|
// Sync vibe flow data to sessionStorage
|
||||||
storageKey: string
|
const STORAGE_KEY_PREFIX = 'vibe-flow-'
|
||||||
|
|
||||||
|
const loadFromSessionStorage = (flowId: string): { versions: FlowGraph[], currentIndex: number } | null => {
|
||||||
|
if (typeof window === 'undefined')
|
||||||
|
return null
|
||||||
|
|
||||||
|
try {
|
||||||
|
const versionsKey = `${STORAGE_KEY_PREFIX}${flowId}-versions`
|
||||||
|
const indexKey = `${STORAGE_KEY_PREFIX}${flowId}-version-index`
|
||||||
|
|
||||||
|
const versionsRaw = sessionStorage.getItem(versionsKey)
|
||||||
|
const indexRaw = sessionStorage.getItem(indexKey)
|
||||||
|
|
||||||
|
if (!versionsRaw)
|
||||||
|
return null
|
||||||
|
|
||||||
|
const versions = JSON.parse(versionsRaw) as FlowGraph[]
|
||||||
|
const currentIndex = indexRaw ? Number.parseInt(indexRaw, 10) : 0
|
||||||
|
|
||||||
|
return { versions, currentIndex }
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyPrefix = 'vibe-flow-'
|
const saveToSessionStorage = (flowId: string, versions: FlowGraph[], currentIndex: number) => {
|
||||||
|
if (typeof window === 'undefined')
|
||||||
|
return
|
||||||
|
|
||||||
export const useVibeFlowData = ({ storageKey }: UseVibeFlowDataParams) => {
|
try {
|
||||||
const [versions, setVersions] = useSessionStorageState<FlowGraph[]>(`${keyPrefix}${storageKey}-versions`, {
|
const versionsKey = `${STORAGE_KEY_PREFIX}${flowId}-versions`
|
||||||
defaultValue: [],
|
const indexKey = `${STORAGE_KEY_PREFIX}${flowId}-version-index`
|
||||||
})
|
|
||||||
|
|
||||||
const [currentVersionIndex, setCurrentVersionIndex] = useSessionStorageState<number>(`${keyPrefix}${storageKey}-version-index`, {
|
sessionStorage.setItem(versionsKey, JSON.stringify(versions))
|
||||||
defaultValue: 0,
|
sessionStorage.setItem(indexKey, String(currentIndex))
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!versions || versions.length === 0) {
|
|
||||||
if (currentVersionIndex !== 0 && currentVersionIndex !== -1)
|
|
||||||
setCurrentVersionIndex(0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentVersionIndex === -1)
|
|
||||||
return
|
|
||||||
|
|
||||||
const normalizedIndex = Math.min(Math.max(currentVersionIndex ?? 0, 0), versions.length - 1)
|
|
||||||
if (normalizedIndex !== currentVersionIndex)
|
|
||||||
setCurrentVersionIndex(normalizedIndex)
|
|
||||||
}, [versions, currentVersionIndex, setCurrentVersionIndex])
|
|
||||||
|
|
||||||
const current = useMemo(() => {
|
|
||||||
if (!versions || versions.length === 0)
|
|
||||||
return undefined
|
|
||||||
const index = currentVersionIndex ?? 0
|
|
||||||
if (index < 0)
|
|
||||||
return undefined
|
|
||||||
return versions[index] || versions[versions.length - 1]
|
|
||||||
}, [versions, currentVersionIndex])
|
|
||||||
|
|
||||||
const addVersion = useCallback((version: FlowGraph) => {
|
|
||||||
// Prevent adding empty graphs
|
|
||||||
if (!version || !version.nodes || version.nodes.length === 0) {
|
|
||||||
setCurrentVersionIndex(-1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setVersions((prev) => {
|
|
||||||
const newVersions = [...(prev || []), version]
|
|
||||||
// Set index in setVersions callback to ensure using the latest length
|
|
||||||
setCurrentVersionIndex(newVersions.length - 1)
|
|
||||||
return newVersions
|
|
||||||
})
|
|
||||||
}, [setVersions, setCurrentVersionIndex])
|
|
||||||
|
|
||||||
return {
|
|
||||||
versions,
|
|
||||||
addVersion,
|
|
||||||
currentVersionIndex,
|
|
||||||
setCurrentVersionIndex,
|
|
||||||
current,
|
|
||||||
}
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Failed to save vibe flow to sessionStorage:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useVibeFlowSessionStorage = (flowId: string) => {
|
||||||
|
const workflowStore = useWorkflowStore()
|
||||||
|
const versions = useStore(s => s.vibeFlowVersions)
|
||||||
|
const currentIndex = useStore(s => s.vibeFlowCurrentIndex)
|
||||||
|
const loadedFlowIdRef = useRef<string | null>(null)
|
||||||
|
const isLoadingRef = useRef(false)
|
||||||
|
|
||||||
|
// Load from sessionStorage when flowId changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (!flowId || loadedFlowIdRef.current === flowId)
|
||||||
|
return
|
||||||
|
|
||||||
|
isLoadingRef.current = true
|
||||||
|
const stored = loadFromSessionStorage(flowId)
|
||||||
|
|
||||||
|
if (stored) {
|
||||||
|
workflowStore.setState({
|
||||||
|
vibeFlowVersions: stored.versions,
|
||||||
|
vibeFlowCurrentIndex: stored.currentIndex,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
workflowStore.setState({
|
||||||
|
vibeFlowVersions: [],
|
||||||
|
vibeFlowCurrentIndex: 0,
|
||||||
|
currentVibeFlow: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedFlowIdRef.current = flowId
|
||||||
|
// Delay to prevent immediate save
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoadingRef.current = false
|
||||||
|
}, 100)
|
||||||
|
}, [flowId, workflowStore])
|
||||||
|
|
||||||
|
// Save to sessionStorage when versions or index change
|
||||||
|
useEffect(() => {
|
||||||
|
if (!flowId || loadedFlowIdRef.current !== flowId || isLoadingRef.current)
|
||||||
|
return
|
||||||
|
|
||||||
|
saveToSessionStorage(flowId, versions, currentIndex)
|
||||||
|
}, [flowId, versions, currentIndex])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useWorkflowVibe = () => {
|
export const useWorkflowVibe = () => {
|
||||||
|
|
@ -367,9 +387,7 @@ export const useWorkflowVibe = () => {
|
||||||
const isGeneratingRef = useRef(false)
|
const isGeneratingRef = useRef(false)
|
||||||
const lastInstructionRef = useRef<string>('')
|
const lastInstructionRef = useRef<string>('')
|
||||||
|
|
||||||
const { addVersion, current: currentFlowGraph } = useVibeFlowData({
|
useVibeFlowSessionStorage(configsMap?.flowId || '')
|
||||||
storageKey: configsMap?.flowId || '',
|
|
||||||
})
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedModel = (() => {
|
const storedModel = (() => {
|
||||||
|
|
@ -702,6 +720,8 @@ export const useWorkflowVibe = () => {
|
||||||
}, [nodeTypeLookup, toolLookup])
|
}, [nodeTypeLookup, toolLookup])
|
||||||
|
|
||||||
const applyFlowchartToWorkflow = useCallback(() => {
|
const applyFlowchartToWorkflow = useCallback(() => {
|
||||||
|
const currentFlowGraph = workflowStore.getState().currentVibeFlow
|
||||||
|
|
||||||
if (!currentFlowGraph || !currentFlowGraph.nodes || currentFlowGraph.nodes.length === 0) {
|
if (!currentFlowGraph || !currentFlowGraph.nodes || currentFlowGraph.nodes.length === 0) {
|
||||||
Toast.notify({ type: 'error', message: t('workflow.vibe.invalidFlowchart') })
|
Toast.notify({ type: 'error', message: t('workflow.vibe.invalidFlowchart') })
|
||||||
return
|
return
|
||||||
|
|
@ -722,7 +742,6 @@ export const useWorkflowVibe = () => {
|
||||||
vibePanelMermaidCode: '',
|
vibePanelMermaidCode: '',
|
||||||
}))
|
}))
|
||||||
}, [
|
}, [
|
||||||
currentFlowGraph,
|
|
||||||
handleSyncWorkflowDraft,
|
handleSyncWorkflowDraft,
|
||||||
nodeTypeLookup,
|
nodeTypeLookup,
|
||||||
nodesMetaDataMap,
|
nodesMetaDataMap,
|
||||||
|
|
@ -730,6 +749,7 @@ export const useWorkflowVibe = () => {
|
||||||
store,
|
store,
|
||||||
t,
|
t,
|
||||||
toolLookup,
|
toolLookup,
|
||||||
|
workflowStore,
|
||||||
])
|
])
|
||||||
|
|
||||||
const handleVibeCommand = useCallback(async (dsl?: string, skipPanelPreview = false) => {
|
const handleVibeCommand = useCallback(async (dsl?: string, skipPanelPreview = false) => {
|
||||||
|
|
@ -830,7 +850,7 @@ export const useWorkflowVibe = () => {
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const workflowGraph = await flowchartToWorkflowGraph(mermaidCode)
|
const workflowGraph = await flowchartToWorkflowGraph(mermaidCode)
|
||||||
addVersion(workflowGraph)
|
workflowStore.getState().addVibeFlowVersion(workflowGraph)
|
||||||
|
|
||||||
if (skipPanelPreview)
|
if (skipPanelPreview)
|
||||||
applyFlowchartToWorkflow()
|
applyFlowchartToWorkflow()
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/com
|
||||||
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
|
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
|
||||||
import { ModelModeType } from '@/types/app'
|
import { ModelModeType } from '@/types/app'
|
||||||
import { VIBE_APPLY_EVENT, VIBE_COMMAND_EVENT } from '../../constants'
|
import { VIBE_APPLY_EVENT, VIBE_COMMAND_EVENT } from '../../constants'
|
||||||
import { useHooksStore } from '../../hooks-store'
|
|
||||||
import { useVibeFlowData } from '../../hooks/use-workflow-vibe'
|
|
||||||
import { useStore, useWorkflowStore } from '../../store'
|
import { useStore, useWorkflowStore } from '../../store'
|
||||||
import WorkflowPreview from '../../workflow-preview'
|
import WorkflowPreview from '../../workflow-preview'
|
||||||
|
|
||||||
|
|
@ -31,11 +29,9 @@ const VibePanel: FC = () => {
|
||||||
const showVibePanel = useStore(s => s.showVibePanel)
|
const showVibePanel = useStore(s => s.showVibePanel)
|
||||||
const isVibeGenerating = useStore(s => s.isVibeGenerating)
|
const isVibeGenerating = useStore(s => s.isVibeGenerating)
|
||||||
const vibePanelInstruction = useStore(s => s.vibePanelInstruction)
|
const vibePanelInstruction = useStore(s => s.vibePanelInstruction)
|
||||||
const configsMap = useHooksStore(s => s.configsMap)
|
const currentFlowGraph = useStore(s => s.currentVibeFlow)
|
||||||
|
const versions = useStore(s => s.vibeFlowVersions)
|
||||||
const { current: currentFlowGraph, versions, currentVersionIndex, setCurrentVersionIndex } = useVibeFlowData({
|
const currentVersionIndex = useStore(s => s.vibeFlowCurrentIndex)
|
||||||
storageKey: configsMap?.flowId || '',
|
|
||||||
})
|
|
||||||
|
|
||||||
const vibePanelPreviewNodes = currentFlowGraph?.nodes || []
|
const vibePanelPreviewNodes = currentFlowGraph?.nodes || []
|
||||||
const vibePanelPreviewEdges = currentFlowGraph?.edges || []
|
const vibePanelPreviewEdges = currentFlowGraph?.edges || []
|
||||||
|
|
@ -124,6 +120,11 @@ const VibePanel: FC = () => {
|
||||||
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') })
|
||||||
}, [workflowStore, t])
|
}, [workflowStore, t])
|
||||||
|
|
||||||
|
const handleVersionChange = useCallback((index: number) => {
|
||||||
|
const { setVibeFlowCurrentIndex } = workflowStore.getState()
|
||||||
|
setVibeFlowCurrentIndex(index)
|
||||||
|
}, [workflowStore])
|
||||||
|
|
||||||
if (!showVibePanel)
|
if (!showVibePanel)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
|
@ -139,6 +140,7 @@ const VibePanel: FC = () => {
|
||||||
isShow={showVibePanel}
|
isShow={showVibePanel}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
className="min-w-[1140px] !p-0"
|
className="min-w-[1140px] !p-0"
|
||||||
|
wrapperClassName="z-[900]"
|
||||||
clickOutsideNotClose
|
clickOutsideNotClose
|
||||||
>
|
>
|
||||||
<div className="flex h-[680px] flex-wrap">
|
<div className="flex h-[680px] flex-wrap">
|
||||||
|
|
@ -193,7 +195,8 @@ const VibePanel: FC = () => {
|
||||||
<VersionSelector
|
<VersionSelector
|
||||||
versionLen={versions.length}
|
versionLen={versions.length}
|
||||||
value={currentVersionIndex}
|
value={currentVersionIndex}
|
||||||
onChange={setCurrentVersionIndex}
|
onChange={handleVersionChange}
|
||||||
|
contentClassName="z-[1200]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
|
|
@ -216,6 +219,7 @@ const VibePanel: FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex grow flex-col overflow-hidden pb-6">
|
<div className="flex grow flex-col overflow-hidden pb-6">
|
||||||
<WorkflowPreview
|
<WorkflowPreview
|
||||||
|
key={currentVersionIndex}
|
||||||
nodes={vibePanelPreviewNodes}
|
nodes={vibePanelPreviewNodes}
|
||||||
edges={vibePanelPreviewEdges}
|
edges={vibePanelPreviewEdges}
|
||||||
viewport={{ x: 0, y: 0, zoom: 1 }}
|
viewport={{ x: 0, y: 0, zoom: 1 }}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
import type { StateCreator } from 'zustand'
|
import type { StateCreator } from 'zustand'
|
||||||
|
import type { Edge, Node } from '../../types'
|
||||||
|
|
||||||
|
export type FlowGraph = {
|
||||||
|
nodes: Node[]
|
||||||
|
edges: Edge[]
|
||||||
|
}
|
||||||
|
|
||||||
export type VibeWorkflowSliceShape = {
|
export type VibeWorkflowSliceShape = {
|
||||||
vibePanelMermaidCode: string
|
vibePanelMermaidCode: string
|
||||||
|
|
@ -7,13 +13,66 @@ export type VibeWorkflowSliceShape = {
|
||||||
setIsVibeGenerating: (isVibeGenerating: boolean) => void
|
setIsVibeGenerating: (isVibeGenerating: boolean) => void
|
||||||
vibePanelInstruction: string
|
vibePanelInstruction: string
|
||||||
setVibePanelInstruction: (vibePanelInstruction: string) => void
|
setVibePanelInstruction: (vibePanelInstruction: string) => void
|
||||||
|
vibeFlowVersions: FlowGraph[]
|
||||||
|
setVibeFlowVersions: (versions: FlowGraph[]) => void
|
||||||
|
vibeFlowCurrentIndex: number
|
||||||
|
setVibeFlowCurrentIndex: (index: number) => void
|
||||||
|
addVibeFlowVersion: (version: FlowGraph) => void
|
||||||
|
currentVibeFlow: FlowGraph | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createVibeWorkflowSlice: StateCreator<VibeWorkflowSliceShape> = set => ({
|
const getCurrentVibeFlow = (versions: FlowGraph[], currentIndex: number): FlowGraph | undefined => {
|
||||||
|
if (!versions || versions.length === 0)
|
||||||
|
return undefined
|
||||||
|
const index = currentIndex ?? 0
|
||||||
|
if (index < 0)
|
||||||
|
return undefined
|
||||||
|
return versions[index] || versions[versions.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createVibeWorkflowSlice: StateCreator<VibeWorkflowSliceShape> = (set, get) => ({
|
||||||
vibePanelMermaidCode: '',
|
vibePanelMermaidCode: '',
|
||||||
setVibePanelMermaidCode: vibePanelMermaidCode => set(() => ({ vibePanelMermaidCode })),
|
setVibePanelMermaidCode: vibePanelMermaidCode => set(() => ({ vibePanelMermaidCode })),
|
||||||
isVibeGenerating: false,
|
isVibeGenerating: false,
|
||||||
setIsVibeGenerating: isVibeGenerating => set(() => ({ isVibeGenerating })),
|
setIsVibeGenerating: isVibeGenerating => set(() => ({ isVibeGenerating })),
|
||||||
vibePanelInstruction: '',
|
vibePanelInstruction: '',
|
||||||
setVibePanelInstruction: vibePanelInstruction => set(() => ({ vibePanelInstruction })),
|
setVibePanelInstruction: vibePanelInstruction => set(() => ({ vibePanelInstruction })),
|
||||||
|
vibeFlowVersions: [],
|
||||||
|
setVibeFlowVersions: versions => set((state) => {
|
||||||
|
const currentVibeFlow = getCurrentVibeFlow(versions, state.vibeFlowCurrentIndex)
|
||||||
|
return { vibeFlowVersions: versions, currentVibeFlow }
|
||||||
|
}),
|
||||||
|
vibeFlowCurrentIndex: 0,
|
||||||
|
setVibeFlowCurrentIndex: (index) => {
|
||||||
|
const state = get()
|
||||||
|
const versions = state.vibeFlowVersions || []
|
||||||
|
|
||||||
|
if (!versions || versions.length === 0) {
|
||||||
|
set({ vibeFlowCurrentIndex: 0, currentVibeFlow: undefined })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedIndex = Math.min(Math.max(index, 0), versions.length - 1)
|
||||||
|
const currentVibeFlow = getCurrentVibeFlow(versions, normalizedIndex)
|
||||||
|
set({ vibeFlowCurrentIndex: normalizedIndex, currentVibeFlow })
|
||||||
|
},
|
||||||
|
addVibeFlowVersion: (version) => {
|
||||||
|
// Prevent adding empty graphs
|
||||||
|
if (!version || !version.nodes || version.nodes.length === 0) {
|
||||||
|
set({ vibeFlowCurrentIndex: -1, currentVibeFlow: undefined })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
const newVersions = [...(state.vibeFlowVersions || []), version]
|
||||||
|
const newIndex = newVersions.length - 1
|
||||||
|
const currentVibeFlow = getCurrentVibeFlow(newVersions, newIndex)
|
||||||
|
return {
|
||||||
|
vibeFlowVersions: newVersions,
|
||||||
|
vibeFlowCurrentIndex: newIndex,
|
||||||
|
currentVibeFlow,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
currentVibeFlow: undefined,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue