mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 18:52:19 +00:00
Add enterAppBuilder method for skipping arrange mode (#9310)
## Summary When already in app mode and entering builder with outputs defined, skip the select step and go straight to arrange ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9310-Add-enterAppBuilder-method-for-skipping-arrange-mode-3156d73d36508101903ff434a2a1ac08) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -9,11 +9,13 @@ import { useCommandStore } from '@/stores/commandStore'
|
|||||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||||
import { cn } from '@/utils/tailwindUtil'
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
import { useAppMode } from '@/composables/useAppMode'
|
import { useAppMode } from '@/composables/useAppMode'
|
||||||
|
import { useAppModeStore } from '@/stores/appModeStore'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const commandStore = useCommandStore()
|
const commandStore = useCommandStore()
|
||||||
const workspaceStore = useWorkspaceStore()
|
const workspaceStore = useWorkspaceStore()
|
||||||
const { enableAppBuilder, setMode } = useAppMode()
|
const { enableAppBuilder } = useAppMode()
|
||||||
|
const { enterBuilder } = useAppModeStore()
|
||||||
const tooltipOptions = { showDelay: 300, hideDelay: 300 }
|
const tooltipOptions = { showDelay: 300, hideDelay: 300 }
|
||||||
|
|
||||||
const isAssetsActive = computed(
|
const isAssetsActive = computed(
|
||||||
@@ -23,10 +25,6 @@ const isWorkflowsActive = computed(
|
|||||||
() => workspaceStore.sidebarTab.activeSidebarTab?.id === 'workflows'
|
() => workspaceStore.sidebarTab.activeSidebarTab?.id === 'workflows'
|
||||||
)
|
)
|
||||||
|
|
||||||
function enterBuilderMode() {
|
|
||||||
setMode('builder:select')
|
|
||||||
}
|
|
||||||
|
|
||||||
function openAssets() {
|
function openAssets() {
|
||||||
void commandStore.execute('Workspace.ToggleSidebarTab.assets')
|
void commandStore.execute('Workspace.ToggleSidebarTab.assets')
|
||||||
}
|
}
|
||||||
@@ -75,7 +73,7 @@ function openTemplates() {
|
|||||||
size="unset"
|
size="unset"
|
||||||
:aria-label="t('linearMode.appModeToolbar.appBuilder')"
|
:aria-label="t('linearMode.appModeToolbar.appBuilder')"
|
||||||
class="size-10 rounded-lg"
|
class="size-10 rounded-lg"
|
||||||
@click="enterBuilderMode"
|
@click="enterBuilder"
|
||||||
>
|
>
|
||||||
<i class="icon-[lucide--hammer] size-4" />
|
<i class="icon-[lucide--hammer] size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import { storeToRefs } from 'pinia'
|
|||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { setMode } = useAppMode()
|
const { setMode } = useAppMode()
|
||||||
const { hasOutputs } = storeToRefs(useAppModeStore())
|
const appModeStore = useAppModeStore()
|
||||||
|
const { hasOutputs } = storeToRefs(appModeStore)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -44,7 +45,7 @@ const { hasOutputs } = storeToRefs(useAppModeStore())
|
|||||||
<Button variant="textonly" size="lg" @click="setMode('graph')">
|
<Button variant="textonly" size="lg" @click="setMode('graph')">
|
||||||
{{ t('linearMode.welcome.backToWorkflow') }}
|
{{ t('linearMode.welcome.backToWorkflow') }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="primary" size="lg" @click="setMode('builder:select')">
|
<Button variant="primary" size="lg" @click="appModeStore.enterBuilder()">
|
||||||
<i class="icon-[lucide--hammer]" />
|
<i class="icon-[lucide--hammer]" />
|
||||||
{{ t('linearMode.welcome.buildApp') }}
|
{{ t('linearMode.welcome.buildApp') }}
|
||||||
<div
|
<div
|
||||||
|
|||||||
90
src/stores/appModeStore.test.ts
Normal file
90
src/stores/appModeStore.test.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import { createPinia, setActivePinia } from 'pinia'
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
import type { AppMode } from '@/composables/useAppMode'
|
||||||
|
|
||||||
|
import { useAppModeStore } from '@/stores/appModeStore'
|
||||||
|
|
||||||
|
const modeRef = ref<AppMode>('graph')
|
||||||
|
const mockSetMode = vi.fn()
|
||||||
|
|
||||||
|
vi.mock('@/composables/useAppMode', () => ({
|
||||||
|
useAppMode: () => ({
|
||||||
|
mode: computed(() => modeRef.value),
|
||||||
|
setMode: mockSetMode,
|
||||||
|
isBuilderMode: computed(
|
||||||
|
() =>
|
||||||
|
modeRef.value === 'builder:select' ||
|
||||||
|
modeRef.value === 'builder:arrange'
|
||||||
|
),
|
||||||
|
isAppMode: computed(
|
||||||
|
() => modeRef.value === 'app' || modeRef.value === 'builder:arrange'
|
||||||
|
),
|
||||||
|
isSelectMode: computed(() => modeRef.value === 'builder:select'),
|
||||||
|
isArrangeMode: computed(() => modeRef.value === 'builder:arrange'),
|
||||||
|
isGraphMode: computed(
|
||||||
|
() => modeRef.value === 'graph' || modeRef.value === 'builder:select'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/renderer/core/canvas/canvasStore', () => ({
|
||||||
|
useCanvasStore: () => ({
|
||||||
|
getCanvas: () => ({ read_only: false })
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
|
||||||
|
useWorkflowStore: () => ({
|
||||||
|
activeWorkflow: null
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('appModeStore', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setActivePinia(createPinia())
|
||||||
|
modeRef.value = 'graph'
|
||||||
|
mockSetMode.mockClear()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('enterBuilder', () => {
|
||||||
|
it('navigates to builder:arrange when in app mode with outputs', () => {
|
||||||
|
modeRef.value = 'app'
|
||||||
|
const store = useAppModeStore()
|
||||||
|
store.selectedOutputs.push('1')
|
||||||
|
|
||||||
|
store.enterBuilder()
|
||||||
|
|
||||||
|
expect(mockSetMode).toHaveBeenCalledWith('builder:arrange')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('navigates to builder:select when in app mode without outputs', () => {
|
||||||
|
modeRef.value = 'app'
|
||||||
|
const store = useAppModeStore()
|
||||||
|
|
||||||
|
store.enterBuilder()
|
||||||
|
|
||||||
|
expect(mockSetMode).toHaveBeenCalledWith('builder:select')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('navigates to builder:select when in graph mode with outputs', () => {
|
||||||
|
modeRef.value = 'graph'
|
||||||
|
const store = useAppModeStore()
|
||||||
|
store.selectedOutputs.push('1')
|
||||||
|
|
||||||
|
store.enterBuilder()
|
||||||
|
|
||||||
|
expect(mockSetMode).toHaveBeenCalledWith('builder:select')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('navigates to builder:select when in graph mode without outputs', () => {
|
||||||
|
modeRef.value = 'graph'
|
||||||
|
const store = useAppModeStore()
|
||||||
|
|
||||||
|
store.enterBuilder()
|
||||||
|
|
||||||
|
expect(mockSetMode).toHaveBeenCalledWith('builder:select')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -66,6 +66,14 @@ export const useAppModeStore = defineStore('appMode', () => {
|
|||||||
(inSelect) => (getCanvas().read_only = inSelect)
|
(inSelect) => (getCanvas().read_only = inSelect)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function enterBuilder() {
|
||||||
|
setMode(
|
||||||
|
mode.value === 'app' && hasOutputs.value
|
||||||
|
? 'builder:arrange'
|
||||||
|
: 'builder:select'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async function exitBuilder() {
|
async function exitBuilder() {
|
||||||
const workflow = workflowStore.activeWorkflow
|
const workflow = workflowStore.activeWorkflow
|
||||||
if (workflow) workflow.dirtyLinearData = null
|
if (workflow) workflow.dirtyLinearData = null
|
||||||
@@ -74,6 +82,7 @@ export const useAppModeStore = defineStore('appMode', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
enterBuilder,
|
||||||
exitBuilder,
|
exitBuilder,
|
||||||
hasOutputs,
|
hasOutputs,
|
||||||
flushSelections,
|
flushSelections,
|
||||||
|
|||||||
Reference in New Issue
Block a user