Compare commits

...

6 Commits

Author SHA1 Message Date
github-actions
a0548e68b6 Update locales [skip ci] 2025-06-13 00:03:10 +00:00
Yiqun Xu
588f59c6ae Revert "Merge branch 'feat/check-template-version' of https://github.com/Comfy-Org/ComfyUI_frontend into feat/check-template-version"
This reverts commit 316755b5db, reversing
changes made to e00886e538.
2025-06-12 16:58:42 -07:00
Yiqun Xu
316755b5db Merge branch 'feat/check-template-version' of https://github.com/Comfy-Org/ComfyUI_frontend into feat/check-template-version 2025-06-12 16:54:50 -07:00
Yiqun Xu
e00886e538 fix: fix unit test 2025-06-12 16:50:03 -07:00
github-actions
72949d93e6 Update locales [skip ci] 2025-06-12 23:03:03 +00:00
Yiqun Xu
9a3547a24b check template version 2025-06-12 06:33:02 -07:00
11 changed files with 115 additions and 15 deletions

View File

@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it, vi } from 'vitest'
import { createPinia, setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue'
import TemplateWorkflowCard from '@/components/templates/TemplateWorkflowCard.vue'
@@ -109,6 +110,10 @@ vi.mock('@/composables/useTemplateWorkflows', () => ({
}))
describe('TemplateWorkflowCard', () => {
beforeEach(() => {
setActivePinia(createPinia())
})
const createTemplate = (overrides = {}): TemplateInfo => ({
name: 'test-template',
mediaType: 'image',

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

@@ -1152,6 +1152,8 @@
"Video": "Video",
"Video API": "API de Video"
},
"currentVersion": "Versión actual: v{version}",
"requiresUpgrade": "Requiere ComfyUI v{version} o superior",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "Hunyuan3D 2.0 MV",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "Usa la API Google Veo2 para generar videos a partir de imágenes."
}
},
"title": "Comienza con una Plantilla"
"title": "Comienza con una Plantilla",
"upgradeToUse": "Actualiza para usar esta plantilla"
},
"toastMessages": {
"couldNotDetermineFileType": "No se pudo determinar el tipo de archivo",

View File

@@ -1152,6 +1152,8 @@
"Video": "Vidéo",
"Video API": "API vidéo"
},
"currentVersion": "Version actuelle : v{version}",
"requiresUpgrade": "Nécessite ComfyUI v{version} ou supérieur",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "Hunyuan3D Multivue",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "Utilisez l'API Google Veo2 pour générer des vidéos à partir d'images."
}
},
"title": "Commencez avec un modèle"
"title": "Commencez avec un modèle",
"upgradeToUse": "Mettez à jour pour utiliser ce modèle"
},
"toastMessages": {
"couldNotDetermineFileType": "Impossible de déterminer le type de fichier",

View File

@@ -1152,6 +1152,8 @@
"Video": "ビデオ",
"Video API": "動画API"
},
"currentVersion": "現在のバージョン: v{version}",
"requiresUpgrade": "ComfyUI v{version} 以上が必要です",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "Hunyuan3D マルチビュー",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "Google Veo2 APIで画像から動画を生成します。"
}
},
"title": "テンプレートを利用して開始"
"title": "テンプレートを利用して開始",
"upgradeToUse": "このテンプレートを使用するにはアップグレードしてください"
},
"toastMessages": {
"couldNotDetermineFileType": "ファイルタイプを判断できませんでした",

View File

@@ -1152,6 +1152,8 @@
"Video": "비디오",
"Video API": "비디오 API"
},
"currentVersion": "현재 버전: v{version}",
"requiresUpgrade": "ComfyUI v{version} 이상이 필요합니다",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "Hunyuan3D 다중뷰",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "Google Veo2 API로 이미지에서 비디오를 생성합니다."
}
},
"title": "템플릿으로 시작하기"
"title": "템플릿으로 시작하기",
"upgradeToUse": "이 템플릿을 사용하려면 업그레이드하세요"
},
"toastMessages": {
"couldNotDetermineFileType": "파일 유형을 결정할 수 없습니다",

View File

@@ -1152,6 +1152,8 @@
"Video": "Видео",
"Video API": "Video API"
},
"currentVersion": "Текущая версия: v{version}",
"requiresUpgrade": "Требуется ComfyUI версии {version} или выше",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "Hunyuan3D Многовидовой",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "Используйте Google Veo2 API для генерации видео из изображений."
}
},
"title": "Начните с шаблона"
"title": "Начните с шаблона",
"upgradeToUse": "Обновите, чтобы использовать этот шаблон"
},
"toastMessages": {
"couldNotDetermineFileType": "Не удалось определить тип файла",

View File

@@ -1152,6 +1152,8 @@
"Video": "视频",
"Video API": "视频 API"
},
"currentVersion": "当前版本v{version}",
"requiresUpgrade": "需要 ComfyUI v{version} 或更高版本",
"template": {
"3D": {
"hunyuan-3d-multiview-elf": "混元3D多视图",
@@ -1354,7 +1356,8 @@
"api_veo2_i2v": "使用 Google Veo2 API 通过图像生成视频。"
}
},
"title": "从模板开始"
"title": "从模板开始",
"upgradeToUse": "升级以使用此模板"
},
"toastMessages": {
"couldNotDetermineFileType": "无法确定文件类型",

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 {