Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/builder/useEmptyWorkflowDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export function useEmptyWorkflowDialog() {
closeDialog()
templateSelectorDialog.show('appbuilder', {
afterClose: () => {
if (app.rootGraph?.nodes?.length) options.onEnterBuilder()
if (app.isGraphReady && app.rootGraph.nodes.length)
options.onEnterBuilder()
}
})
}
Expand Down
1 change: 1 addition & 0 deletions src/components/builder/useResolvedSelectedInputs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useResolvedSelectedInputs } from './useResolvedSelectedInputs'

vi.mock('@/scripts/app', () => ({
app: {
isGraphReady: true,
rootGraph: {
id: '11111111-1111-4111-8111-111111111111',
nodes: [] as LGraphNode[],
Expand Down
32 changes: 13 additions & 19 deletions src/components/builder/useResolvedSelectedInputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,24 @@ export type ResolvedSelection =
export function useResolvedSelectedInputs() {
const appModeStore = useAppModeStore()

const graphNodes = shallowRef<LGraphNode[]>([...(app.rootGraph?.nodes ?? [])])
const refreshGraphNodes = () =>
(graphNodes.value = [...(app.rootGraph?.nodes ?? [])])
useEventListener(() => app.rootGraph?.events, 'configured', refreshGraphNodes)
useEventListener(
() => app.rootGraph?.events,
'convert-to-subgraph',
refreshGraphNodes
)
useEventListener(
() => app.rootGraph?.events,
'subgraph-created',
refreshGraphNodes
)
useEventListener(
() => app.rootGraph?.events,
'node:slot-label:changed',
() => triggerRef(graphNodes)
const readGraphNodes = () =>
app.isGraphReady ? [...app.rootGraph.nodes] : []
const rootGraphEvents = () =>
app.isGraphReady ? app.rootGraph.events : undefined

const graphNodes = shallowRef<LGraphNode[]>(readGraphNodes())
const refreshGraphNodes = () => (graphNodes.value = readGraphNodes())
useEventListener(rootGraphEvents, 'configured', refreshGraphNodes)
useEventListener(rootGraphEvents, 'convert-to-subgraph', refreshGraphNodes)
useEventListener(rootGraphEvents, 'subgraph-created', refreshGraphNodes)
useEventListener(rootGraphEvents, 'node:slot-label:changed', () =>
triggerRef(graphNodes)
)

return computed<ResolvedSelection[]>(() => {
void graphNodes.value
if (!app.isGraphReady) return []
const rootGraph = app.rootGraph
if (!rootGraph) return []

return appModeStore.selectedInputs.flatMap(
([widgetId, displayName, config]): ResolvedSelection[] => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/rightSidePanel/errors/useErrorGroups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ export function useErrorGroups(searchQuery: MaybeRefOrGetter<string>) {
if (cachedNode && nodeIds.has(String(cachedNode.id))) return true

// Resolve from graph for model/media candidates
if (app.rootGraph) {
if (app.isGraphReady) {
const graphNode = getNodeByExecutionId(app.rootGraph, executionNodeId)
if (graphNode && nodeIds.has(String(graphNode.id))) return true
}
Expand Down
17 changes: 11 additions & 6 deletions src/composables/graph/useErrorClearingHooks.promotion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ import { app } from '@/scripts/app'
import { createNodeExecutionId } from '@/types/nodeIdentification'
import { toNodeId } from '@/types/nodeId'

function stubRootGraph(graph: LGraph) {
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(graph)
vi.spyOn(app, 'isGraphReady', 'get').mockReturnValue(true)
}

describe('link ownership error surface', () => {
beforeEach(() => {
setActivePinia(createTestingPinia({ stubActions: false }))
Expand All @@ -49,7 +54,7 @@ describe('link ownership error surface', () => {
)
input.widget = { name: widget.name }
graph.add(node)
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(graph)
stubRootGraph(graph)

installErrorClearingHooks(graph)

Expand Down Expand Up @@ -99,7 +104,7 @@ describe('link ownership while a workflow loads', () => {
)
input.widget = { name: widget.name }
graph.add(node)
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(graph)
stubRootGraph(graph)

installErrorClearingHooks(graph)

Expand Down Expand Up @@ -132,7 +137,7 @@ describe('link ownership while a workflow loads', () => {
)
input.widget = { name: widget.name }
graph.add(node)
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(graph)
stubRootGraph(graph)

installErrorClearingHooks(graph)

Expand Down Expand Up @@ -174,7 +179,7 @@ describe('promotion listener lifecycle', () => {
rootGraph.add(host)
return host
})
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(rootGraph)
stubRootGraph(rootGraph)
return { subgraph, rootGraph, hosts }
}

Expand Down Expand Up @@ -268,7 +273,7 @@ describe('promoted widget promotion error surface moves with ownership', () => {
leafInput.widget = { name: leafWidget.name }
subgraph.add(leafNode)

vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(rootGraph)
stubRootGraph(rootGraph)
return { subgraph, rootGraph, host, leafNode, leafWidget }
}

Expand Down Expand Up @@ -355,7 +360,7 @@ describe('promoted widget demotion error clearing', () => {
promoteValueWidgetViaSubgraphInput(host, leafNode, leafWidget).ok
).toBe(true)
expect(host.widgets).toHaveLength(1)
vi.spyOn(app, 'rootGraph', 'get').mockReturnValue(rootGraph)
stubRootGraph(rootGraph)
installErrorClearingHooks(subgraph)

const mediaStore = useMissingMediaStore()
Expand Down
Loading
Loading