check template version

This commit is contained in:
Yiqun Xu
2025-06-12 06:33:02 -07:00
parent a937ac59ad
commit 9a3547a24b
4 changed files with 85 additions and 8 deletions

View File

@@ -2,14 +2,18 @@
<Card
ref="cardRef"
:data-testid="`template-workflow-${template.name}`"
class="w-64 template-card rounded-2xl overflow-hidden cursor-pointer shadow-elevation-2 dark-theme:bg-dark-elevation-1.5 h-full"
class="w-64 template-card rounded-2xl overflow-hidden shadow-elevation-2 dark-theme:bg-dark-elevation-1.5 h-full"
:class="{
'cursor-pointer': isCompatible,
'cursor-not-allowed opacity-60 grayscale': !isCompatible
}"
:pt="{
body: { class: 'p-0 h-full flex flex-col' }
}"
@click="$emit('loadWorkflow', template.name)"
@click="handleCardClick"
>
<template #header>
<div class="flex items-center justify-center">
<div class="flex items-center justify-center relative">
<div class="relative overflow-hidden rounded-t-lg">
<template v-if="template.mediaType === 'audio'">
<AudioThumbnail :src="baseThumbnailSrc" />
@@ -19,7 +23,7 @@
:base-image-src="baseThumbnailSrc"
:overlay-image-src="overlayThumbnailSrc"
:alt="title"
:is-hovered="isHovered"
:is-hovered="isHovered && isCompatible"
:is-video="
template.mediaType === 'video' ||
template.mediaSubtype === 'webp'
@@ -31,7 +35,7 @@
:base-image-src="baseThumbnailSrc"
:overlay-image-src="overlayThumbnailSrc"
:alt="title"
:is-hovered="isHovered"
:is-hovered="isHovered && isCompatible"
:is-video="
template.mediaType === 'video' ||
template.mediaSubtype === 'webp'
@@ -42,7 +46,7 @@
<DefaultThumbnail
:src="baseThumbnailSrc"
:alt="title"
:is-hovered="isHovered"
:is-hovered="isHovered && isCompatible"
:is-video="
template.mediaType === 'video' ||
template.mediaSubtype === 'webp'
@@ -59,6 +63,21 @@
class="absolute inset-0 z-1 w-3/12 h-full"
/>
</div>
<!-- Version incompatibility indicator -->
<div
v-if="!isCompatible"
class="absolute top-2 right-2 bg-yellow-500 text-white text-xs px-2 py-1 rounded-full flex items-center gap-1 shadow-lg z-10"
:title="
$t('templateWorkflows.requiresUpgrade', {
version: template.versionRequired
})
"
>
<i class="pi pi-exclamation-triangle text-xs"></i>
<span class="text-xs font-medium"
>v{{ template.versionRequired }}+</span
>
</div>
</div>
</template>
<template #content>
@@ -70,6 +89,21 @@
<p class="line-clamp-2 text-sm text-muted grow" :title="description">
{{ description }}
</p>
<!-- Upgrade prompt for incompatible templates -->
<div
v-if="!isCompatible"
class="mt-2 text-xs text-yellow-600 dark:text-yellow-400 font-medium"
>
{{ $t('templateWorkflows.upgradeToUse') }}
<br />
<span class="text-muted">
{{
$t('templateWorkflows.currentVersion', {
version: currentVersion
})
}}
</span>
</div>
</div>
</div>
</template>
@@ -87,7 +121,9 @@ import CompareSliderThumbnail from '@/components/templates/thumbnails/CompareSli
import DefaultThumbnail from '@/components/templates/thumbnails/DefaultThumbnail.vue'
import HoverDissolveThumbnail from '@/components/templates/thumbnails/HoverDissolveThumbnail.vue'
import { useTemplateWorkflows } from '@/composables/useTemplateWorkflows'
import { useSystemStatsStore } from '@/stores/systemStatsStore'
import { TemplateInfo } from '@/types/workflowTemplateTypes'
import { compareVersions } from '@/utils/formatUtil'
const UPSCALE_ZOOM_SCALE = 16 // for upscale templates, exaggerate the hover zoom
const DEFAULT_ZOOM_SCALE = 5
@@ -101,6 +137,7 @@ const { sourceModule, loading, template } = defineProps<{
const cardRef = ref<HTMLElement | null>(null)
const isHovered = useElementHover(cardRef)
const systemStatsStore = useSystemStatsStore()
const { getTemplateThumbnailUrl, getTemplateTitle, getTemplateDescription } =
useTemplateWorkflows()
@@ -133,7 +170,31 @@ const title = computed(() =>
getTemplateTitle(template, effectiveSourceModule.value)
)
defineEmits<{
// Version compatibility check
const currentVersion = computed(() => {
return systemStatsStore.systemStats?.system?.comfyui_version || ''
})
const isCompatible = computed(() => {
if (!template.versionRequired) {
return true // No version requirement, always compatible
}
if (!currentVersion.value) {
return false // No current version available, assume incompatible
}
// Return true if current version is >= required version
return compareVersions(currentVersion.value, template.versionRequired) >= 0
})
const emit = defineEmits<{
loadWorkflow: [name: string]
}>()
const handleCardClick = () => {
if (isCompatible.value) {
emit('loadWorkflow', template.name)
}
}
</script>

View File

@@ -56,12 +56,13 @@ import { useAsyncState } from '@vueuse/core'
import Button from 'primevue/button'
import Divider from 'primevue/divider'
import ProgressSpinner from 'primevue/progressspinner'
import { watch } from 'vue'
import { onMounted, watch } from 'vue'
import TemplateWorkflowView from '@/components/templates/TemplateWorkflowView.vue'
import TemplateWorkflowsSideNav from '@/components/templates/TemplateWorkflowsSideNav.vue'
import { useResponsiveCollapse } from '@/composables/element/useResponsiveCollapse'
import { useTemplateWorkflows } from '@/composables/useTemplateWorkflows'
import { useSystemStatsStore } from '@/stores/systemStatsStore'
import type { WorkflowTemplates } from '@/types/workflowTemplateTypes'
const {
@@ -82,6 +83,14 @@ const {
} = useTemplateWorkflows()
const { isReady } = useAsyncState(loadTemplates, null)
const systemStatsStore = useSystemStatsStore()
// Initialize system stats when component mounts
onMounted(async () => {
if (!systemStatsStore.systemStats) {
await systemStatsStore.fetchSystemStats()
}
})
watch(
isReady,

View File

@@ -501,6 +501,9 @@
},
"templateWorkflows": {
"title": "Get Started with a Template",
"requiresUpgrade": "Requires ComfyUI v{version} or higher",
"upgradeToUse": "Upgrade to use this template",
"currentVersion": "Current version: v{version}",
"category": {
"ComfyUI Examples": "ComfyUI Examples",
"Custom Nodes": "Custom Nodes",

View File

@@ -12,6 +12,10 @@ export interface TemplateInfo {
localizedTitle?: string
localizedDescription?: string
sourceModule?: string
/**
* Minimum version of ComfyUI required to use this template
*/
versionRequired?: string
}
export interface WorkflowTemplates {