use-workflow-interactions.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { useCallback } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { useReactFlow } from 'reactflow'
  4. import { useWorkflowStore } from '../store'
  5. import { WORKFLOW_DATA_UPDATE } from '../constants'
  6. import type { WorkflowDataUpdator } from '../types'
  7. import {
  8. initialEdges,
  9. initialNodes,
  10. } from '../utils'
  11. import { useEdgesInteractions } from './use-edges-interactions'
  12. import { useNodesInteractions } from './use-nodes-interactions'
  13. import { useEventEmitterContextContext } from '@/context/event-emitter'
  14. import { fetchWorkflowDraft } from '@/service/workflow'
  15. import { exportAppConfig } from '@/service/apps'
  16. import { useToastContext } from '@/app/components/base/toast'
  17. import { useStore as useAppStore } from '@/app/components/app/store'
  18. export const useWorkflowInteractions = () => {
  19. const workflowStore = useWorkflowStore()
  20. const { handleNodeCancelRunningStatus } = useNodesInteractions()
  21. const { handleEdgeCancelRunningStatus } = useEdgesInteractions()
  22. const handleCancelDebugAndPreviewPanel = useCallback(() => {
  23. workflowStore.setState({
  24. showDebugAndPreviewPanel: false,
  25. workflowRunningData: undefined,
  26. })
  27. handleNodeCancelRunningStatus()
  28. handleEdgeCancelRunningStatus()
  29. }, [workflowStore, handleNodeCancelRunningStatus, handleEdgeCancelRunningStatus])
  30. return {
  31. handleCancelDebugAndPreviewPanel,
  32. }
  33. }
  34. export const useWorkflowUpdate = () => {
  35. const reactflow = useReactFlow()
  36. const workflowStore = useWorkflowStore()
  37. const { eventEmitter } = useEventEmitterContextContext()
  38. const handleUpdateWorkflowCanvas = useCallback((payload: WorkflowDataUpdator) => {
  39. const {
  40. nodes,
  41. edges,
  42. viewport,
  43. } = payload
  44. const { setViewport } = reactflow
  45. eventEmitter?.emit({
  46. type: WORKFLOW_DATA_UPDATE,
  47. payload: {
  48. nodes: initialNodes(nodes, edges),
  49. edges: initialEdges(edges, nodes),
  50. },
  51. } as any)
  52. setViewport(viewport)
  53. }, [eventEmitter, reactflow])
  54. const handleRefreshWorkflowDraft = useCallback(() => {
  55. const {
  56. appId,
  57. setSyncWorkflowDraftHash,
  58. setIsSyncingWorkflowDraft,
  59. } = workflowStore.getState()
  60. setIsSyncingWorkflowDraft(true)
  61. fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => {
  62. handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdator)
  63. setSyncWorkflowDraftHash(response.hash)
  64. }).finally(() => setIsSyncingWorkflowDraft(false))
  65. }, [handleUpdateWorkflowCanvas, workflowStore])
  66. return {
  67. handleUpdateWorkflowCanvas,
  68. handleRefreshWorkflowDraft,
  69. }
  70. }
  71. export const useDSL = () => {
  72. const { t } = useTranslation()
  73. const { notify } = useToastContext()
  74. const appDetail = useAppStore(s => s.appDetail)
  75. const handleExportDSL = useCallback(async () => {
  76. if (!appDetail)
  77. return
  78. try {
  79. const { data } = await exportAppConfig(appDetail.id)
  80. const a = document.createElement('a')
  81. const file = new Blob([data], { type: 'application/yaml' })
  82. a.href = URL.createObjectURL(file)
  83. a.download = `${appDetail.name}.yml`
  84. a.click()
  85. }
  86. catch (e) {
  87. notify({ type: 'error', message: t('app.exportFailed') })
  88. }
  89. }, [appDetail, notify, t])
  90. return {
  91. handleExportDSL,
  92. }
  93. }