mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-22 15:29:44 +00:00
feat: App mode empty graph handling (#9393)
## Summary Adds handling for entering app mode with an empty graph prompting the user to load a template as a starting point ## Changes - **What**: - app mode handle empty workflows, disable builder button, show different message - fix fitView when switching from app mode to graph ## Review Focus Moving the fitView since the canvas is hidden in app mode until after the workflow is loaded and the mode has been switched back to graph, I don't see how this could cause any issues but worth a closer eye ## Screenshots (if applicable) <img width="1057" height="916" alt="image" src="https://github.com/user-attachments/assets/2ffe2b6d-9ce1-4218-828a-b7bc336c365a" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9393-feat-App-mode-empty-graph-handling-3196d73d3650812cab0ce878109ed5c9) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -130,8 +130,8 @@ describe('appModeStore', () => {
|
||||
})
|
||||
|
||||
describe('empty workflow dialog callbacks', () => {
|
||||
function getDialogOptions() {
|
||||
vi.mocked(app.rootGraph).nodes = []
|
||||
function getDialogOptions(nodes: LGraphNode[] = []) {
|
||||
vi.mocked(app.rootGraph).nodes = nodes
|
||||
workflowStore.activeWorkflow = createBuilderWorkflow('graph')
|
||||
store.enterBuilder()
|
||||
return mockEmptyWorkflowDialog.lastOptions
|
||||
@@ -149,10 +149,7 @@ describe('appModeStore', () => {
|
||||
})
|
||||
|
||||
it('onEnterBuilder enters builder when nodes exist', () => {
|
||||
const options = getDialogOptions()
|
||||
|
||||
// Simulate template having loaded nodes
|
||||
vi.mocked(app.rootGraph).nodes = [{ id: 1 } as LGraphNode]
|
||||
const options = getDialogOptions([{ id: 1 } as LGraphNode])
|
||||
|
||||
options.onEnterBuilder()
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@ export const useAppModeStore = defineStore('appMode', () => {
|
||||
const selectedInputs = reactive<[NodeId, string][]>([])
|
||||
const selectedOutputs = reactive<NodeId[]>([])
|
||||
const hasOutputs = computed(() => !!selectedOutputs.length)
|
||||
const hasNodes = computed(() => {
|
||||
// Nodes are not reactive, so trigger recomputation when workflow changes
|
||||
void workflowStore.activeWorkflow
|
||||
void mode.value
|
||||
return !!app.rootGraph?.nodes?.length
|
||||
})
|
||||
|
||||
function loadSelections(data: Partial<LinearData> | undefined) {
|
||||
const rawInputs = data?.inputs ?? []
|
||||
@@ -91,7 +97,7 @@ export const useAppModeStore = defineStore('appMode', () => {
|
||||
})
|
||||
|
||||
function enterBuilder() {
|
||||
if (!app.rootGraph?.nodes?.length) {
|
||||
if (!hasNodes.value) {
|
||||
emptyWorkflowDialog.show({
|
||||
onEnterBuilder: () => enterBuilder(),
|
||||
onDismiss: () => setMode('graph')
|
||||
@@ -114,6 +120,7 @@ export const useAppModeStore = defineStore('appMode', () => {
|
||||
return {
|
||||
enterBuilder,
|
||||
exitBuilder,
|
||||
hasNodes,
|
||||
hasOutputs,
|
||||
resetSelectedToWorkflow,
|
||||
selectedInputs,
|
||||
|
||||
Reference in New Issue
Block a user