mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 14:54:37 +00:00
feat: show legacy manager search tip in no-results empty state (#8537)
## Summary
Show a non-intrusive tip in the no-results empty state when users search
legacy manager-related terms in the new manager UI.
## Changes
- **What**: Add `useLegacySearchTip` composable that detects when search
query matches legacy manager keywords ("manager", "comfyui-manager",
etc.) and appends a tip to the empty state message suggesting the
`--enable-manager-legacy-ui` flag
- **Integration**: Tip appears as secondary muted text below "Try a
different search" message when no results found
- **Tests**: 9 test cases covering detection logic and edge cases
## Review Focus
- Keyword list covers common legacy manager search terms
- Non-intrusive approach: tip only shows in no-results state, no dismiss
button needed
Fixes COM-12509
This commit is contained in:
@@ -290,6 +290,7 @@
|
||||
"legacyMenuNotAvailable": "Legacy manager menu is not available, defaulting to the new manager menu.",
|
||||
"legacyManagerUI": "Use Legacy UI",
|
||||
"legacyManagerUIDescription": "To use the legacy Manager UI, start ComfyUI with --enable-manager-legacy-ui",
|
||||
"legacyManagerSearchTip": "Looking for ComfyUI-Manager? You can enable the legacy manager UI by starting ComfyUI with the --enable-manager-legacy-ui flag.",
|
||||
"failed": "Failed",
|
||||
"failedToInstall": "Failed to Install",
|
||||
"installError": "Install Error",
|
||||
|
||||
@@ -206,6 +206,8 @@ import { useManagerDisplayPacks } from '@/workbench/extensions/manager/composabl
|
||||
import { useManagerStatePersistence } from '@/workbench/extensions/manager/composables/useManagerStatePersistence'
|
||||
import { useRegistrySearch } from '@/workbench/extensions/manager/composables/useRegistrySearch'
|
||||
import { useConflictDetectionStore } from '@/workbench/extensions/manager/stores/conflictDetectionStore'
|
||||
import { useLegacySearchTip } from '@/workbench/extensions/manager/composables/useLegacySearchTip'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
@@ -222,6 +224,7 @@ const comfyManagerStore = useComfyManagerStore()
|
||||
const { getPackById } = useComfyRegistryStore()
|
||||
const conflictAcknowledgment = useConflictAcknowledgment()
|
||||
const conflictDetectionStore = useConflictDetectionStore()
|
||||
const { isNewManagerUI } = useManagerState()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const persistedState = useManagerStatePersistence()
|
||||
const initialState = persistedState.loadStoredState()
|
||||
@@ -349,7 +352,11 @@ const {
|
||||
})
|
||||
pageNumber.value = 0
|
||||
|
||||
// Filter and sort options for SingleSelect
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
const filterOptions = computed(() => [
|
||||
{ name: t('manager.filter.nodePack'), value: 'packs' },
|
||||
{ name: t('g.nodes'), value: 'nodes' }
|
||||
@@ -414,7 +421,13 @@ const emptyStateTitle = computed(() => {
|
||||
|
||||
const emptyStateMessage = computed(() => {
|
||||
if (comfyManagerStore.error) return t('manager.tryAgainLater')
|
||||
if (searchQuery.value) return t('manager.tryDifferentSearch')
|
||||
if (searchQuery.value) {
|
||||
const baseMessage = t('manager.tryDifferentSearch')
|
||||
if (isLegacyManagerSearch.value) {
|
||||
return `${baseMessage}\n\n${t('manager.legacyManagerSearchTip')}`
|
||||
}
|
||||
return baseMessage
|
||||
}
|
||||
|
||||
const tabId = selectedTab.value?.id as ManagerTab | undefined
|
||||
const emptyStateKey = tabId ? tabEmptyStateKeys[tabId] : undefined
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import type { Ref } from 'vue'
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
import { useLegacySearchTip } from './useLegacySearchTip'
|
||||
|
||||
describe('useLegacySearchTip', () => {
|
||||
let searchQuery: Ref<string>
|
||||
let isNewManagerUI: Ref<boolean>
|
||||
|
||||
beforeEach(() => {
|
||||
searchQuery = ref('')
|
||||
isNewManagerUI = ref(true)
|
||||
})
|
||||
|
||||
describe('isLegacyManagerSearch', () => {
|
||||
it('returns true when searching "manager" in new manager UI', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'manager'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(true)
|
||||
})
|
||||
|
||||
it('returns true when searching "comfyui-manager"', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'comfyui-manager'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(true)
|
||||
})
|
||||
|
||||
it('returns true when searching "comfyui manager" (space variant)', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'comfyui manager'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(true)
|
||||
})
|
||||
|
||||
it('returns true when keyword is part of larger query', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'where is manager'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(true)
|
||||
})
|
||||
|
||||
it('matches case-insensitively', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'MANAGER'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(true)
|
||||
})
|
||||
|
||||
it('returns false when query is empty', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = ''
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false when query is whitespace only', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = ' '
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false when searching unrelated terms', async () => {
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'controlnet'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false when isNewManagerUI is false', async () => {
|
||||
isNewManagerUI.value = false
|
||||
const { isLegacyManagerSearch } = useLegacySearchTip(
|
||||
searchQuery,
|
||||
isNewManagerUI
|
||||
)
|
||||
|
||||
searchQuery.value = 'manager'
|
||||
await nextTick()
|
||||
|
||||
expect(isLegacyManagerSearch.value).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { Ref } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const LEGACY_MANAGER_KEYWORDS = [
|
||||
'manager',
|
||||
'comfyui-manager',
|
||||
'manager comfyui',
|
||||
'comfyui manager'
|
||||
] as const
|
||||
|
||||
export function useLegacySearchTip(
|
||||
searchQuery: Ref<string>,
|
||||
isNewManagerUI: Ref<boolean>
|
||||
) {
|
||||
const isLegacyManagerSearch = computed(() => {
|
||||
if (!isNewManagerUI.value) return false
|
||||
const query = searchQuery.value.toLowerCase().trim()
|
||||
if (!query) return false
|
||||
return LEGACY_MANAGER_KEYWORDS.some((keyword) => query.includes(keyword))
|
||||
})
|
||||
|
||||
return {
|
||||
isLegacyManagerSearch
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user