From 4340a0ab55309875845da03041f56da64730e35e Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Thu, 22 Jan 2026 21:24:46 +0900 Subject: [PATCH] chore: manager dialog modified --- src/components/widget/nav/NavItem.vue | 2 +- src/locales/en/main.json | 11 + .../components/manager/ManagerDialog.vue | 382 +++++++----------- .../manager/button/PackInstallButton.vue | 3 +- .../manager/button/PackTryUpdateButton.vue | 2 +- .../manager/button/PackUninstallButton.vue | 3 +- .../manager/button/PackUpdateButton.vue | 3 +- .../manager/infoPanel/InfoPanel.vue | 22 +- .../manager/infoPanel/InfoPanelHeader.vue | 41 +- .../components/manager/infoPanel/InfoTabs.vue | 60 ++- .../infoPanel/tabs/WarningTabPanel.vue | 2 +- .../manager/packBanner/PackBanner.vue | 2 +- .../components/manager/packCard/PackCard.vue | 79 ++-- .../composables/useManagerDisplayPacks.ts | 207 ++++++++++ .../manager/composables/useRegistrySearch.ts | 5 +- .../manager/types/comfyManagerTypes.ts | 8 +- 16 files changed, 461 insertions(+), 371 deletions(-) create mode 100644 src/workbench/extensions/manager/composables/useManagerDisplayPacks.ts diff --git a/src/components/widget/nav/NavItem.vue b/src/components/widget/nav/NavItem.vue index eb20b9852..b8b62cd5d 100644 --- a/src/components/widget/nav/NavItem.vue +++ b/src/components/widget/nav/NavItem.vue @@ -3,7 +3,7 @@ v-tooltip.right="{ value: tooltipText, disabled: !isOverflowing, - pt: { text: { class: 'whitespace-nowrap' } } + pt: { text: { class: 'w-max whitespace-nowrap' } } }" class="flex cursor-pointer items-center-safe gap-2 rounded-md px-4 py-3 text-sm transition-colors text-base-foreground" :class=" diff --git a/src/locales/en/main.json b/src/locales/en/main.json index fbb3b965f..f3602479e 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -295,6 +295,17 @@ "changingVersion": "Changing version from {from} to {to}", "dependencies": "Dependencies", "inWorkflow": "In Workflow", + "nav": { + "allExtensions": "All Extensions", + "notInstalled": "Not Installed", + "installedSection": "INSTALLED", + "allInstalled": "All installed", + "updatesAvailable": "Updates Available", + "conflicting": "Conflicting", + "inWorkflowSection": "IN WORKFLOW", + "allInWorkflow": "All in: {workflowName}", + "missingNodes": "Missing Nodes" + }, "infoPanelEmpty": "Click an item to see the info", "applyChanges": "Apply Changes", "restartToApplyChanges": "To apply changes, please restart ComfyUI", diff --git a/src/workbench/extensions/manager/components/manager/ManagerDialog.vue b/src/workbench/extensions/manager/components/manager/ManagerDialog.vue index ad7657645..8dde24f68 100644 --- a/src/workbench/extensions/manager/components/manager/ManagerDialog.vue +++ b/src/workbench/extensions/manager/components/manager/ManagerDialog.vue @@ -16,32 +16,63 @@ @@ -79,37 +110,18 @@ - -
-
- - -
- - -
- - - -
+ +
+ + +
@@ -118,7 +130,7 @@
-
+
workflowStore.activeWorkflow?.filename ?? t('manager.inWorkflow') +) + // Navigation items for LeftSidePanel -const navItems = computed(() => [ - { id: ManagerTab.All, label: t('g.all'), icon: 'pi pi-list' }, - { id: ManagerTab.Installed, label: t('g.installed'), icon: 'pi pi-box' }, +const navItems = computed<(NavItemData | NavGroupData)[]>(() => [ { - id: ManagerTab.Workflow, - label: t('manager.inWorkflow'), - icon: 'pi pi-folder' + id: ManagerTab.All, + label: t('manager.nav.allExtensions'), + icon: 'icon-[lucide--list]' }, { - id: ManagerTab.Missing, - label: t('g.missing'), - icon: 'pi pi-exclamation-circle' + id: ManagerTab.NotInstalled, + label: t('manager.nav.notInstalled'), + icon: 'icon-[lucide--globe]' }, { - id: ManagerTab.UpdateAvailable, - label: t('g.updateAvailable'), - icon: 'pi pi-sync' + title: t('manager.nav.installedSection'), + items: [ + { + id: ManagerTab.AllInstalled, + label: t('manager.nav.allInstalled'), + icon: 'icon-[lucide--download]' + }, + { + id: ManagerTab.UpdateAvailable, + label: t('manager.nav.updatesAvailable'), + icon: 'icon-[lucide--refresh-cw]' + }, + { + id: ManagerTab.Conflicting, + label: t('manager.nav.conflicting'), + icon: 'icon-[lucide--triangle-alert]', + badge: conflictDetectionStore.conflictedPackages.length || undefined + } + ] + }, + { + title: t('manager.nav.inWorkflowSection'), + items: [ + { + id: ManagerTab.Workflow, + label: t('manager.nav.allInWorkflow', { + workflowName: workflowName.value + }), + icon: 'icon-[lucide--share-2]' + }, + { + id: ManagerTab.Missing, + label: t('manager.nav.missingNodes'), + icon: 'icon-[lucide--triangle-alert]' + } + ] } ]) const initialTabId = initialTab ?? initialState.selectedTabId ?? ManagerTab.All const selectedNavId = ref(initialTabId) +// Helper to find a nav item by id in the nested structure +const findNavItemById = ( + items: (NavItemData | NavGroupData)[], + id: string | null +): NavItemData | undefined => { + for (const item of items) { + if ('items' in item) { + const found = item.items.find((subItem) => subItem.id === id) + if (found) return found + } else if (item.id === id) { + return item + } + } + return undefined +} + const selectedTab = computed(() => - navItems.value.find((item) => item.id === selectedNavId.value) + findNavItemById(navItems.value, selectedNavId.value) ) const { @@ -318,120 +384,20 @@ const isInitialLoad = computed( () => searchResults.value.length === 0 && searchQuery.value === '' ) -const isEmptySearch = computed(() => searchQuery.value === '') -const displayPacks = ref([]) - +// Use the new composable for tab-based display packs const { - startFetchInstalled, - filterInstalledPack, - installedPacks, - isLoading: isLoadingInstalled, - isReady: installedPacksReady -} = useInstalledPacks() - -const { - startFetchWorkflowPacks, - filterWorkflowPack, - workflowPacks, - isLoading: isLoadingWorkflow, - isReady: workflowPacksReady -} = useWorkflowPacks() - -const filterMissingPacks = (packs: components['schemas']['Node'][]) => - packs.filter((pack) => !comfyManagerStore.isPackInstalled(pack.id)) + displayPacks, + isLoading: isTabLoading, + workflowPacks +} = useManagerDisplayPacks(selectedNavId, searchResults, searchQuery, sortField) +// Tab helpers for template const isUpdateAvailableTab = computed( () => selectedTab.value?.id === ManagerTab.UpdateAvailable ) -const isInstalledTab = computed( - () => selectedTab.value?.id === ManagerTab.Installed -) const isMissingTab = computed( () => selectedTab.value?.id === ManagerTab.Missing ) -const isWorkflowTab = computed( - () => selectedTab.value?.id === ManagerTab.Workflow -) -const isAllTab = computed(() => selectedTab.value?.id === ManagerTab.All) - -const isOutdatedPack = (pack: components['schemas']['Node']) => { - const { isUpdateAvailable } = usePackUpdateStatus(pack) - return isUpdateAvailable.value === true -} -const filterOutdatedPacks = (packs: components['schemas']['Node'][]) => - packs.filter(isOutdatedPack) - -watch( - [isUpdateAvailableTab, installedPacks], - async () => { - if (!isUpdateAvailableTab.value) return - - if (!isEmptySearch.value) { - displayPacks.value = filterOutdatedPacks(installedPacks.value) - } else if ( - !installedPacks.value.length && - !installedPacksReady.value && - !isLoadingInstalled.value - ) { - await startFetchInstalled() - } else { - displayPacks.value = filterOutdatedPacks(installedPacks.value) - } - }, - { immediate: true } -) - -watch( - [isInstalledTab, installedPacks], - async () => { - if (!isInstalledTab.value) return - - if (!isEmptySearch.value) { - displayPacks.value = filterInstalledPack(searchResults.value) - } else if ( - !installedPacks.value.length && - !installedPacksReady.value && - !isLoadingInstalled.value - ) { - await startFetchInstalled() - } else { - displayPacks.value = installedPacks.value - } - }, - { immediate: true } -) - -watch( - [isMissingTab, isWorkflowTab, workflowPacks, installedPacks], - async () => { - if (!isWorkflowTab.value && !isMissingTab.value) return - - if (!isEmptySearch.value) { - displayPacks.value = isMissingTab.value - ? filterMissingPacks(filterWorkflowPack(searchResults.value)) - : filterWorkflowPack(searchResults.value) - } else if ( - !workflowPacks.value.length && - !isLoadingWorkflow.value && - !workflowPacksReady.value - ) { - await startFetchWorkflowPacks() - if (isMissingTab.value) { - await startFetchInstalled() - } - } else { - displayPacks.value = isMissingTab.value - ? filterMissingPacks(workflowPacks.value) - : workflowPacks.value - } - }, - { immediate: true } -) - -watch([isAllTab, searchResults], () => { - if (!isAllTab.value) return - displayPacks.value = searchResults.value -}) const onClickWarningLink = () => { window.open( @@ -442,49 +408,9 @@ const onClickWarningLink = () => { ) } -const onResultsChange = () => { - switch (selectedTab.value?.id) { - case ManagerTab.Installed: - displayPacks.value = isEmptySearch.value - ? installedPacks.value - : filterInstalledPack(searchResults.value) - break - case ManagerTab.Workflow: - displayPacks.value = isEmptySearch.value - ? workflowPacks.value - : filterWorkflowPack(searchResults.value) - break - case ManagerTab.Missing: - if (!isEmptySearch.value) { - displayPacks.value = filterMissingPacks( - filterWorkflowPack(searchResults.value) - ) - } - break - case ManagerTab.UpdateAvailable: - displayPacks.value = isEmptySearch.value - ? filterOutdatedPacks(installedPacks.value) - : filterOutdatedPacks(searchResults.value) - break - default: - displayPacks.value = searchResults.value - } -} - -watch(searchResults, onResultsChange, { flush: 'post' }) -watch(() => comfyManagerStore.installedPacksIds, onResultsChange) - const isLoading = computed(() => { if (isSearchLoading.value) return searchResults.value.length === 0 - if (selectedTab.value?.id === ManagerTab.Installed) { - return isLoadingInstalled.value - } - if ( - selectedTab.value?.id === ManagerTab.Workflow || - selectedTab.value?.id === ManagerTab.Missing - ) { - return isLoadingWorkflow.value - } + if (isTabLoading.value) return true return isInitialLoad.value }) @@ -511,7 +437,7 @@ watch( const getLoadingCount = () => { switch (selectedTab.value?.id) { - case ManagerTab.Installed: + case ManagerTab.AllInstalled: return comfyManagerStore.installedPacksIds?.size case ManagerTab.Workflow: return workflowPacks.value?.length @@ -581,10 +507,6 @@ whenever(selectedNodePack, async () => { if (packIndex !== -1) { selectedNodePacks.value.splice(packIndex, 1, mergedPack) } - const idx = displayPacks.value.findIndex((p) => p.id === mergedPack.id) - if (idx !== -1) { - displayPacks.value.splice(idx, 1, mergedPack) - } } }) diff --git a/src/workbench/extensions/manager/components/manager/button/PackInstallButton.vue b/src/workbench/extensions/manager/components/manager/button/PackInstallButton.vue index 3000a4a33..0aeab79fe 100644 --- a/src/workbench/extensions/manager/components/manager/button/PackInstallButton.vue +++ b/src/workbench/extensions/manager/components/manager/button/PackInstallButton.vue @@ -1,6 +1,6 @@ diff --git a/src/workbench/extensions/manager/components/manager/button/PackTryUpdateButton.vue b/src/workbench/extensions/manager/components/manager/button/PackTryUpdateButton.vue index 218aaf35f..9f681e010 100644 --- a/src/workbench/extensions/manager/components/manager/button/PackTryUpdateButton.vue +++ b/src/workbench/extensions/manager/components/manager/button/PackTryUpdateButton.vue @@ -1,7 +1,7 @@ diff --git a/src/workbench/extensions/manager/components/manager/infoPanel/InfoPanel.vue b/src/workbench/extensions/manager/components/manager/infoPanel/InfoPanel.vue index 9f25902cd..a25a13417 100644 --- a/src/workbench/extensions/manager/components/manager/infoPanel/InfoPanel.vue +++ b/src/workbench/extensions/manager/components/manager/infoPanel/InfoPanel.vue @@ -1,22 +1,15 @@