mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-20 14:54:12 +00:00
[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)
This commit is contained in:
committed by
GitHub
parent
d50a2fabc0
commit
c6988380c2
@@ -310,23 +310,29 @@ export const useWorkflowService = () => {
|
||||
value: string | ComfyWorkflow | null,
|
||||
workflowData: ComfyWorkflowJSON
|
||||
) => {
|
||||
// Use workspaceStore here as it is patched in unit tests.
|
||||
const workflowStore = useWorkspaceStore().workflow
|
||||
if (typeof value === 'string') {
|
||||
const workflow = workflowStore.getWorkflowByPath(
|
||||
ComfyWorkflow.basePath + appendJsonExt(value)
|
||||
)
|
||||
if (workflow?.isPersisted) {
|
||||
const loadedWorkflow = await workflowStore.openWorkflow(workflow)
|
||||
loadedWorkflow.changeTracker.restore()
|
||||
loadedWorkflow.changeTracker.reset(workflowData)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (value === null || typeof value === 'string') {
|
||||
const path = value as string | null
|
||||
const tempWorkflow = workflowStore.createTemporary(
|
||||
|
||||
// Check if a persisted workflow with this path exists
|
||||
if (path) {
|
||||
const fullPath = ComfyWorkflow.basePath + appendJsonExt(path)
|
||||
const existingWorkflow = workflowStore.getWorkflowByPath(fullPath)
|
||||
|
||||
// If the workflow exists and is NOT loaded yet (restoration case),
|
||||
// use the existing workflow instead of creating a new one.
|
||||
// If it IS loaded, this is a re-import case - create new with suffix.
|
||||
if (existingWorkflow?.isPersisted && !existingWorkflow.isLoaded) {
|
||||
const loadedWorkflow =
|
||||
await workflowStore.openWorkflow(existingWorkflow)
|
||||
loadedWorkflow.changeTracker.reset(workflowData)
|
||||
loadedWorkflow.changeTracker.restore()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const tempWorkflow = workflowStore.createNewTemporary(
|
||||
path ? appendJsonExt(path) : undefined,
|
||||
workflowData
|
||||
)
|
||||
@@ -334,7 +340,6 @@ export const useWorkflowService = () => {
|
||||
return
|
||||
}
|
||||
|
||||
// value is a ComfyWorkflow.
|
||||
const loadedWorkflow = await workflowStore.openWorkflow(value)
|
||||
loadedWorkflow.changeTracker.reset(workflowData)
|
||||
loadedWorkflow.changeTracker.restore()
|
||||
|
||||
@@ -172,6 +172,10 @@ interface WorkflowStore {
|
||||
path?: string,
|
||||
workflowData?: ComfyWorkflowJSON
|
||||
) => ComfyWorkflow
|
||||
createNewTemporary: (
|
||||
path?: string,
|
||||
workflowData?: ComfyWorkflowJSON
|
||||
) => ComfyWorkflow
|
||||
renameWorkflow: (workflow: ComfyWorkflow, newPath: string) => Promise<void>
|
||||
deleteWorkflow: (workflow: ComfyWorkflow) => Promise<void>
|
||||
saveWorkflow: (workflow: ComfyWorkflow) => Promise<void>
|
||||
@@ -365,25 +369,15 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
return workflow
|
||||
}
|
||||
|
||||
const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
|
||||
const fullPath = getUnconflictedPath(
|
||||
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
|
||||
)
|
||||
const existingWorkflow = workflows.value.find((w) => w.fullFilename == path)
|
||||
if (
|
||||
path &&
|
||||
workflowData &&
|
||||
existingWorkflow?.changeTracker &&
|
||||
!existingWorkflow.directory.startsWith(
|
||||
ComfyWorkflow.basePath.slice(0, -1)
|
||||
)
|
||||
) {
|
||||
existingWorkflow.changeTracker.reset(workflowData)
|
||||
return existingWorkflow
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a new temporary workflow
|
||||
*/
|
||||
const createNewWorkflow = (
|
||||
path: string,
|
||||
workflowData?: ComfyWorkflowJSON
|
||||
): ComfyWorkflow => {
|
||||
const workflow = new ComfyWorkflow({
|
||||
path: fullPath,
|
||||
path,
|
||||
modified: Date.now(),
|
||||
size: -1
|
||||
})
|
||||
@@ -396,6 +390,47 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
return workflow
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary workflow, attempting to reuse an existing workflow if conditions match
|
||||
*/
|
||||
const createTemporary = (path?: string, workflowData?: ComfyWorkflowJSON) => {
|
||||
const fullPath = getUnconflictedPath(
|
||||
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
|
||||
)
|
||||
|
||||
// Try to reuse an existing loaded workflow with the same filename
|
||||
// that is not stored in the workflows directory
|
||||
if (path && workflowData) {
|
||||
const existingWorkflow = workflows.value.find(
|
||||
(w) => w.fullFilename === path
|
||||
)
|
||||
if (
|
||||
existingWorkflow?.changeTracker &&
|
||||
!existingWorkflow.directory.startsWith(
|
||||
ComfyWorkflow.basePath.slice(0, -1)
|
||||
)
|
||||
) {
|
||||
existingWorkflow.changeTracker.reset(workflowData)
|
||||
return existingWorkflow
|
||||
}
|
||||
}
|
||||
|
||||
return createNewWorkflow(fullPath, workflowData)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new temporary workflow without attempting to reuse existing workflows
|
||||
*/
|
||||
const createNewTemporary = (
|
||||
path?: string,
|
||||
workflowData?: ComfyWorkflowJSON
|
||||
): ComfyWorkflow => {
|
||||
const fullPath = getUnconflictedPath(
|
||||
ComfyWorkflow.basePath + (path ?? 'Unsaved Workflow.json')
|
||||
)
|
||||
return createNewWorkflow(fullPath, workflowData)
|
||||
}
|
||||
|
||||
const closeWorkflow = async (workflow: ComfyWorkflow) => {
|
||||
openWorkflowPaths.value = openWorkflowPaths.value.filter(
|
||||
(path) => path !== workflow.path
|
||||
@@ -777,6 +812,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
isBusy,
|
||||
closeWorkflow,
|
||||
createTemporary,
|
||||
createNewTemporary,
|
||||
renameWorkflow,
|
||||
deleteWorkflow,
|
||||
saveAs,
|
||||
|
||||
Reference in New Issue
Block a user