Files
ComfyUI_frontend/src/utils/categoryUtil.ts
Christian Byrne fbdaf5d7f3 feat: New Template Library (#7062)
## Summary

Implement the new design for template library

## Changes

- What
  - New sort option: `Popular` and  `Recommended`
  - New category: `Popular`, leverage the `Popular` sorting
  - Support add category stick to top of the side bar 
- Support template customized visible in different platform by
`includeOnDistributions` field

### How to make `Popular` and `Recommended` work

Add usage-based ordering to workflow templates with position bias
correction, manual ranking (searchRank), and freshness boost.

New sort modes:
- "Recommended" (default): usage × 0.5 + searchRank × 0.3 + freshness ×
0.2
- "Popular": usage × 0.9 + freshness × 0.1

## Screenshots (if applicable)

New default ordering:

<img width="1812" height="1852" alt="Selection_2485"
src="https://github.com/user-attachments/assets/8f4ed6e9-9cf4-43a8-8796-022dcf4c277e"
/>

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7062-feat-usage-based-template-ordering-2bb6d73d365081f1ac65f8ad55fe8ce6)
by [Unito](https://www.unito.io)

Popular category:

<img width="281" height="283" alt="image"
src="https://github.com/user-attachments/assets/fd54fcb8-6caa-4982-a6b6-1f70ca4b31e3"
/>

---------

Co-authored-by: Yourz <crazilou@vip.qq.com>
Co-authored-by: GitHub Action <action@github.com>
2026-01-06 19:10:40 +01:00

63 lines
2.0 KiB
TypeScript

/**
* Maps category IDs to their corresponding Lucide icon classes
*/
export const getCategoryIcon = (categoryId: string): string => {
const iconMap: Record<string, string> = {
// Main categories
all: 'icon-[lucide--list]',
'getting-started': 'icon-[lucide--graduation-cap]',
// Generation types
'generation-image': 'icon-[lucide--image]',
image: 'icon-[lucide--image]',
'generation-video': 'icon-[lucide--film]',
video: 'icon-[lucide--film]',
'generation-3d': 'icon-[lucide--box]',
'3d': 'icon-[lucide--box]',
'generation-audio': 'icon-[lucide--volume-2]',
audio: 'icon-[lucide--volume-2]',
'generation-llm': 'icon-[lucide--message-square-text]',
// API and models
'api-nodes': 'icon-[lucide--hand-coins]',
'closed-models': 'icon-[lucide--hand-coins]',
// LLMs and AI
llm: 'icon-[lucide--message-square-text]',
llms: 'icon-[lucide--message-square-text]',
'llm-api': 'icon-[lucide--message-square-text]',
// Performance and hardware
'small-models': 'icon-[lucide--zap]',
performance: 'icon-[lucide--zap]',
'mac-compatible': 'icon-[lucide--command]',
'runs-on-mac': 'icon-[lucide--command]',
// Training
'lora-training': 'icon-[lucide--dumbbell]',
training: 'icon-[lucide--dumbbell]',
// Extensions and tools
extensions: 'icon-[lucide--puzzle]',
tools: 'icon-[lucide--wrench]',
// Fallbacks for common patterns
upscaling: 'icon-[lucide--maximize-2]',
controlnet: 'icon-[lucide--sliders-horizontal]',
'area-composition': 'icon-[lucide--layout-grid]'
}
// Return mapped icon or fallback to folder
return iconMap[categoryId.toLowerCase()] || 'icon-[lucide--folder]'
}
/**
* Generates a unique category ID from a category group and title
*/
export function generateCategoryId(
categoryGroup: string,
categoryTitle: string
) {
return `${categoryGroup.toLowerCase().replace(/\s+/g, '-')}-${categoryTitle.toLowerCase().replace(/\s+/g, '-')}`
}