mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-11 02:20:08 +00:00
[feat] Add Partner Nodes virtual category and rename license filter (#6542)
This PR adds a 'Partner Nodes' virtual category that filters templates where OpenSource === false, and renames the 'License' filter to 'Runs on' with values 'ComfyUI' and 'Partner API'. The implementation is backward compatible and works like the existing 'Basics' category - it filters templates from any category without duplication. The filter logic now uses the explicit OpenSource field instead of heuristic detection. This change coordinates with upcoming workflow_templates repo updates that will move API templates to GENERATION TYPE categories and add the OpenSource field to all API node templates. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6542-feat-Add-Partner-Nodes-virtual-category-and-rename-license-filter-29f6d73d36508111a85bdf5017f0a100) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -114,16 +114,17 @@ export function useTemplateFiltering(
|
||||
}
|
||||
|
||||
return filteredByUseCases.value.filter((template) => {
|
||||
// Check if template has API in its tags or name (indicating it runs on external/remote API)
|
||||
const isApiTemplate =
|
||||
template.tags?.includes('API') ||
|
||||
template.name?.toLowerCase().includes('api_')
|
||||
// Use openSource field to determine where template runs
|
||||
// openSource === false -> External/Remote API
|
||||
// openSource !== false -> ComfyUI (includes true and undefined)
|
||||
const isExternalAPI = template.openSource === false
|
||||
const isComfyUI = template.openSource !== false
|
||||
|
||||
return selectedRunsOn.value.some((selectedRunsOn) => {
|
||||
if (selectedRunsOn === 'External or Remote API') {
|
||||
return isApiTemplate
|
||||
return isExternalAPI
|
||||
} else if (selectedRunsOn === 'ComfyUI') {
|
||||
return !isApiTemplate
|
||||
return isComfyUI
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
@@ -754,7 +754,10 @@
|
||||
"Image API": "Image API",
|
||||
"Video API": "Video API",
|
||||
"LLM API": "LLM API",
|
||||
"All": "All Templates"
|
||||
"All": "All Templates",
|
||||
"Extensions": "Extensions",
|
||||
"Partner Nodes": "Partner Nodes",
|
||||
"Generation Type": "Generation Type"
|
||||
},
|
||||
"categories": "Categories",
|
||||
"resetFilters": "Clear Filters",
|
||||
@@ -767,6 +770,7 @@
|
||||
"modelsSelected": "{count} Models",
|
||||
"useCasesSelected": "{count} Use Cases",
|
||||
"runsOnSelected": "{count} Runs On",
|
||||
"runsOnFilter": "Runs on",
|
||||
"resultsCount": "Showing {count} of {total} templates",
|
||||
"sort": {
|
||||
"recommended": "Recommended",
|
||||
|
||||
@@ -22,6 +22,7 @@ interface EnhancedTemplate extends TemplateInfo {
|
||||
categoryType?: string
|
||||
categoryGroup?: string // 'GENERATION TYPE' or 'CLOSED SOURCE MODELS'
|
||||
isEssential?: boolean
|
||||
isPartnerNode?: boolean // Computed from OpenSource === false
|
||||
searchableText?: string
|
||||
}
|
||||
|
||||
@@ -202,6 +203,7 @@ export const useWorkflowTemplatesStore = defineStore(
|
||||
categoryType: category.type,
|
||||
categoryGroup: category.category,
|
||||
isEssential: category.isEssential,
|
||||
isPartnerNode: template.openSource === false,
|
||||
searchableText: [
|
||||
template.title || template.name,
|
||||
template.description || '',
|
||||
@@ -269,6 +271,11 @@ export const useWorkflowTemplatesStore = defineStore(
|
||||
return enhancedTemplates.value.filter((t) => t.isEssential)
|
||||
}
|
||||
|
||||
if (categoryId === 'partner-nodes') {
|
||||
// Filter for templates where OpenSource === false
|
||||
return enhancedTemplates.value.filter((t) => t.isPartnerNode)
|
||||
}
|
||||
|
||||
// Handle extension-specific filters
|
||||
if (categoryId.startsWith('extension-')) {
|
||||
const moduleName = categoryId.replace('extension-', '')
|
||||
@@ -397,6 +404,22 @@ export const useWorkflowTemplatesStore = defineStore(
|
||||
}
|
||||
})
|
||||
|
||||
// 3.5. Partner Nodes - virtual category for OpenSource === false templates
|
||||
const partnerNodeCount = enhancedTemplates.value.filter(
|
||||
(t) => t.isPartnerNode
|
||||
).length
|
||||
|
||||
if (partnerNodeCount > 0) {
|
||||
items.push({
|
||||
id: 'partner-nodes',
|
||||
label: st(
|
||||
'templateWorkflows.category.Partner Nodes',
|
||||
'Partner Nodes'
|
||||
),
|
||||
icon: 'icon-[lucide--handshake]'
|
||||
})
|
||||
}
|
||||
|
||||
// 4. Extensions - always last
|
||||
const extensionCounts = enhancedTemplates.value.filter(
|
||||
(t) => t.sourceModule !== 'default'
|
||||
|
||||
@@ -23,6 +23,10 @@ export interface TemplateInfo {
|
||||
*/
|
||||
vram?: number
|
||||
size?: number
|
||||
/**
|
||||
* Whether this template uses open source models. When false, indicates partner/API node templates.
|
||||
*/
|
||||
openSource?: boolean
|
||||
}
|
||||
|
||||
export interface WorkflowTemplates {
|
||||
|
||||
@@ -74,7 +74,8 @@ describe('useTemplateFiltering', () => {
|
||||
tags: ['API', 'Video'],
|
||||
models: ['Flux'],
|
||||
date: '2024-06-01',
|
||||
vram: 15 * 1024 ** 3
|
||||
vram: 15 * 1024 ** 3,
|
||||
openSource: false
|
||||
},
|
||||
{
|
||||
name: 'portrait-flow',
|
||||
|
||||
Reference in New Issue
Block a user