mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 10:59:53 +00:00
Expose dialogService to extensionManager (#2113)
This commit is contained in:
20
README.md
20
README.md
@@ -229,6 +229,26 @@ https://github.com/user-attachments/assets/c142c43f-2fe9-4030-8196-b3bfd4c6977d
|
||||
|
||||
### Developer APIs
|
||||
|
||||
<details>
|
||||
<summary>v1.6.13: Prompt dialog</summary>
|
||||
|
||||
`window.prompt` is not available in ComfyUI desktop's electron environment. Please use the following API to show a prompt dialog.
|
||||
|
||||
```js
|
||||
window['app'].extensionManager.dialog
|
||||
.prompt({
|
||||
title: 'Test Prompt',
|
||||
message: 'Test Prompt Message'
|
||||
})
|
||||
.then((value: string) => {
|
||||
// Do something with the value user entered
|
||||
})
|
||||
```
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>v1.3.34: Register about panel badges</summary>
|
||||
|
||||
|
||||
@@ -158,4 +158,24 @@ test.describe('Topbar commands', () => {
|
||||
expect(await badge.textContent()).toContain('Test Badge')
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Dialog', () => {
|
||||
test('Should allow showing a prompt dialog', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].extensionManager.dialog
|
||||
.prompt({
|
||||
title: 'Test Prompt',
|
||||
message: 'Test Prompt Message'
|
||||
})
|
||||
.then((value: string) => {
|
||||
window['value'] = value
|
||||
})
|
||||
})
|
||||
|
||||
await comfyPage.fillPromptDialog('Hello, world!')
|
||||
expect(await comfyPage.page.evaluate(() => window['value'])).toBe(
|
||||
'Hello, world!'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -530,6 +530,13 @@ export class ComfyPage {
|
||||
return this.page.locator('.p-dialog-content input[type="text"]')
|
||||
}
|
||||
|
||||
async fillPromptDialog(value: string) {
|
||||
await this.promptDialogInput.fill(value)
|
||||
await this.page.keyboard.press('Enter')
|
||||
await this.promptDialogInput.waitFor({ state: 'hidden' })
|
||||
await this.nextFrame()
|
||||
}
|
||||
|
||||
async disconnectEdge() {
|
||||
await this.dragAndDrop(this.clipTextEncodeNode1InputSlot, this.emptySpace)
|
||||
}
|
||||
@@ -797,9 +804,7 @@ export class ComfyPage {
|
||||
await this.canvas.press('Control+a')
|
||||
const node = await this.getFirstNodeRef()
|
||||
await node!.clickContextMenuOption('Convert to Group Node')
|
||||
await this.promptDialogInput.fill(groupNodeName)
|
||||
await this.page.keyboard.press('Enter')
|
||||
await this.promptDialogInput.waitFor({ state: 'hidden' })
|
||||
await this.fillPromptDialog(groupNodeName)
|
||||
await this.nextFrame()
|
||||
}
|
||||
|
||||
|
||||
@@ -235,9 +235,7 @@ export class NodeReference {
|
||||
}
|
||||
async convertToGroupNode(groupNodeName: string = 'GroupNode') {
|
||||
await this.clickContextMenuOption('Convert to Group Node')
|
||||
await this.comfyPage.promptDialogInput.fill(groupNodeName)
|
||||
await this.comfyPage.page.keyboard.press('Enter')
|
||||
await this.comfyPage.promptDialogInput.waitFor({ state: 'hidden' })
|
||||
await this.comfyPage.fillPromptDialog(groupNodeName)
|
||||
await this.comfyPage.nextFrame()
|
||||
const nodes = await this.comfyPage.getNodeRefsByType(
|
||||
`workflow>${groupNodeName}`
|
||||
|
||||
@@ -115,7 +115,7 @@ import { electronAPI as getElectronAPI, isElectron } from '@/utils/envUtil'
|
||||
label: 'Reinstall',
|
||||
icon: 'pi pi-refresh',
|
||||
async function() {
|
||||
const proceed = await useDialogService().showConfirmationDialog({
|
||||
const proceed = await useDialogService().confirm({
|
||||
message: t('desktopMenu.confirmReinstall'),
|
||||
title: t('desktopMenu.reinstall'),
|
||||
type: 'reinstall'
|
||||
|
||||
@@ -79,7 +79,7 @@ class GroupNodeBuilder {
|
||||
}
|
||||
|
||||
async getName() {
|
||||
const name = await useDialogService().showPromptDialog({
|
||||
const name = await useDialogService().prompt({
|
||||
title: t('groupNode.create'),
|
||||
message: t('groupNode.enterName'),
|
||||
defaultValue: ''
|
||||
|
||||
@@ -353,7 +353,7 @@ app.registerExtension({
|
||||
content: `Save Selected as Template`,
|
||||
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
|
||||
callback: async () => {
|
||||
const name = await useDialogService().showPromptDialog({
|
||||
const name = await useDialogService().prompt({
|
||||
title: t('nodeTemplates.saveAsTemplate'),
|
||||
message: t('nodeTemplates.enterName'),
|
||||
defaultValue: ''
|
||||
|
||||
@@ -84,7 +84,7 @@ export const useDialogService = () => {
|
||||
})
|
||||
}
|
||||
|
||||
async function showPromptDialog({
|
||||
async function prompt({
|
||||
title,
|
||||
message,
|
||||
defaultValue = ''
|
||||
@@ -119,7 +119,7 @@ export const useDialogService = () => {
|
||||
* `false` if denied (e.g. no in yes/no/cancel), or
|
||||
* `null` if the dialog is cancelled or closed
|
||||
*/
|
||||
async function showConfirmationDialog({
|
||||
async function confirm({
|
||||
title,
|
||||
type,
|
||||
message,
|
||||
@@ -161,7 +161,7 @@ export const useDialogService = () => {
|
||||
showAboutDialog,
|
||||
showExecutionErrorDialog,
|
||||
showTemplateWorkflowsDialog,
|
||||
showPromptDialog,
|
||||
showConfirmationDialog
|
||||
prompt,
|
||||
confirm
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export const useWorkflowService = () => {
|
||||
|
||||
async function getFilename(defaultName: string): Promise<string | null> {
|
||||
if (settingStore.get('Comfy.PromptFilename')) {
|
||||
let filename = await dialogService.showPromptDialog({
|
||||
let filename = await dialogService.prompt({
|
||||
title: t('workflowService.exportWorkflow'),
|
||||
message: t('workflowService.enterFilename') + ':',
|
||||
defaultValue: defaultName
|
||||
@@ -60,7 +60,7 @@ export const useWorkflowService = () => {
|
||||
* @param workflow The workflow to save
|
||||
*/
|
||||
const saveWorkflowAs = async (workflow: ComfyWorkflow) => {
|
||||
const newFilename = await dialogService.showPromptDialog({
|
||||
const newFilename = await dialogService.prompt({
|
||||
title: t('workflowService.saveWorkflow'),
|
||||
message: t('workflowService.enterFilename') + ':',
|
||||
defaultValue: workflow.filename
|
||||
@@ -72,7 +72,7 @@ export const useWorkflowService = () => {
|
||||
const existingWorkflow = workflowStore.getWorkflowByPath(newPath)
|
||||
|
||||
if (existingWorkflow && !existingWorkflow.isTemporary) {
|
||||
const res = await dialogService.showConfirmationDialog({
|
||||
const res = await dialogService.confirm({
|
||||
title: t('sideToolbar.workflowTab.confirmOverwriteTitle'),
|
||||
type: 'overwrite',
|
||||
message: t('sideToolbar.workflowTab.confirmOverwrite'),
|
||||
@@ -181,7 +181,7 @@ export const useWorkflowService = () => {
|
||||
}
|
||||
|
||||
if (workflow.isModified && options.warnIfUnsaved) {
|
||||
const confirmed = await dialogService.showConfirmationDialog({
|
||||
const confirmed = await dialogService.confirm({
|
||||
title: t('sideToolbar.workflowTab.dirtyCloseTitle'),
|
||||
type: 'dirtyClose',
|
||||
message: t('sideToolbar.workflowTab.dirtyClose'),
|
||||
@@ -225,7 +225,7 @@ export const useWorkflowService = () => {
|
||||
let confirmed: boolean | null = bypassConfirm || silent
|
||||
|
||||
if (!confirmed) {
|
||||
confirmed = await dialogService.showConfirmationDialog({
|
||||
confirmed = await dialogService.confirm({
|
||||
title: t('sideToolbar.workflowTab.confirmDeleteTitle'),
|
||||
type: 'delete',
|
||||
message: t('sideToolbar.workflowTab.confirmDelete'),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useColorPaletteService } from '@/services/colorPaletteService'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import type { SidebarTabExtension, ToastManager } from '@/types/extensionTypes'
|
||||
|
||||
import { useCommandStore } from './commandStore'
|
||||
@@ -34,6 +35,7 @@ export const useWorkspaceStore = defineStore('workspace', () => {
|
||||
}))
|
||||
const workflow = computed(() => useWorkflowStore())
|
||||
const colorPalette = useColorPaletteService()
|
||||
const dialog = useDialogService()
|
||||
|
||||
/**
|
||||
* Registers a sidebar tab.
|
||||
@@ -76,6 +78,7 @@ export const useWorkspaceStore = defineStore('workspace', () => {
|
||||
setting,
|
||||
workflow,
|
||||
colorPalette,
|
||||
dialog,
|
||||
|
||||
registerSidebarTab,
|
||||
unregisterSidebarTab,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component } from 'vue'
|
||||
|
||||
import type { useDialogService } from '@/services/dialogService'
|
||||
import type { ComfyCommand } from '@/stores/commandStore'
|
||||
|
||||
export interface BaseSidebarTabExtension {
|
||||
@@ -102,6 +103,7 @@ export interface ExtensionManager {
|
||||
getSidebarTabs(): SidebarTabExtension[]
|
||||
|
||||
toast: ToastManager
|
||||
dialog: ReturnType<typeof useDialogService>
|
||||
command: CommandManager
|
||||
setting: {
|
||||
get: (id: string) => any
|
||||
|
||||
Reference in New Issue
Block a user