Workflows/Templates fixes

Match styles

Make workflows button functional

When opening a workflow or template from linear mode that does not
explicitly have a value set for linear mode, open the workflow or
template in linear mode

Known issue: workflows sidebar pane has a higher min-width than the
outputs panel. This is not an easy fix and I may have to re-implement
our own splitter component to smooth over the annoyances I've faced
This commit is contained in:
Austin Mroz
2026-01-06 11:45:05 -08:00
parent 664150b6a3
commit 2845320ddf
3 changed files with 25 additions and 27 deletions

View File

@@ -151,6 +151,7 @@ import {
useWorkflowBookmarkStore,
useWorkflowStore
} from '@/platform/workflow/management/stores/workflowStore'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useWorkspaceStore } from '@/stores/workspaceStore'
import type { TreeExplorerNode, TreeNode } from '@/types/treeExplorerTypes'
import { appendJsonExt } from '@/utils/formatUtil'
@@ -238,7 +239,12 @@ const renderTreeNode = (
e: MouseEvent
) {
if (this.leaf) {
const canvasStore = useCanvasStore()
const fromLinearMode = canvasStore.linearMode
await workflowService.openWorkflow(workflow)
const extra = workflow.activeState?.extra
if (extra && extra.linearMode === undefined && fromLinearMode)
canvasStore.linearMode = extra.linearMode = true
} else {
toggleNodeOnEvent(e, this)
}

View File

@@ -9,6 +9,7 @@ import type {
TemplateInfo,
WorkflowTemplates
} from '@/platform/workflow/templates/types/template'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
import { useDialogStore } from '@/stores/dialogStore'
@@ -121,28 +122,7 @@ export function useTemplateWorkflows() {
if (!template || !template.sourceModule) return false
// Use the stored source module for loading
const actualSourceModule = template.sourceModule
json = await fetchTemplateJson(id, actualSourceModule)
// Use source module for name
const workflowName =
actualSourceModule === 'default'
? t(`templateWorkflows.template.${id}`, id)
: id
if (isCloud) {
useTelemetry()?.trackTemplate({
workflow_name: id,
template_source: actualSourceModule
})
}
dialogStore.closeDialog()
await app.loadGraphData(json, true, true, workflowName, {
openSource: 'template'
})
return true
sourceModule = template.sourceModule
}
// Regular case for normal categories
@@ -159,12 +139,18 @@ export function useTemplateWorkflows() {
template_source: sourceModule
})
}
dialogStore.closeDialog()
const canvasStore = useCanvasStore()
const fromLinearMode = canvasStore.linearMode
await app.loadGraphData(json, true, true, workflowName, {
openSource: 'template'
})
const extra = app.rootGraph.extra
if (extra && extra.linearMode === undefined && fromLinearMode)
canvasStore.linearMode = extra.linearMode = true
return true
} catch (error) {
console.error('Error loading workflow template:', error)

View File

@@ -14,7 +14,9 @@ import { computed, ref, shallowRef, useTemplateRef, watch } from 'vue'
import { downloadFile } from '@/base/common/downloadUtil'
import Load3dViewerContent from '@/components/load3d/Load3dViewerContent.vue'
import SidebarIcon from '@/components/sidebar/SidebarIcon.vue'
import SidebarTemplatesButton from '@/components/sidebar/SidebarTemplatesButton.vue'
import WorkflowsSidebarTab from '@/components/sidebar/tabs/WorkflowsSidebarTab.vue'
import TopbarBadges from '@/components/topbar/TopbarBadges.vue'
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
import Popover from '@/components/ui/Popover.vue'
@@ -60,6 +62,7 @@ const workflowStore = useWorkflowStore()
void outputs.fetchMediaList()
const displayWorkflows = ref(false)
const hasPreview = ref(false)
whenever(
() => nodeOutputStore.latestPreview[0],
@@ -307,7 +310,6 @@ const itemStats = computed<StatItem[]>(() => {
{ content: formatTime(activeItem.value.created_at) },
{ content: formatDuration(user_metadata.executionTimeInSeconds) },
allOutputs && { content: `${allOutputs.length} asset` },
//TODO asset icon
(activeOutput && mediaTypes[getMediaType(activeOutput)]) ?? {}
].filter((i) => !!i)
})
@@ -421,9 +423,11 @@ function downloadAsset(item: AssetItem) {
<div
class="h-full flex flex-col w-14 shrink-0 overflow-hidden items-center p-2 border-r border-node-component-border"
>
<Button class="bg-transparent">
<i class="size-4 icon-[comfy--workflow] bg-muted-foreground" />
</Button>
<SidebarIcon
icon="icon-[comfy--workflow]"
:selected="displayWorkflows"
@click="displayWorkflows = !displayWorkflows"
/>
<SidebarTemplatesButton />
<div class="flex-1" />
<div class="p-1 bg-secondary-background rounded-lg w-10">
@@ -445,7 +449,9 @@ function downloadAsset(item: AssetItem) {
</Button>
</div>
</div>
<WorkflowsSidebarTab v-if="displayWorkflows" class="min-w-0" />
<linear-outputs
v-else
ref="outputsRef"
class="h-full min-w-24 grow-1 p-3 overflow-y-auto border-r-1 border-node-component-border flex flex-col items-center"
>