| @@ -1,323 +0,0 @@ | |||
| import { useContext } from 'react' | |||
| import { | |||
| useStore as useZustandStore, | |||
| } from 'zustand' | |||
| import { createStore } from 'zustand/vanilla' | |||
| import { debounce } from 'lodash-es' | |||
| import type { Viewport } from 'reactflow' | |||
| import type { | |||
| HelpLineHorizontalPosition, | |||
| HelpLineVerticalPosition, | |||
| } from './help-line/types' | |||
| import type { VariableAssignerNodeType } from './nodes/variable-assigner/types' | |||
| import type { | |||
| ConversationVariable, | |||
| Edge, | |||
| EnvironmentVariable, | |||
| HistoryWorkflowData, | |||
| Node, | |||
| RunFile, | |||
| ToolWithProvider, | |||
| WorkflowRunningData, | |||
| } from './types' | |||
| import { WorkflowContext } from './context' | |||
| import type { NodeTracing, VersionHistory } from '@/types/workflow' | |||
| // #TODO chatVar# | |||
| // const MOCK_DATA = [ | |||
| // { | |||
| // id: 'fjlaksdjflkjg-dfjlajfl0dnfkafjk-djfdkafj-djfak', | |||
| // name: 'chat_history', | |||
| // value_type: 'array[message]', | |||
| // value: [], | |||
| // description: 'The chat history of the conversation', | |||
| // }, | |||
| // { | |||
| // id: 'fljdaklfjl-dfjlafj0-dklajglje-eknglh', | |||
| // name: 'order_id', | |||
| // value: '123456', | |||
| // value_type: 'string', | |||
| // description: '', | |||
| // }, | |||
| // ] | |||
| type PreviewRunningData = WorkflowRunningData & { | |||
| resultTabActive?: boolean | |||
| resultText?: string | |||
| } | |||
| type Shape = { | |||
| appId: string | |||
| panelWidth: number | |||
| showSingleRunPanel: boolean | |||
| setShowSingleRunPanel: (showSingleRunPanel: boolean) => void | |||
| workflowRunningData?: PreviewRunningData | |||
| setWorkflowRunningData: (workflowData: PreviewRunningData) => void | |||
| historyWorkflowData?: HistoryWorkflowData | |||
| setHistoryWorkflowData: (historyWorkflowData?: HistoryWorkflowData) => void | |||
| showRunHistory: boolean | |||
| setShowRunHistory: (showRunHistory: boolean) => void | |||
| showFeaturesPanel: boolean | |||
| setShowFeaturesPanel: (showFeaturesPanel: boolean) => void | |||
| helpLineHorizontal?: HelpLineHorizontalPosition | |||
| setHelpLineHorizontal: (helpLineHorizontal?: HelpLineHorizontalPosition) => void | |||
| helpLineVertical?: HelpLineVerticalPosition | |||
| setHelpLineVertical: (helpLineVertical?: HelpLineVerticalPosition) => void | |||
| draftUpdatedAt: number | |||
| setDraftUpdatedAt: (draftUpdatedAt: number) => void | |||
| publishedAt: number | |||
| setPublishedAt: (publishedAt: number) => void | |||
| currentVersion: VersionHistory | null | |||
| setCurrentVersion: (currentVersion: VersionHistory) => void | |||
| showWorkflowVersionHistoryPanel: boolean | |||
| setShowWorkflowVersionHistoryPanel: (showWorkflowVersionHistoryPanel: boolean) => void | |||
| showInputsPanel: boolean | |||
| setShowInputsPanel: (showInputsPanel: boolean) => void | |||
| inputs: Record<string, string> | |||
| setInputs: (inputs: Record<string, string>) => void | |||
| toolPublished: boolean | |||
| setToolPublished: (toolPublished: boolean) => void | |||
| files: RunFile[] | |||
| setFiles: (files: RunFile[]) => void | |||
| backupDraft?: { | |||
| nodes: Node[] | |||
| edges: Edge[] | |||
| viewport: Viewport | |||
| features: Record<string, any> | |||
| environmentVariables: EnvironmentVariable[] | |||
| } | |||
| setBackupDraft: (backupDraft?: Shape['backupDraft']) => void | |||
| notInitialWorkflow: boolean | |||
| setNotInitialWorkflow: (notInitialWorkflow: boolean) => void | |||
| nodesDefaultConfigs: Record<string, any> | |||
| setNodesDefaultConfigs: (nodesDefaultConfigs: Record<string, any>) => void | |||
| nodeAnimation: boolean | |||
| setNodeAnimation: (nodeAnimation: boolean) => void | |||
| isRestoring: boolean | |||
| setIsRestoring: (isRestoring: boolean) => void | |||
| debouncedSyncWorkflowDraft: (fn: () => void) => void | |||
| buildInTools: ToolWithProvider[] | |||
| setBuildInTools: (tools: ToolWithProvider[]) => void | |||
| customTools: ToolWithProvider[] | |||
| setCustomTools: (tools: ToolWithProvider[]) => void | |||
| workflowTools: ToolWithProvider[] | |||
| setWorkflowTools: (tools: ToolWithProvider[]) => void | |||
| clipboardElements: Node[] | |||
| setClipboardElements: (clipboardElements: Node[]) => void | |||
| showDebugAndPreviewPanel: boolean | |||
| setShowDebugAndPreviewPanel: (showDebugAndPreviewPanel: boolean) => void | |||
| showEnvPanel: boolean | |||
| setShowEnvPanel: (showEnvPanel: boolean) => void | |||
| environmentVariables: EnvironmentVariable[] | |||
| setEnvironmentVariables: (environmentVariables: EnvironmentVariable[]) => void | |||
| envSecrets: Record<string, string> | |||
| setEnvSecrets: (envSecrets: Record<string, string>) => void | |||
| showChatVariablePanel: boolean | |||
| setShowChatVariablePanel: (showChatVariablePanel: boolean) => void | |||
| showGlobalVariablePanel: boolean | |||
| setShowGlobalVariablePanel: (showGlobalVariablePanel: boolean) => void | |||
| conversationVariables: ConversationVariable[] | |||
| setConversationVariables: (conversationVariables: ConversationVariable[]) => void | |||
| selection: null | { x1: number; y1: number; x2: number; y2: number } | |||
| setSelection: (selection: Shape['selection']) => void | |||
| bundleNodeSize: { width: number; height: number } | null | |||
| setBundleNodeSize: (bundleNodeSize: Shape['bundleNodeSize']) => void | |||
| controlMode: 'pointer' | 'hand' | |||
| setControlMode: (controlMode: Shape['controlMode']) => void | |||
| candidateNode?: Node | |||
| setCandidateNode: (candidateNode?: Node) => void | |||
| panelMenu?: { | |||
| top: number | |||
| left: number | |||
| } | |||
| setPanelMenu: (panelMenu: Shape['panelMenu']) => void | |||
| nodeMenu?: { | |||
| top: number | |||
| left: number | |||
| nodeId: string | |||
| } | |||
| setNodeMenu: (nodeMenu: Shape['nodeMenu']) => void | |||
| mousePosition: { pageX: number; pageY: number; elementX: number; elementY: number } | |||
| setMousePosition: (mousePosition: Shape['mousePosition']) => void | |||
| syncWorkflowDraftHash: string | |||
| setSyncWorkflowDraftHash: (hash: string) => void | |||
| showConfirm?: { title: string; desc?: string; onConfirm: () => void } | |||
| setShowConfirm: (showConfirm: Shape['showConfirm']) => void | |||
| showAssignVariablePopup?: { | |||
| nodeId: string | |||
| nodeData: Node['data'] | |||
| variableAssignerNodeId: string | |||
| variableAssignerNodeData: VariableAssignerNodeType | |||
| variableAssignerNodeHandleId: string | |||
| parentNode?: Node | |||
| x: number | |||
| y: number | |||
| } | |||
| setShowAssignVariablePopup: (showAssignVariablePopup: Shape['showAssignVariablePopup']) => void | |||
| hoveringAssignVariableGroupId?: string | |||
| setHoveringAssignVariableGroupId: (hoveringAssignVariableGroupId?: string) => void | |||
| connectingNodePayload?: { nodeId: string; nodeType: string; handleType: string; handleId: string | null } | |||
| setConnectingNodePayload: (startConnectingPayload?: Shape['connectingNodePayload']) => void | |||
| enteringNodePayload?: { | |||
| nodeId: string | |||
| nodeData: VariableAssignerNodeType | |||
| } | |||
| setEnteringNodePayload: (enteringNodePayload?: Shape['enteringNodePayload']) => void | |||
| isSyncingWorkflowDraft: boolean | |||
| setIsSyncingWorkflowDraft: (isSyncingWorkflowDraft: boolean) => void | |||
| controlPromptEditorRerenderKey: number | |||
| setControlPromptEditorRerenderKey: (controlPromptEditorRerenderKey: number) => void | |||
| showImportDSLModal: boolean | |||
| setShowImportDSLModal: (showImportDSLModal: boolean) => void | |||
| showTips: string | |||
| setShowTips: (showTips: string) => void | |||
| iterTimes: number | |||
| setIterTimes: (iterTimes: number) => void | |||
| loopTimes: number | |||
| setLoopTimes: (loopTimes: number) => void | |||
| iterParallelLogMap: Map<string, Map<string, NodeTracing[]>> | |||
| setIterParallelLogMap: (iterParallelLogMap: Map<string, Map<string, NodeTracing[]>>) => void | |||
| versionHistory: VersionHistory[] | |||
| setVersionHistory: (versionHistory: VersionHistory[]) => void | |||
| } | |||
| export const createWorkflowStore = () => { | |||
| const hideAllPanel = { | |||
| showDebugAndPreviewPanel: false, | |||
| showEnvPanel: false, | |||
| showChatVariablePanel: false, | |||
| showGlobalVariablePanel: false, | |||
| } | |||
| return createStore<Shape>(set => ({ | |||
| appId: '', | |||
| panelWidth: localStorage.getItem('workflow-node-panel-width') ? Number.parseFloat(localStorage.getItem('workflow-node-panel-width')!) : 420, | |||
| showSingleRunPanel: false, | |||
| setShowSingleRunPanel: showSingleRunPanel => set(() => ({ showSingleRunPanel })), | |||
| workflowRunningData: undefined, | |||
| setWorkflowRunningData: workflowRunningData => set(() => ({ workflowRunningData })), | |||
| historyWorkflowData: undefined, | |||
| setHistoryWorkflowData: historyWorkflowData => set(() => ({ historyWorkflowData })), | |||
| showRunHistory: false, | |||
| setShowRunHistory: showRunHistory => set(() => ({ showRunHistory })), | |||
| showFeaturesPanel: false, | |||
| setShowFeaturesPanel: showFeaturesPanel => set(() => ({ showFeaturesPanel })), | |||
| helpLineHorizontal: undefined, | |||
| setHelpLineHorizontal: helpLineHorizontal => set(() => ({ helpLineHorizontal })), | |||
| helpLineVertical: undefined, | |||
| setHelpLineVertical: helpLineVertical => set(() => ({ helpLineVertical })), | |||
| draftUpdatedAt: 0, | |||
| setDraftUpdatedAt: draftUpdatedAt => set(() => ({ draftUpdatedAt: draftUpdatedAt ? draftUpdatedAt * 1000 : 0 })), | |||
| publishedAt: 0, | |||
| setPublishedAt: publishedAt => set(() => ({ publishedAt: publishedAt ? publishedAt * 1000 : 0 })), | |||
| currentVersion: null, | |||
| setCurrentVersion: currentVersion => set(() => ({ currentVersion })), | |||
| showWorkflowVersionHistoryPanel: false, | |||
| setShowWorkflowVersionHistoryPanel: showWorkflowVersionHistoryPanel => set(() => ({ showWorkflowVersionHistoryPanel })), | |||
| showInputsPanel: false, | |||
| setShowInputsPanel: showInputsPanel => set(() => ({ showInputsPanel })), | |||
| inputs: {}, | |||
| setInputs: inputs => set(() => ({ inputs })), | |||
| toolPublished: false, | |||
| setToolPublished: toolPublished => set(() => ({ toolPublished })), | |||
| files: [], | |||
| setFiles: files => set(() => ({ files })), | |||
| backupDraft: undefined, | |||
| setBackupDraft: backupDraft => set(() => ({ backupDraft })), | |||
| notInitialWorkflow: false, | |||
| setNotInitialWorkflow: notInitialWorkflow => set(() => ({ notInitialWorkflow })), | |||
| nodesDefaultConfigs: {}, | |||
| setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })), | |||
| nodeAnimation: false, | |||
| setNodeAnimation: nodeAnimation => set(() => ({ nodeAnimation })), | |||
| isRestoring: false, | |||
| setIsRestoring: isRestoring => set(() => ({ isRestoring })), | |||
| debouncedSyncWorkflowDraft: debounce((syncWorkflowDraft) => { | |||
| syncWorkflowDraft() | |||
| }, 5000), | |||
| buildInTools: [], | |||
| setBuildInTools: buildInTools => set(() => ({ buildInTools })), | |||
| customTools: [], | |||
| setCustomTools: customTools => set(() => ({ customTools })), | |||
| workflowTools: [], | |||
| setWorkflowTools: workflowTools => set(() => ({ workflowTools })), | |||
| clipboardElements: [], | |||
| setClipboardElements: clipboardElements => set(() => ({ clipboardElements })), | |||
| showDebugAndPreviewPanel: false, | |||
| setShowDebugAndPreviewPanel: showDebugAndPreviewPanel => set(() => ({ showDebugAndPreviewPanel })), | |||
| showEnvPanel: false, | |||
| setShowEnvPanel: showEnvPanel => set(() => ({ showEnvPanel })), | |||
| environmentVariables: [], | |||
| setEnvironmentVariables: environmentVariables => set(() => ({ environmentVariables })), | |||
| envSecrets: {}, | |||
| setEnvSecrets: envSecrets => set(() => ({ envSecrets })), | |||
| showChatVariablePanel: false, | |||
| setShowChatVariablePanel: showChatVariablePanel => set(() => ({ showChatVariablePanel })), | |||
| showGlobalVariablePanel: false, | |||
| setShowGlobalVariablePanel: showGlobalVariablePanel => set(() => { | |||
| if (showGlobalVariablePanel) | |||
| return { ...hideAllPanel, showGlobalVariablePanel: true } | |||
| else | |||
| return { showGlobalVariablePanel: false } | |||
| }), | |||
| conversationVariables: [], | |||
| setConversationVariables: conversationVariables => set(() => ({ conversationVariables })), | |||
| selection: null, | |||
| setSelection: selection => set(() => ({ selection })), | |||
| bundleNodeSize: null, | |||
| setBundleNodeSize: bundleNodeSize => set(() => ({ bundleNodeSize })), | |||
| controlMode: localStorage.getItem('workflow-operation-mode') === 'pointer' ? 'pointer' : 'hand', | |||
| setControlMode: (controlMode) => { | |||
| set(() => ({ controlMode })) | |||
| localStorage.setItem('workflow-operation-mode', controlMode) | |||
| }, | |||
| candidateNode: undefined, | |||
| setCandidateNode: candidateNode => set(() => ({ candidateNode })), | |||
| panelMenu: undefined, | |||
| setPanelMenu: panelMenu => set(() => ({ panelMenu })), | |||
| nodeMenu: undefined, | |||
| setNodeMenu: nodeMenu => set(() => ({ nodeMenu })), | |||
| mousePosition: { pageX: 0, pageY: 0, elementX: 0, elementY: 0 }, | |||
| setMousePosition: mousePosition => set(() => ({ mousePosition })), | |||
| syncWorkflowDraftHash: '', | |||
| setSyncWorkflowDraftHash: syncWorkflowDraftHash => set(() => ({ syncWorkflowDraftHash })), | |||
| showConfirm: undefined, | |||
| setShowConfirm: showConfirm => set(() => ({ showConfirm })), | |||
| showAssignVariablePopup: undefined, | |||
| setShowAssignVariablePopup: showAssignVariablePopup => set(() => ({ showAssignVariablePopup })), | |||
| hoveringAssignVariableGroupId: undefined, | |||
| setHoveringAssignVariableGroupId: hoveringAssignVariableGroupId => set(() => ({ hoveringAssignVariableGroupId })), | |||
| connectingNodePayload: undefined, | |||
| setConnectingNodePayload: connectingNodePayload => set(() => ({ connectingNodePayload })), | |||
| enteringNodePayload: undefined, | |||
| setEnteringNodePayload: enteringNodePayload => set(() => ({ enteringNodePayload })), | |||
| isSyncingWorkflowDraft: false, | |||
| setIsSyncingWorkflowDraft: isSyncingWorkflowDraft => set(() => ({ isSyncingWorkflowDraft })), | |||
| controlPromptEditorRerenderKey: 0, | |||
| setControlPromptEditorRerenderKey: controlPromptEditorRerenderKey => set(() => ({ controlPromptEditorRerenderKey })), | |||
| showImportDSLModal: false, | |||
| setShowImportDSLModal: showImportDSLModal => set(() => ({ showImportDSLModal })), | |||
| showTips: '', | |||
| setShowTips: showTips => set(() => ({ showTips })), | |||
| iterTimes: 1, | |||
| setIterTimes: iterTimes => set(() => ({ iterTimes })), | |||
| loopTimes: 1, | |||
| setLoopTimes: loopTimes => set(() => ({ loopTimes })), | |||
| iterParallelLogMap: new Map<string, Map<string, NodeTracing[]>>(), | |||
| setIterParallelLogMap: iterParallelLogMap => set(() => ({ iterParallelLogMap })), | |||
| versionHistory: [], | |||
| setVersionHistory: versionHistory => set(() => ({ versionHistory })), | |||
| })) | |||
| } | |||
| export function useStore<T>(selector: (state: Shape) => T): T { | |||
| const store = useContext(WorkflowContext) | |||
| if (!store) | |||
| throw new Error('Missing WorkflowContext.Provider in the tree') | |||
| return useZustandStore(store, selector) | |||
| } | |||
| export const useWorkflowStore = () => { | |||
| return useContext(WorkflowContext)! | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| export * from './workflow' | |||
| @@ -0,0 +1,34 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { ConversationVariable } from '@/app/components/workflow/types' | |||
| export type ChatVariableSliceShape = { | |||
| showChatVariablePanel: boolean | |||
| setShowChatVariablePanel: (showChatVariablePanel: boolean) => void | |||
| showGlobalVariablePanel: boolean | |||
| setShowGlobalVariablePanel: (showGlobalVariablePanel: boolean) => void | |||
| conversationVariables: ConversationVariable[] | |||
| setConversationVariables: (conversationVariables: ConversationVariable[]) => void | |||
| } | |||
| export const createChatVariableSlice: StateCreator<ChatVariableSliceShape> = (set) => { | |||
| const hideAllPanel = { | |||
| showDebugAndPreviewPanel: false, | |||
| showEnvPanel: false, | |||
| showChatVariablePanel: false, | |||
| showGlobalVariablePanel: false, | |||
| } | |||
| return ({ | |||
| showChatVariablePanel: false, | |||
| setShowChatVariablePanel: showChatVariablePanel => set(() => ({ showChatVariablePanel })), | |||
| showGlobalVariablePanel: false, | |||
| setShowGlobalVariablePanel: showGlobalVariablePanel => set(() => { | |||
| if (showGlobalVariablePanel) | |||
| return { ...hideAllPanel, showGlobalVariablePanel: true } | |||
| else | |||
| return { showGlobalVariablePanel: false } | |||
| }), | |||
| conversationVariables: [], | |||
| setConversationVariables: conversationVariables => set(() => ({ conversationVariables })), | |||
| }) | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { EnvironmentVariable } from '@/app/components/workflow/types' | |||
| export type EnvVariableSliceShape = { | |||
| showEnvPanel: boolean | |||
| setShowEnvPanel: (showEnvPanel: boolean) => void | |||
| environmentVariables: EnvironmentVariable[] | |||
| setEnvironmentVariables: (environmentVariables: EnvironmentVariable[]) => void | |||
| envSecrets: Record<string, string> | |||
| setEnvSecrets: (envSecrets: Record<string, string>) => void | |||
| } | |||
| export const createEnvVariableSlice: StateCreator<EnvVariableSliceShape> = set => ({ | |||
| showEnvPanel: false, | |||
| setShowEnvPanel: showEnvPanel => set(() => ({ showEnvPanel })), | |||
| environmentVariables: [], | |||
| setEnvironmentVariables: environmentVariables => set(() => ({ environmentVariables })), | |||
| envSecrets: {}, | |||
| setEnvSecrets: envSecrets => set(() => ({ envSecrets })), | |||
| }) | |||
| @@ -0,0 +1,18 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| RunFile, | |||
| } from '@/app/components/workflow/types' | |||
| export type FormSliceShape = { | |||
| inputs: Record<string, string> | |||
| setInputs: (inputs: Record<string, string>) => void | |||
| files: RunFile[] | |||
| setFiles: (files: RunFile[]) => void | |||
| } | |||
| export const createFormSlice: StateCreator<FormSliceShape> = set => ({ | |||
| inputs: {}, | |||
| setInputs: inputs => set(() => ({ inputs })), | |||
| files: [], | |||
| setFiles: files => set(() => ({ files })), | |||
| }) | |||
| @@ -0,0 +1,19 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| HelpLineHorizontalPosition, | |||
| HelpLineVerticalPosition, | |||
| } from '@/app/components/workflow/help-line/types' | |||
| export type HelpLineSliceShape = { | |||
| helpLineHorizontal?: HelpLineHorizontalPosition | |||
| setHelpLineHorizontal: (helpLineHorizontal?: HelpLineHorizontalPosition) => void | |||
| helpLineVertical?: HelpLineVerticalPosition | |||
| setHelpLineVertical: (helpLineVertical?: HelpLineVerticalPosition) => void | |||
| } | |||
| export const createHelpLineSlice: StateCreator<HelpLineSliceShape> = set => ({ | |||
| helpLineHorizontal: undefined, | |||
| setHelpLineHorizontal: helpLineHorizontal => set(() => ({ helpLineHorizontal })), | |||
| helpLineVertical: undefined, | |||
| setHelpLineVertical: helpLineVertical => set(() => ({ helpLineVertical })), | |||
| }) | |||
| @@ -0,0 +1,25 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| HistoryWorkflowData, | |||
| } from '@/app/components/workflow/types' | |||
| import type { | |||
| VersionHistory, | |||
| } from '@/types/workflow' | |||
| export type HistorySliceShape = { | |||
| historyWorkflowData?: HistoryWorkflowData | |||
| setHistoryWorkflowData: (historyWorkflowData?: HistoryWorkflowData) => void | |||
| showRunHistory: boolean | |||
| setShowRunHistory: (showRunHistory: boolean) => void | |||
| versionHistory: VersionHistory[] | |||
| setVersionHistory: (versionHistory: VersionHistory[]) => void | |||
| } | |||
| export const createHistorySlice: StateCreator<HistorySliceShape> = set => ({ | |||
| historyWorkflowData: undefined, | |||
| setHistoryWorkflowData: historyWorkflowData => set(() => ({ historyWorkflowData })), | |||
| showRunHistory: false, | |||
| setShowRunHistory: showRunHistory => set(() => ({ showRunHistory })), | |||
| versionHistory: [], | |||
| setVersionHistory: versionHistory => set(() => ({ versionHistory })), | |||
| }) | |||
| @@ -0,0 +1,69 @@ | |||
| import { useContext } from 'react' | |||
| import { | |||
| useStore as useZustandStore, | |||
| } from 'zustand' | |||
| import { createStore } from 'zustand/vanilla' | |||
| import type { ChatVariableSliceShape } from './chat-variable-slice' | |||
| import { createChatVariableSlice } from './chat-variable-slice' | |||
| import type { EnvVariableSliceShape } from './env-variable-slice' | |||
| import { createEnvVariableSlice } from './env-variable-slice' | |||
| import type { FormSliceShape } from './form-slice' | |||
| import { createFormSlice } from './form-slice' | |||
| import type { HelpLineSliceShape } from './help-line-slice' | |||
| import { createHelpLineSlice } from './help-line-slice' | |||
| import type { HistorySliceShape } from './history-slice' | |||
| import { createHistorySlice } from './history-slice' | |||
| import type { NodeSliceShape } from './node-slice' | |||
| import { createNodeSlice } from './node-slice' | |||
| import type { PanelSliceShape } from './panel-slice' | |||
| import { createPanelSlice } from './panel-slice' | |||
| import type { ToolSliceShape } from './tool-slice' | |||
| import { createToolSlice } from './tool-slice' | |||
| import type { VersionSliceShape } from './version-slice' | |||
| import { createVersionSlice } from './version-slice' | |||
| import type { WorkflowDraftSliceShape } from './workflow-draft-slice' | |||
| import { createWorkflowDraftSlice } from './workflow-draft-slice' | |||
| import type { WorkflowSliceShape } from './workflow-slice' | |||
| import { createWorkflowSlice } from './workflow-slice' | |||
| import { WorkflowContext } from '@/app/components/workflow/context' | |||
| export type Shape = | |||
| ChatVariableSliceShape & | |||
| EnvVariableSliceShape & | |||
| FormSliceShape & | |||
| HelpLineSliceShape & | |||
| HistorySliceShape & | |||
| NodeSliceShape & | |||
| PanelSliceShape & | |||
| ToolSliceShape & | |||
| VersionSliceShape & | |||
| WorkflowDraftSliceShape & | |||
| WorkflowSliceShape | |||
| export const createWorkflowStore = () => { | |||
| return createStore<Shape>((...args) => ({ | |||
| ...createChatVariableSlice(...args), | |||
| ...createEnvVariableSlice(...args), | |||
| ...createFormSlice(...args), | |||
| ...createHelpLineSlice(...args), | |||
| ...createHistorySlice(...args), | |||
| ...createNodeSlice(...args), | |||
| ...createPanelSlice(...args), | |||
| ...createToolSlice(...args), | |||
| ...createVersionSlice(...args), | |||
| ...createWorkflowDraftSlice(...args), | |||
| ...createWorkflowSlice(...args), | |||
| })) | |||
| } | |||
| export function useStore<T>(selector: (state: Shape) => T): T { | |||
| const store = useContext(WorkflowContext) | |||
| if (!store) | |||
| throw new Error('Missing WorkflowContext.Provider in the tree') | |||
| return useZustandStore(store, selector) | |||
| } | |||
| export const useWorkflowStore = () => { | |||
| return useContext(WorkflowContext)! | |||
| } | |||
| @@ -0,0 +1,80 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| Node, | |||
| } from '@/app/components/workflow/types' | |||
| import type { | |||
| VariableAssignerNodeType, | |||
| } from '@/app/components/workflow/nodes/variable-assigner/types' | |||
| import type { | |||
| NodeTracing, | |||
| } from '@/types/workflow' | |||
| export type NodeSliceShape = { | |||
| showSingleRunPanel: boolean | |||
| setShowSingleRunPanel: (showSingleRunPanel: boolean) => void | |||
| nodesDefaultConfigs: Record<string, any> | |||
| setNodesDefaultConfigs: (nodesDefaultConfigs: Record<string, any>) => void | |||
| nodeAnimation: boolean | |||
| setNodeAnimation: (nodeAnimation: boolean) => void | |||
| candidateNode?: Node | |||
| setCandidateNode: (candidateNode?: Node) => void | |||
| nodeMenu?: { | |||
| top: number | |||
| left: number | |||
| nodeId: string | |||
| } | |||
| setNodeMenu: (nodeMenu: NodeSliceShape['nodeMenu']) => void | |||
| showAssignVariablePopup?: { | |||
| nodeId: string | |||
| nodeData: Node['data'] | |||
| variableAssignerNodeId: string | |||
| variableAssignerNodeData: VariableAssignerNodeType | |||
| variableAssignerNodeHandleId: string | |||
| parentNode?: Node | |||
| x: number | |||
| y: number | |||
| } | |||
| setShowAssignVariablePopup: (showAssignVariablePopup: NodeSliceShape['showAssignVariablePopup']) => void | |||
| hoveringAssignVariableGroupId?: string | |||
| setHoveringAssignVariableGroupId: (hoveringAssignVariableGroupId?: string) => void | |||
| connectingNodePayload?: { nodeId: string; nodeType: string; handleType: string; handleId: string | null } | |||
| setConnectingNodePayload: (startConnectingPayload?: NodeSliceShape['connectingNodePayload']) => void | |||
| enteringNodePayload?: { | |||
| nodeId: string | |||
| nodeData: VariableAssignerNodeType | |||
| } | |||
| setEnteringNodePayload: (enteringNodePayload?: NodeSliceShape['enteringNodePayload']) => void | |||
| iterTimes: number | |||
| setIterTimes: (iterTimes: number) => void | |||
| loopTimes: number | |||
| setLoopTimes: (loopTimes: number) => void | |||
| iterParallelLogMap: Map<string, Map<string, NodeTracing[]>> | |||
| setIterParallelLogMap: (iterParallelLogMap: Map<string, Map<string, NodeTracing[]>>) => void | |||
| } | |||
| export const createNodeSlice: StateCreator<NodeSliceShape> = set => ({ | |||
| showSingleRunPanel: false, | |||
| setShowSingleRunPanel: showSingleRunPanel => set(() => ({ showSingleRunPanel })), | |||
| nodesDefaultConfigs: {}, | |||
| setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })), | |||
| nodeAnimation: false, | |||
| setNodeAnimation: nodeAnimation => set(() => ({ nodeAnimation })), | |||
| candidateNode: undefined, | |||
| setCandidateNode: candidateNode => set(() => ({ candidateNode })), | |||
| nodeMenu: undefined, | |||
| setNodeMenu: nodeMenu => set(() => ({ nodeMenu })), | |||
| showAssignVariablePopup: undefined, | |||
| setShowAssignVariablePopup: showAssignVariablePopup => set(() => ({ showAssignVariablePopup })), | |||
| hoveringAssignVariableGroupId: undefined, | |||
| setHoveringAssignVariableGroupId: hoveringAssignVariableGroupId => set(() => ({ hoveringAssignVariableGroupId })), | |||
| connectingNodePayload: undefined, | |||
| setConnectingNodePayload: connectingNodePayload => set(() => ({ connectingNodePayload })), | |||
| enteringNodePayload: undefined, | |||
| setEnteringNodePayload: enteringNodePayload => set(() => ({ enteringNodePayload })), | |||
| iterTimes: 1, | |||
| setIterTimes: iterTimes => set(() => ({ iterTimes })), | |||
| loopTimes: 1, | |||
| setLoopTimes: loopTimes => set(() => ({ loopTimes })), | |||
| iterParallelLogMap: new Map<string, Map<string, NodeTracing[]>>(), | |||
| setIterParallelLogMap: iterParallelLogMap => set(() => ({ iterParallelLogMap })), | |||
| }) | |||
| @@ -0,0 +1,32 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| export type PanelSliceShape = { | |||
| panelWidth: number | |||
| showFeaturesPanel: boolean | |||
| setShowFeaturesPanel: (showFeaturesPanel: boolean) => void | |||
| showWorkflowVersionHistoryPanel: boolean | |||
| setShowWorkflowVersionHistoryPanel: (showWorkflowVersionHistoryPanel: boolean) => void | |||
| showInputsPanel: boolean | |||
| setShowInputsPanel: (showInputsPanel: boolean) => void | |||
| showDebugAndPreviewPanel: boolean | |||
| setShowDebugAndPreviewPanel: (showDebugAndPreviewPanel: boolean) => void | |||
| panelMenu?: { | |||
| top: number | |||
| left: number | |||
| } | |||
| setPanelMenu: (panelMenu: PanelSliceShape['panelMenu']) => void | |||
| } | |||
| export const createPanelSlice: StateCreator<PanelSliceShape> = set => ({ | |||
| panelWidth: localStorage.getItem('workflow-node-panel-width') ? Number.parseFloat(localStorage.getItem('workflow-node-panel-width')!) : 420, | |||
| showFeaturesPanel: false, | |||
| setShowFeaturesPanel: showFeaturesPanel => set(() => ({ showFeaturesPanel })), | |||
| showWorkflowVersionHistoryPanel: false, | |||
| setShowWorkflowVersionHistoryPanel: showWorkflowVersionHistoryPanel => set(() => ({ showWorkflowVersionHistoryPanel })), | |||
| showInputsPanel: false, | |||
| setShowInputsPanel: showInputsPanel => set(() => ({ showInputsPanel })), | |||
| showDebugAndPreviewPanel: false, | |||
| setShowDebugAndPreviewPanel: showDebugAndPreviewPanel => set(() => ({ showDebugAndPreviewPanel })), | |||
| panelMenu: undefined, | |||
| setPanelMenu: panelMenu => set(() => ({ panelMenu })), | |||
| }) | |||
| @@ -0,0 +1,26 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| ToolWithProvider, | |||
| } from '@/app/components/workflow/types' | |||
| export type ToolSliceShape = { | |||
| buildInTools: ToolWithProvider[] | |||
| setBuildInTools: (tools: ToolWithProvider[]) => void | |||
| customTools: ToolWithProvider[] | |||
| setCustomTools: (tools: ToolWithProvider[]) => void | |||
| workflowTools: ToolWithProvider[] | |||
| setWorkflowTools: (tools: ToolWithProvider[]) => void | |||
| toolPublished: boolean | |||
| setToolPublished: (toolPublished: boolean) => void | |||
| } | |||
| export const createToolSlice: StateCreator<ToolSliceShape> = set => ({ | |||
| buildInTools: [], | |||
| setBuildInTools: buildInTools => set(() => ({ buildInTools })), | |||
| customTools: [], | |||
| setCustomTools: customTools => set(() => ({ customTools })), | |||
| workflowTools: [], | |||
| setWorkflowTools: workflowTools => set(() => ({ workflowTools })), | |||
| toolPublished: false, | |||
| setToolPublished: toolPublished => set(() => ({ toolPublished })), | |||
| }) | |||
| @@ -0,0 +1,26 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| VersionHistory, | |||
| } from '@/types/workflow' | |||
| export type VersionSliceShape = { | |||
| draftUpdatedAt: number | |||
| setDraftUpdatedAt: (draftUpdatedAt: number) => void | |||
| publishedAt: number | |||
| setPublishedAt: (publishedAt: number) => void | |||
| currentVersion: VersionHistory | null | |||
| setCurrentVersion: (currentVersion: VersionHistory) => void | |||
| isRestoring: boolean | |||
| setIsRestoring: (isRestoring: boolean) => void | |||
| } | |||
| export const createVersionSlice: StateCreator<VersionSliceShape> = set => ({ | |||
| draftUpdatedAt: 0, | |||
| setDraftUpdatedAt: draftUpdatedAt => set(() => ({ draftUpdatedAt: draftUpdatedAt ? draftUpdatedAt * 1000 : 0 })), | |||
| publishedAt: 0, | |||
| setPublishedAt: publishedAt => set(() => ({ publishedAt: publishedAt ? publishedAt * 1000 : 0 })), | |||
| currentVersion: null, | |||
| setCurrentVersion: currentVersion => set(() => ({ currentVersion })), | |||
| isRestoring: false, | |||
| setIsRestoring: isRestoring => set(() => ({ isRestoring })), | |||
| }) | |||
| @@ -0,0 +1,36 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import { debounce } from 'lodash-es' | |||
| import type { Viewport } from 'reactflow' | |||
| import type { | |||
| Edge, | |||
| EnvironmentVariable, | |||
| Node, | |||
| } from '@/app/components/workflow/types' | |||
| export type WorkflowDraftSliceShape = { | |||
| backupDraft?: { | |||
| nodes: Node[] | |||
| edges: Edge[] | |||
| viewport: Viewport | |||
| features: Record<string, any> | |||
| environmentVariables: EnvironmentVariable[] | |||
| } | |||
| setBackupDraft: (backupDraft?: WorkflowDraftSliceShape['backupDraft']) => void | |||
| debouncedSyncWorkflowDraft: (fn: () => void) => void | |||
| syncWorkflowDraftHash: string | |||
| setSyncWorkflowDraftHash: (hash: string) => void | |||
| isSyncingWorkflowDraft: boolean | |||
| setIsSyncingWorkflowDraft: (isSyncingWorkflowDraft: boolean) => void | |||
| } | |||
| export const createWorkflowDraftSlice: StateCreator<WorkflowDraftSliceShape> = set => ({ | |||
| backupDraft: undefined, | |||
| setBackupDraft: backupDraft => set(() => ({ backupDraft })), | |||
| debouncedSyncWorkflowDraft: debounce((syncWorkflowDraft) => { | |||
| syncWorkflowDraft() | |||
| }, 5000), | |||
| syncWorkflowDraftHash: '', | |||
| setSyncWorkflowDraftHash: syncWorkflowDraftHash => set(() => ({ syncWorkflowDraftHash })), | |||
| isSyncingWorkflowDraft: false, | |||
| setIsSyncingWorkflowDraft: isSyncingWorkflowDraft => set(() => ({ isSyncingWorkflowDraft })), | |||
| }) | |||
| @@ -0,0 +1,65 @@ | |||
| import type { StateCreator } from 'zustand' | |||
| import type { | |||
| Node, | |||
| WorkflowRunningData, | |||
| } from '@/app/components/workflow/types' | |||
| type PreviewRunningData = WorkflowRunningData & { | |||
| resultTabActive?: boolean | |||
| resultText?: string | |||
| } | |||
| export type WorkflowSliceShape = { | |||
| appId: string | |||
| workflowRunningData?: PreviewRunningData | |||
| setWorkflowRunningData: (workflowData: PreviewRunningData) => void | |||
| notInitialWorkflow: boolean | |||
| setNotInitialWorkflow: (notInitialWorkflow: boolean) => void | |||
| clipboardElements: Node[] | |||
| setClipboardElements: (clipboardElements: Node[]) => void | |||
| selection: null | { x1: number; y1: number; x2: number; y2: number } | |||
| setSelection: (selection: WorkflowSliceShape['selection']) => void | |||
| bundleNodeSize: { width: number; height: number } | null | |||
| setBundleNodeSize: (bundleNodeSize: WorkflowSliceShape['bundleNodeSize']) => void | |||
| controlMode: 'pointer' | 'hand' | |||
| setControlMode: (controlMode: WorkflowSliceShape['controlMode']) => void | |||
| mousePosition: { pageX: number; pageY: number; elementX: number; elementY: number } | |||
| setMousePosition: (mousePosition: WorkflowSliceShape['mousePosition']) => void | |||
| showConfirm?: { title: string; desc?: string; onConfirm: () => void } | |||
| setShowConfirm: (showConfirm: WorkflowSliceShape['showConfirm']) => void | |||
| controlPromptEditorRerenderKey: number | |||
| setControlPromptEditorRerenderKey: (controlPromptEditorRerenderKey: number) => void | |||
| showImportDSLModal: boolean | |||
| setShowImportDSLModal: (showImportDSLModal: boolean) => void | |||
| showTips: string | |||
| setShowTips: (showTips: string) => void | |||
| } | |||
| export const createWorkflowSlice: StateCreator<WorkflowSliceShape> = set => ({ | |||
| appId: '', | |||
| workflowRunningData: undefined, | |||
| setWorkflowRunningData: workflowRunningData => set(() => ({ workflowRunningData })), | |||
| notInitialWorkflow: false, | |||
| setNotInitialWorkflow: notInitialWorkflow => set(() => ({ notInitialWorkflow })), | |||
| clipboardElements: [], | |||
| setClipboardElements: clipboardElements => set(() => ({ clipboardElements })), | |||
| selection: null, | |||
| setSelection: selection => set(() => ({ selection })), | |||
| bundleNodeSize: null, | |||
| setBundleNodeSize: bundleNodeSize => set(() => ({ bundleNodeSize })), | |||
| controlMode: localStorage.getItem('workflow-operation-mode') === 'pointer' ? 'pointer' : 'hand', | |||
| setControlMode: (controlMode) => { | |||
| set(() => ({ controlMode })) | |||
| localStorage.setItem('workflow-operation-mode', controlMode) | |||
| }, | |||
| mousePosition: { pageX: 0, pageY: 0, elementX: 0, elementY: 0 }, | |||
| setMousePosition: mousePosition => set(() => ({ mousePosition })), | |||
| showConfirm: undefined, | |||
| setShowConfirm: showConfirm => set(() => ({ showConfirm })), | |||
| controlPromptEditorRerenderKey: 0, | |||
| setControlPromptEditorRerenderKey: controlPromptEditorRerenderKey => set(() => ({ controlPromptEditorRerenderKey })), | |||
| showImportDSLModal: false, | |||
| setShowImportDSLModal: showImportDSLModal => set(() => ({ showImportDSLModal })), | |||
| showTips: '', | |||
| setShowTips: showTips => set(() => ({ showTips })), | |||
| }) | |||