Merge remote-tracking branch 'origin/p254' into p284

This commit is contained in:
hjlarry
2025-09-18 15:14:55 +08:00
64 changed files with 11839 additions and 1363 deletions

View File

@ -13,7 +13,7 @@ import { syncWorkflowDraft } from '@/service/workflow'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { API_PREFIX } from '@/config'
import { useWorkflowRefreshDraft } from '.'
import { useCollaboration } from '@/app/components/workflow/collaboration/hooks/use-collaboration'
import { collaborationManager } from '@/app/components/workflow/collaboration/core/collaboration-manager'
export const useNodesSyncDraft = () => {
const store = useStoreApi()
@ -22,7 +22,6 @@ export const useNodesSyncDraft = () => {
const { getNodesReadOnly } = useNodesReadOnly()
const { handleRefreshWorkflowDraft } = useWorkflowRefreshDraft()
const params = useParams()
const { isLeader } = useCollaboration(params.appId as string)
const getPostParams = useCallback(() => {
const {
@ -94,11 +93,22 @@ export const useNodesSyncDraft = () => {
}, [store, featuresStore, workflowStore])
const syncWorkflowDraftWhenPageClose = useCallback(() => {
if (getNodesReadOnly() || !isLeader)
if (getNodesReadOnly())
return
// Check leader status at sync time
const currentIsLeader = collaborationManager.getIsLeader()
// Only allow leader to sync data
if (!currentIsLeader) {
console.log('Not leader, skipping sync on page close')
return
}
const postParams = getPostParams()
if (postParams) {
console.log('Leader syncing workflow draft on page close')
navigator.sendBeacon(
`${API_PREFIX}/apps/${params.appId}/workflows/draft?_token=${localStorage.getItem('console_token')}`,
JSON.stringify(postParams.params),
@ -113,11 +123,23 @@ export const useNodesSyncDraft = () => {
onError?: () => void
onSettled?: () => void
},
forceUpload?: boolean,
) => {
if (getNodesReadOnly() || !isLeader)
if (getNodesReadOnly())
return
console.log('I am the leader, saving draft...')
// Check leader status at sync time
const currentIsLeader = collaborationManager.getIsLeader()
// If not leader and not forcing upload, request the leader to sync
if (!currentIsLeader && !forceUpload) {
console.log('Not leader, requesting leader to sync workflow draft')
collaborationManager.emitSyncRequest()
callback?.onSettled?.()
return
}
console.log(forceUpload ? 'Force uploading workflow draft' : 'Leader performing workflow draft sync')
const postParams = getPostParams()
if (postParams) {
@ -125,19 +147,31 @@ export const useNodesSyncDraft = () => {
setSyncWorkflowDraftHash,
setDraftUpdatedAt,
} = workflowStore.getState()
// Add force_upload parameter if needed
const finalParams = {
...postParams.params,
...(forceUpload && { force_upload: true }),
}
try {
const res = await syncWorkflowDraft(postParams)
const res = await syncWorkflowDraft({
url: postParams.url,
params: finalParams,
})
setSyncWorkflowDraftHash(res.hash)
setDraftUpdatedAt(res.updated_at)
console.log('Leader successfully synced workflow draft')
callback?.onSuccess && callback.onSuccess()
}
catch (error: any) {
console.error('Leader failed to sync workflow draft:', error)
if (error && error.json && !error.bodyUsed) {
error.json().then((err: any) => {
if (err.code === 'draft_workflow_not_sync' && !notRefreshWhenSyncError)
// TODO: hjlarry test collaboration
// handleRefreshWorkflowDraft()
if (err.code === 'draft_workflow_not_sync' && !notRefreshWhenSyncError) {
console.error('draft_workflow_not_sync', err)
handleRefreshWorkflowDraft()
}
})
}
callback?.onError && callback.onError()

View File

@ -1,6 +1,7 @@
import { useCallback } from 'react'
import { useWorkflowStore } from '@/app/components/workflow/store'
import { fetchWorkflowDraft } from '@/service/workflow'
import type { WorkflowDataUpdater } from '@/app/components/workflow/types'
import { useWorkflowUpdate } from '@/app/components/workflow/hooks'
export const useWorkflowRefreshDraft = () => {
@ -18,8 +19,7 @@ export const useWorkflowRefreshDraft = () => {
} = workflowStore.getState()
setIsSyncingWorkflowDraft(true)
fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => {
// TODO: hjlarry test collaboration
// handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdater)
handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdater)
setSyncWorkflowDraftHash(response.hash)
setEnvSecrets((response.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => {
acc[env.id] = env.value