diff --git a/src/components/dialog/GlobalDialog.vue b/src/components/dialog/GlobalDialog.vue index 2074132b5..afc056d61 100644 --- a/src/components/dialog/GlobalDialog.vue +++ b/src/components/dialog/GlobalDialog.vue @@ -55,17 +55,4 @@ const dialogStore = useDialogStore() @apply p-2 2xl:p-[var(--p-dialog-content-padding)]; @apply pt-0; } - -.manager-dialog { - height: 80vh; - max-width: 1724px; - max-height: 1026px; -} - -@media (min-width: 3000px) { - .manager-dialog { - max-width: 2200px; - max-height: 1320px; - } -} diff --git a/src/components/widget/layout/BaseModalLayout.vue b/src/components/widget/layout/BaseModalLayout.vue index 325ca0ac6..0da7755af 100644 --- a/src/components/widget/layout/BaseModalLayout.vue +++ b/src/components/widget/layout/BaseModalLayout.vue @@ -2,7 +2,7 @@
@@ -111,6 +111,10 @@ const { contentTitle } = defineProps<{ contentTitle: string }>() +const isRightPanelOpen = defineModel('rightPanelOpen', { + default: false +}) + const BREAKPOINTS = { md: 880 } const PANEL_SIZES = { width: 'w-1/3', @@ -125,7 +129,6 @@ const breakpoints = useBreakpoints(BREAKPOINTS) const notMobile = breakpoints.greater('md') const isLeftPanelOpen = ref(true) -const isRightPanelOpen = ref(false) const mobileMenuOpen = ref(false) const hasRightPanel = computed(() => !!slots.rightPanel) diff --git a/src/composables/element/useResponsiveCollapse.ts b/src/composables/element/useResponsiveCollapse.ts deleted file mode 100644 index 4f1846865..000000000 --- a/src/composables/element/useResponsiveCollapse.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { breakpointsTailwind, useBreakpoints } from '@vueuse/core' -import { ref, watch } from 'vue' - -type BreakpointKey = keyof typeof breakpointsTailwind - -/** - * Composable for element with responsive collapsed state - * @param breakpointThreshold - Breakpoint at which the element should become collapsible - */ -export const useResponsiveCollapse = ( - breakpointThreshold: BreakpointKey = 'lg' -) => { - const breakpoints = useBreakpoints(breakpointsTailwind) - - const isSmallScreen = breakpoints.smallerOrEqual(breakpointThreshold) - const isOpen = ref(!isSmallScreen.value) - - /** - * Handles screen size changes to automatically open/close the element - * when crossing the breakpoint threshold - */ - const onIsSmallScreenChange = () => { - if (isSmallScreen.value && isOpen.value) { - isOpen.value = false - } else if (!isSmallScreen.value && !isOpen.value) { - isOpen.value = true - } - } - - watch(isSmallScreen, onIsSmallScreenChange) - - return { - breakpoints, - isOpen, - isSmallScreen, - - open: () => (isOpen.value = true), - close: () => (isOpen.value = false), - toggle: () => (isOpen.value = !isOpen.value) - } -} diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 65189f5b8..a856c3b0e 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -273,7 +273,7 @@ "noItems": "No items" }, "manager": { - "title": "Custom Nodes Manager", + "title": "Nodes Manager", "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", diff --git a/src/services/dialogService.ts b/src/services/dialogService.ts index 50b0223ce..e70b7fcb0 100644 --- a/src/services/dialogService.ts +++ b/src/services/dialogService.ts @@ -25,8 +25,6 @@ import type { ShowDialogOptions } from '@/stores/dialogStore' -import ManagerDialogContent from '@/workbench/extensions/manager/components/manager/ManagerDialogContent.vue' -import ManagerHeader from '@/workbench/extensions/manager/components/manager/ManagerHeader.vue' import ImportFailedNodeContent from '@/workbench/extensions/manager/components/manager/ImportFailedNodeContent.vue' import ImportFailedNodeFooter from '@/workbench/extensions/manager/components/manager/ImportFailedNodeFooter.vue' import ImportFailedNodeHeader from '@/workbench/extensions/manager/components/manager/ImportFailedNodeHeader.vue' @@ -152,32 +150,6 @@ export const useDialogService = () => { }) } - function showManagerDialog( - props: ComponentAttrs = {} - ) { - dialogStore.showDialog({ - key: 'global-manager', - component: ManagerDialogContent, - headerComponent: ManagerHeader, - dialogComponentProps: { - closable: true, - pt: { - pcCloseButton: { - root: { - class: 'bg-dialog-surface w-9 h-9 p-1.5 rounded-full text-white' - } - }, - header: { class: 'py-0! px-6 m-0! h-[68px]' }, - content: { - class: 'p-0! h-full w-[90vw] max-w-full flex-1 overflow-hidden' - }, - root: { class: 'manager-dialog' } - } - }, - props - }) - } - function parseError(error: Error) { const filename = 'fileName' in error @@ -419,20 +391,10 @@ export const useDialogService = () => { } } - function toggleManagerDialog( - props?: ComponentAttrs - ) { - if (dialogStore.isDialogOpen('global-manager')) { - dialogStore.closeDialog({ key: 'global-manager' }) - } else { - showManagerDialog(props) - } - } - function showLayoutDialog(options: { key: string component: Component - props: { onClose: () => void } + props: { onClose: () => void } & Record dialogComponentProps?: DialogComponentProps }) { const layoutDefaultProps: DialogComponentProps = { @@ -563,7 +525,6 @@ export const useDialogService = () => { showSettingsDialog, showAboutDialog, showExecutionErrorDialog, - showManagerDialog, showApiNodesSignInDialog, showSignInDialog, showSubscriptionRequiredDialog, @@ -573,7 +534,6 @@ export const useDialogService = () => { prompt, showErrorDialog, confirm, - toggleManagerDialog, showLayoutDialog, showImportFailedNodeDialog, showNodeConflictDialog diff --git a/src/workbench/extensions/manager/components/manager/ManagerDialogContent.vue b/src/workbench/extensions/manager/components/manager/ManagerDialog.vue similarity index 59% rename from src/workbench/extensions/manager/components/manager/ManagerDialogContent.vue rename to src/workbench/extensions/manager/components/manager/ManagerDialog.vue index c05f375e2..ad7657645 100644 --- a/src/workbench/extensions/manager/components/manager/ManagerDialogContent.vue +++ b/src/workbench/extensions/manager/components/manager/ManagerDialog.vue @@ -1,180 +1,218 @@ diff --git a/src/workbench/extensions/manager/components/manager/ManagerNavSidebar.vue b/src/workbench/extensions/manager/components/manager/ManagerNavSidebar.vue deleted file mode 100644 index 571b22ecf..000000000 --- a/src/workbench/extensions/manager/components/manager/ManagerNavSidebar.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/src/workbench/extensions/manager/components/manager/button/PackUpdateButton.vue b/src/workbench/extensions/manager/components/manager/button/PackUpdateButton.vue index 8057cc3c6..328b76ba1 100644 --- a/src/workbench/extensions/manager/components/manager/button/PackUpdateButton.vue +++ b/src/workbench/extensions/manager/components/manager/button/PackUpdateButton.vue @@ -3,9 +3,8 @@ v-tooltip.top=" hasDisabledUpdatePacks ? $t('manager.disabledNodesWontUpdate') : null " - variant="textonly" class="border" - size="sm" + :size :disabled="isUpdating" @click="updateAllPacks" > @@ -19,14 +18,20 @@ import { ref } from 'vue' import DotSpinner from '@/components/common/DotSpinner.vue' import Button from '@/components/ui/button/Button.vue' +import type { ButtonVariants } from '@/components/ui/button/button.variants' import type { components } from '@/types/comfyRegistryTypes' import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comfyManagerStore' type NodePack = components['schemas']['Node'] -const { nodePacks, hasDisabledUpdatePacks } = defineProps<{ +const { + nodePacks, + hasDisabledUpdatePacks, + size = 'sm' +} = defineProps<{ nodePacks: NodePack[] hasDisabledUpdatePacks?: boolean + size?: ButtonVariants['size'] }>() const isUpdating = ref(false) diff --git a/src/workbench/extensions/manager/components/manager/registrySearchBar/RegistrySearchBar.vue b/src/workbench/extensions/manager/components/manager/registrySearchBar/RegistrySearchBar.vue deleted file mode 100644 index dbb1150d6..000000000 --- a/src/workbench/extensions/manager/components/manager/registrySearchBar/RegistrySearchBar.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - diff --git a/src/workbench/extensions/manager/components/manager/registrySearchBar/SearchFilterDropdown.vue b/src/workbench/extensions/manager/components/manager/registrySearchBar/SearchFilterDropdown.vue deleted file mode 100644 index 973820c72..000000000 --- a/src/workbench/extensions/manager/components/manager/registrySearchBar/SearchFilterDropdown.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/src/workbench/extensions/manager/composables/nodePack/useMissingNodes.ts b/src/workbench/extensions/manager/composables/nodePack/useMissingNodes.ts index 96f1d4403..24daee309 100644 --- a/src/workbench/extensions/manager/composables/nodePack/useMissingNodes.ts +++ b/src/workbench/extensions/manager/composables/nodePack/useMissingNodes.ts @@ -14,7 +14,6 @@ import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comf /** * Composable to find missing NodePacks from workflow - * Uses the same filtering approach as ManagerDialogContent.vue * Automatically fetches workflow pack data when initialized * This is a shared singleton composable - all components use the same instance */ @@ -25,7 +24,6 @@ export const useMissingNodes = createSharedComposable(() => { const { workflowPacks, isLoading, error, startFetchWorkflowPacks } = useWorkflowPacks() - // Same filtering logic as ManagerDialogContent.vue const filterMissingPacks = (packs: components['schemas']['Node'][]) => packs.filter((pack) => !comfyManagerStore.isPackInstalled(pack.id)) diff --git a/src/workbench/extensions/manager/composables/nodePack/useUpdateAvailableNodes.ts b/src/workbench/extensions/manager/composables/nodePack/useUpdateAvailableNodes.ts index c18fcdf61..fd6f74e1d 100644 --- a/src/workbench/extensions/manager/composables/nodePack/useUpdateAvailableNodes.ts +++ b/src/workbench/extensions/manager/composables/nodePack/useUpdateAvailableNodes.ts @@ -7,7 +7,6 @@ import { useComfyManagerStore } from '@/workbench/extensions/manager/stores/comf /** * Composable to find NodePacks that have updates available - * Uses the same filtering approach as ManagerDialogContent.vue * Automatically fetches installed pack data when initialized */ export const useUpdateAvailableNodes = () => { @@ -34,7 +33,6 @@ export const useUpdateAvailableNodes = () => { return compare(latestVersion, installedVersion) > 0 } - // Same filtering logic as ManagerDialogContent.vue const filterOutdatedPacks = (packs: components['schemas']['Node'][]) => packs.filter(isOutdatedPack) diff --git a/src/workbench/extensions/manager/composables/useManagerDialog.ts b/src/workbench/extensions/manager/composables/useManagerDialog.ts new file mode 100644 index 000000000..9cf8fb01e --- /dev/null +++ b/src/workbench/extensions/manager/composables/useManagerDialog.ts @@ -0,0 +1,36 @@ +import { useDialogService } from '@/services/dialogService' +import { useDialogStore } from '@/stores/dialogStore' +import type { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes' +import ManagerDialog from '@/workbench/extensions/manager/components/manager/ManagerDialog.vue' + +const DIALOG_KEY = 'global-manager' + +export function useManagerDialog() { + const dialogService = useDialogService() + const dialogStore = useDialogStore() + + function hide() { + dialogStore.closeDialog({ key: DIALOG_KEY }) + } + + function show(initialTab?: ManagerTab) { + dialogService.showLayoutDialog({ + key: DIALOG_KEY, + component: ManagerDialog, + props: { + onClose: hide, + initialTab + }, + dialogComponentProps: { + pt: { + content: { class: '!px-0 overflow-hidden h-full !py-0' } + } + } + }) + } + + return { + show, + hide + } +} diff --git a/src/workbench/extensions/manager/composables/useManagerState.test.ts b/src/workbench/extensions/manager/composables/useManagerState.test.ts index c2f0f83c8..1ba41d107 100644 --- a/src/workbench/extensions/manager/composables/useManagerState.test.ts +++ b/src/workbench/extensions/manager/composables/useManagerState.test.ts @@ -53,6 +53,13 @@ vi.mock('@/stores/toastStore', () => ({ })) })) +vi.mock('@/workbench/extensions/manager/composables/useManagerDialog', () => ({ + useManagerDialog: vi.fn(() => ({ + show: vi.fn(), + hide: vi.fn() + })) +})) + describe('useManagerState', () => { beforeEach(() => { vi.clearAllMocks() diff --git a/src/workbench/extensions/manager/composables/useManagerState.ts b/src/workbench/extensions/manager/composables/useManagerState.ts index f8b7e095b..49c9debfd 100644 --- a/src/workbench/extensions/manager/composables/useManagerState.ts +++ b/src/workbench/extensions/manager/composables/useManagerState.ts @@ -7,6 +7,7 @@ import { api } from '@/scripts/api' import { useDialogService } from '@/services/dialogService' import { useCommandStore } from '@/stores/commandStore' import { useSystemStatsStore } from '@/stores/systemStatsStore' +import { useManagerDialog } from '@/workbench/extensions/manager/composables/useManagerDialog' import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes' export enum ManagerUIState { @@ -19,6 +20,7 @@ export function useManagerState() { const systemStatsStore = useSystemStatsStore() const { systemStats, isInitialized: systemInitialized } = storeToRefs(systemStatsStore) + const managerDialog = useManagerDialog() /** * The current manager UI state. @@ -186,11 +188,9 @@ export function useManagerState() { detail: t('manager.legacyMenuNotAvailable'), life: 3000 }) - dialogService.showManagerDialog({ initialTab: ManagerTab.All }) + await managerDialog.show(ManagerTab.All) } else { - dialogService.showManagerDialog( - options?.initialTab ? { initialTab: options.initialTab } : undefined - ) + await managerDialog.show(options?.initialTab) } break } diff --git a/src/workbench/extensions/manager/types/comfyManagerTypes.ts b/src/workbench/extensions/manager/types/comfyManagerTypes.ts index c53619719..bd7ab024e 100644 --- a/src/workbench/extensions/manager/types/comfyManagerTypes.ts +++ b/src/workbench/extensions/manager/types/comfyManagerTypes.ts @@ -20,12 +20,6 @@ export enum ManagerTab { UpdateAvailable = 'updateAvailable' } -export interface TabItem { - id: ManagerTab - label: string - icon: string -} - export type TaskLog = { taskName: string taskId: string @@ -37,11 +31,6 @@ export interface UseNodePacksOptions { maxConcurrent?: number } -export interface SearchOption { - id: T - label: string -} - export enum SortableAlgoliaField { Downloads = 'total_install', Created = 'create_time',