Skip to content

Commit c698838

Browse files
authored
[feat] Allow opening workflows with same name as new tabs (#7104)
When importing a workflow file that has the same name as an existing open workflow, create a new tab with a unique suffix (2), (3), etc. instead of silently failing or replacing the existing workflow. - Add forceNew parameter to createTemporary() in workflowStore - Always create new temporary workflow when importing via file picker - Remove logic that looked up persisted workflows by name during import https://github.com/user-attachments/assets/9c9aebd3-37c2-464f-9fb4-9ef871ec2673 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7104-feat-Allow-opening-workflows-with-same-name-as-new-tabs-2bd6d73d365081cd9182eaa35bf37c29) by [Unito](https://www.unito.io)
1 parent d50a2fa commit c698838

File tree

2 files changed

+73
-32
lines changed

2 files changed

+73
-32
lines changed

src/platform/workflow/core/services/workflowService.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -310,31 +310,36 @@ export const useWorkflowService = () => {
310310
value: string | ComfyWorkflow | null,
311311
workflowData: ComfyWorkflowJSON
312312
) => {
313-
// Use workspaceStore here as it is patched in unit tests.
314313
const workflowStore = useWorkspaceStore().workflow
315-
if (typeof value === 'string') {
316-
const workflow = workflowStore.getWorkflowByPath(
317-
ComfyWorkflow.basePath + appendJsonExt(value)
318-
)
319-
if (workflow?.isPersisted) {
320-
const loadedWorkflow = await workflowStore.openWorkflow(workflow)
321-
loadedWorkflow.changeTracker.restore()
322-
loadedWorkflow.changeTracker.reset(workflowData)
323-
return
324-
}
325-
}
326314

327315
if (value === null || typeof value === 'string') {
328316
const path = value as string | null
329-
const tempWorkflow = workflowStore.createTemporary(
317+
318+
// Check if a persisted workflow with this path exists
319+
if (path) {
320+
const fullPath = ComfyWorkflow.basePath + appendJsonExt(path)
321+
const existingWorkflow = workflowStore.getWorkflowByPath(fullPath)
322+
323+
// If the workflow exists and is NOT loaded yet (restoration case),
324+
// use the existing workflow instead of creating a new one.
325+
// If it IS loaded, this is a re-import case - create new with suffix.
326+
if (existingWorkflow?.isPersisted && !existingWorkflow.isLoaded) {
327+
const loadedWorkflow =
328+
await workflowStore.openWorkflow(existingWorkflow)
329+
loadedWorkflow.changeTracker.reset(workflowData)
330+
loadedWorkflow.changeTracker.restore()
331+
return
332+
}
333+
}
334+
335+
const tempWorkflow = workflowStore.createNewTemporary(
330336
path ? appendJsonExt(path) : undefined,
331337
workflowData
332338
)
333339
await workflowStore.openWorkflow(tempWorkflow)
334340
return
335341
}
336342

337-
// value is a ComfyWorkflow.
338343
const loadedWorkflow = await workflowStore.openWorkflow(value)
339344
loadedWorkflow.changeTracker.reset(workflowData)
340345
loadedWorkflow.changeTracker.restore()

src/platform/workflow/management/stores/workflowStore.ts

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ interface WorkflowStore {
172172
path?: string,
173173
workflowData?: ComfyWorkflowJSON
174174
) => ComfyWorkflow
175+
createNewTemporary: (
176+
path?: string,
177+
workflowData?: ComfyWorkflowJSON
178+
) => ComfyWorkflow
175179
renameWorkflow: (workflow: ComfyWorkflow, newPath: string) => Promise<void>
176180
deleteWorkflow: (workflow: ComfyWorkflow) => Promise<void>
177181
saveWorkflow: (workflow: ComfyWorkflow) => Promise<void>
@@ -365,25 +369,15 @@ export const useWorkflowStore = defineStore('workflow', () => {
365369
return workflow
366370
}
367371

368-
const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
369-
const fullPath = getUnconflictedPath(
370-
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
371-
)
372-
const existingWorkflow = workflows.value.find((w) => w.fullFilename == path)
373-
if (
374-
path &&
375-
workflowData &&
376-
existingWorkflow?.changeTracker &&
377-
!existingWorkflow.directory.startsWith(
378-
ComfyWorkflow.basePath.slice(0, -1)
379-
)
380-
) {
381-
existingWorkflow.changeTracker.reset(workflowData)
382-
return existingWorkflow
383-
}
384-
372+
/**
373+
* Helper to create a new temporary workflow
374+
*/
375+
const createNewWorkflow = (
376+
path: string,
377+
workflowData?: ComfyWorkflowJSON
378+
): ComfyWorkflow => {
385379
const workflow = new ComfyWorkflow({
386-
path: fullPath,
380+
path,
387381
modified: Date.now(),
388382
size: -1
389383
})
@@ -396,6 +390,47 @@ export const useWorkflowStore = defineStore('workflow', () => {
396390
return workflow
397391
}
398392

393+
/**
394+
* Create a temporary workflow, attempting to reuse an existing workflow if conditions match
395+
*/
396+
const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
397+
const fullPath = getUnconflictedPath(
398+
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
399+
)
400+
401+
// Try to reuse an existing loaded workflow with the same filename
402+
// that is not stored in the workflows directory
403+
if (path && workflowData) {
404+
const existingWorkflow = workflows.value.find(
405+
(w) => w.fullFilename === path
406+
)
407+
if (
408+
existingWorkflow?.changeTracker &&
409+
!existingWorkflow.directory.startsWith(
410+
ComfyWorkflow.basePath.slice(0, -1)
411+
)
412+
) {
413+
existingWorkflow.changeTracker.reset(workflowData)
414+
return existingWorkflow
415+
}
416+
}
417+
418+
return createNewWorkflow(fullPath, workflowData)
419+
}
420+
421+
/**
422+
* Create a new temporary workflow without attempting to reuse existing workflows
423+
*/
424+
const createNewTemporary = (
425+
path?: string,
426+
workflowData?: ComfyWorkflowJSON
427+
): ComfyWorkflow => {
428+
const fullPath = getUnconflictedPath(
429+
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
430+
)
431+
return createNewWorkflow(fullPath, workflowData)
432+
}
433+
399434
const closeWorkflow = async (workflow: ComfyWorkflow) => {
400435
openWorkflowPaths.value = openWorkflowPaths.value.filter(
401436
(path) => path !== workflow.path
@@ -777,6 +812,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
777812
isBusy,
778813
closeWorkflow,
779814
createTemporary,
815+
createNewTemporary,
780816
renameWorkflow,
781817
deleteWorkflow,
782818
saveAs,

0 commit comments

Comments
 (0)