mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-28 10:44:12 +00:00
[Refactor] Convert dialogService to composable (#2058)
This commit is contained in:
@@ -1,117 +1,15 @@
|
||||
// This module is mocked in tests-ui/
|
||||
// Import vue components here to avoid tests-ui/ reporting errors
|
||||
// about importing primevue components.
|
||||
import { useDialogStore, type ShowDialogOptions } from '@/stores/dialogStore'
|
||||
import type { ExecutionErrorWsMessage } from '@/types/apiTypes'
|
||||
import type { MissingNodeType } from '@/types/comfy'
|
||||
import LoadWorkflowWarning from '@/components/dialog/content/LoadWorkflowWarning.vue'
|
||||
import MissingModelsWarning from '@/components/dialog/content/MissingModelsWarning.vue'
|
||||
import SettingDialogContent from '@/components/dialog/content/SettingDialogContent.vue'
|
||||
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
|
||||
import type { ExecutionErrorWsMessage } from '@/types/apiTypes'
|
||||
import ExecutionErrorDialogContent from '@/components/dialog/content/ExecutionErrorDialogContent.vue'
|
||||
import TemplateWorkflowsContent from '@/components/templates/TemplateWorkflowsContent.vue'
|
||||
import PromptDialogContent from '@/components/dialog/content/PromptDialogContent.vue'
|
||||
import ConfirmationDialogContent from '@/components/dialog/content/ConfirmationDialogContent.vue'
|
||||
import { t } from '@/i18n'
|
||||
import type { MissingNodeType } from '@/types/comfy'
|
||||
|
||||
export function showLoadWorkflowWarning(props: {
|
||||
missingNodeTypes: MissingNodeType[]
|
||||
[key: string]: any
|
||||
}) {
|
||||
const dialogStore = useDialogStore()
|
||||
dialogStore.showDialog({
|
||||
key: 'global-load-workflow-warning',
|
||||
component: LoadWorkflowWarning,
|
||||
props
|
||||
})
|
||||
}
|
||||
|
||||
export function showMissingModelsWarning(props: {
|
||||
missingModels: any[]
|
||||
paths: Record<string, string[]>
|
||||
[key: string]: any
|
||||
}) {
|
||||
const dialogStore = useDialogStore()
|
||||
dialogStore.showDialog({
|
||||
key: 'global-missing-models-warning',
|
||||
component: MissingModelsWarning,
|
||||
props
|
||||
})
|
||||
}
|
||||
|
||||
export function showSettingsDialog(
|
||||
panel?: 'about' | 'keybinding' | 'extension' | 'server-config'
|
||||
) {
|
||||
const props = panel ? { props: { defaultPanel: panel } } : undefined
|
||||
|
||||
useDialogStore().showDialog({
|
||||
key: 'global-settings',
|
||||
headerComponent: SettingDialogHeader,
|
||||
component: SettingDialogContent,
|
||||
...props
|
||||
})
|
||||
}
|
||||
|
||||
export function showAboutDialog() {
|
||||
useDialogStore().showDialog({
|
||||
key: 'global-settings',
|
||||
headerComponent: SettingDialogHeader,
|
||||
component: SettingDialogContent,
|
||||
props: {
|
||||
defaultPanel: 'about'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function showExecutionErrorDialog(error: ExecutionErrorWsMessage) {
|
||||
useDialogStore().showDialog({
|
||||
key: 'global-execution-error',
|
||||
component: ExecutionErrorDialogContent,
|
||||
props: {
|
||||
error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function showTemplateWorkflowsDialog() {
|
||||
useDialogStore().showDialog({
|
||||
key: 'global-template-workflows',
|
||||
title: t('templateWorkflows.title'),
|
||||
component: TemplateWorkflowsContent
|
||||
})
|
||||
}
|
||||
|
||||
export async function showPromptDialog({
|
||||
title,
|
||||
message,
|
||||
defaultValue = ''
|
||||
}: {
|
||||
title: string
|
||||
message: string
|
||||
defaultValue?: string
|
||||
}): Promise<string | null> {
|
||||
const dialogStore = useDialogStore()
|
||||
|
||||
return new Promise((resolve) => {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-prompt',
|
||||
title,
|
||||
component: PromptDialogContent,
|
||||
props: {
|
||||
message,
|
||||
defaultValue,
|
||||
onConfirm: (value: string) => {
|
||||
resolve(value)
|
||||
}
|
||||
},
|
||||
dialogComponentProps: {
|
||||
onClose: () => {
|
||||
resolve(null)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export type ConfirmationDialogType =
|
||||
| 'overwrite'
|
||||
@@ -119,43 +17,151 @@ export type ConfirmationDialogType =
|
||||
| 'dirtyClose'
|
||||
| 'reinstall'
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns `true` if the user confirms the dialog,
|
||||
* `false` if denied (e.g. no in yes/no/cancel), or
|
||||
* `null` if the dialog is cancelled or closed
|
||||
*/
|
||||
export async function showConfirmationDialog({
|
||||
title,
|
||||
type,
|
||||
message,
|
||||
itemList = []
|
||||
}: {
|
||||
/** Dialog heading */
|
||||
title: string
|
||||
/** Pre-configured dialog type */
|
||||
type: ConfirmationDialogType
|
||||
/** The main message body */
|
||||
message: string
|
||||
/** Displayed as an unorderd list immediately below the message body */
|
||||
itemList?: string[]
|
||||
}): Promise<boolean | null> {
|
||||
return new Promise((resolve) => {
|
||||
const options: ShowDialogOptions = {
|
||||
key: 'global-prompt',
|
||||
title,
|
||||
component: ConfirmationDialogContent,
|
||||
props: {
|
||||
message,
|
||||
type,
|
||||
itemList,
|
||||
onConfirm: resolve
|
||||
},
|
||||
dialogComponentProps: {
|
||||
onClose: () => resolve(null)
|
||||
}
|
||||
}
|
||||
export const useDialogService = () => {
|
||||
const dialogStore = useDialogStore()
|
||||
function showLoadWorkflowWarning(props: {
|
||||
missingNodeTypes: MissingNodeType[]
|
||||
[key: string]: any
|
||||
}) {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-load-workflow-warning',
|
||||
component: LoadWorkflowWarning,
|
||||
props
|
||||
})
|
||||
}
|
||||
|
||||
useDialogStore().showDialog(options)
|
||||
})
|
||||
function showMissingModelsWarning(props: {
|
||||
missingModels: any[]
|
||||
paths: Record<string, string[]>
|
||||
[key: string]: any
|
||||
}) {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-missing-models-warning',
|
||||
component: MissingModelsWarning,
|
||||
props
|
||||
})
|
||||
}
|
||||
|
||||
function showSettingsDialog(
|
||||
panel?: 'about' | 'keybinding' | 'extension' | 'server-config'
|
||||
) {
|
||||
const props = panel ? { props: { defaultPanel: panel } } : undefined
|
||||
|
||||
dialogStore.showDialog({
|
||||
key: 'global-settings',
|
||||
headerComponent: SettingDialogHeader,
|
||||
component: SettingDialogContent,
|
||||
...props
|
||||
})
|
||||
}
|
||||
|
||||
function showAboutDialog() {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-settings',
|
||||
headerComponent: SettingDialogHeader,
|
||||
component: SettingDialogContent,
|
||||
props: {
|
||||
defaultPanel: 'about'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showExecutionErrorDialog(error: ExecutionErrorWsMessage) {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-execution-error',
|
||||
component: ExecutionErrorDialogContent,
|
||||
props: {
|
||||
error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showTemplateWorkflowsDialog() {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-template-workflows',
|
||||
title: t('templateWorkflows.title'),
|
||||
component: TemplateWorkflowsContent
|
||||
})
|
||||
}
|
||||
|
||||
async function showPromptDialog({
|
||||
title,
|
||||
message,
|
||||
defaultValue = ''
|
||||
}: {
|
||||
title: string
|
||||
message: string
|
||||
defaultValue?: string
|
||||
}): Promise<string | null> {
|
||||
return new Promise((resolve) => {
|
||||
dialogStore.showDialog({
|
||||
key: 'global-prompt',
|
||||
title,
|
||||
component: PromptDialogContent,
|
||||
props: {
|
||||
message,
|
||||
defaultValue,
|
||||
onConfirm: (value: string) => {
|
||||
resolve(value)
|
||||
}
|
||||
},
|
||||
dialogComponentProps: {
|
||||
onClose: () => {
|
||||
resolve(null)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns `true` if the user confirms the dialog,
|
||||
* `false` if denied (e.g. no in yes/no/cancel), or
|
||||
* `null` if the dialog is cancelled or closed
|
||||
*/
|
||||
async function showConfirmationDialog({
|
||||
title,
|
||||
type,
|
||||
message,
|
||||
itemList = []
|
||||
}: {
|
||||
/** Dialog heading */
|
||||
title: string
|
||||
/** Pre-configured dialog type */
|
||||
type: ConfirmationDialogType
|
||||
/** The main message body */
|
||||
message: string
|
||||
/** Displayed as an unorderd list immediately below the message body */
|
||||
itemList?: string[]
|
||||
}): Promise<boolean | null> {
|
||||
return new Promise((resolve) => {
|
||||
const options: ShowDialogOptions = {
|
||||
key: 'global-prompt',
|
||||
title,
|
||||
component: ConfirmationDialogContent,
|
||||
props: {
|
||||
message,
|
||||
type,
|
||||
itemList,
|
||||
onConfirm: resolve
|
||||
},
|
||||
dialogComponentProps: {
|
||||
onClose: () => resolve(null)
|
||||
}
|
||||
}
|
||||
|
||||
dialogStore.showDialog(options)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
showLoadWorkflowWarning,
|
||||
showMissingModelsWarning,
|
||||
showSettingsDialog,
|
||||
showAboutDialog,
|
||||
showExecutionErrorDialog,
|
||||
showTemplateWorkflowsDialog,
|
||||
showPromptDialog,
|
||||
showConfirmationDialog
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { downloadBlob } from '@/scripts/utils'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
import { useWorkflowStore, ComfyWorkflow } from '@/stores/workflowStore'
|
||||
import { showConfirmationDialog, showPromptDialog } from './dialogService'
|
||||
import { useDialogService } from './dialogService'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { LGraphCanvas } from '@comfyorg/litegraph'
|
||||
@@ -16,10 +16,11 @@ export const useWorkflowService = () => {
|
||||
const settingStore = useSettingStore()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const toastStore = useToastStore()
|
||||
const dialogService = useDialogService()
|
||||
|
||||
async function getFilename(defaultName: string): Promise<string | null> {
|
||||
if (settingStore.get('Comfy.PromptFilename')) {
|
||||
let filename = await showPromptDialog({
|
||||
let filename = await dialogService.showPromptDialog({
|
||||
title: t('workflowService.exportWorkflow'),
|
||||
message: t('workflowService.enterFilename') + ':',
|
||||
defaultValue: defaultName
|
||||
@@ -57,7 +58,7 @@ export const useWorkflowService = () => {
|
||||
* @param workflow The workflow to save
|
||||
*/
|
||||
const saveWorkflowAs = async (workflow: ComfyWorkflow) => {
|
||||
const newFilename = await showPromptDialog({
|
||||
const newFilename = await dialogService.showPromptDialog({
|
||||
title: t('workflowService.saveWorkflow'),
|
||||
message: t('workflowService.enterFilename') + ':',
|
||||
defaultValue: workflow.filename
|
||||
@@ -69,7 +70,7 @@ export const useWorkflowService = () => {
|
||||
const existingWorkflow = workflowStore.getWorkflowByPath(newPath)
|
||||
|
||||
if (existingWorkflow && !existingWorkflow.isTemporary) {
|
||||
const res = await showConfirmationDialog({
|
||||
const res = await dialogService.showConfirmationDialog({
|
||||
title: t('sideToolbar.workflowTab.confirmOverwriteTitle'),
|
||||
type: 'overwrite',
|
||||
message: t('sideToolbar.workflowTab.confirmOverwrite'),
|
||||
@@ -178,7 +179,7 @@ export const useWorkflowService = () => {
|
||||
}
|
||||
|
||||
if (workflow.isModified && options.warnIfUnsaved) {
|
||||
const confirmed = await showConfirmationDialog({
|
||||
const confirmed = await dialogService.showConfirmationDialog({
|
||||
title: t('sideToolbar.workflowTab.dirtyCloseTitle'),
|
||||
type: 'dirtyClose',
|
||||
message: t('sideToolbar.workflowTab.dirtyClose'),
|
||||
@@ -222,7 +223,7 @@ export const useWorkflowService = () => {
|
||||
let confirmed: boolean | null = bypassConfirm || silent
|
||||
|
||||
if (!confirmed) {
|
||||
confirmed = await showConfirmationDialog({
|
||||
confirmed = await dialogService.showConfirmationDialog({
|
||||
title: t('sideToolbar.workflowTab.confirmDeleteTitle'),
|
||||
type: 'delete',
|
||||
message: t('sideToolbar.workflowTab.confirmDelete'),
|
||||
|
||||
Reference in New Issue
Block a user