mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 22:59:14 +00:00
## Summary Simplifies the Manager dialog by consolidating components and using BaseModalLayout with v-model support for right panel state. ## Changes - **Consolidation**: Merged ManagerDialogContent, ManagerHeader, ManagerNavSidebar, RegistrySearchBar, and SearchFilterDropdown into single ManagerDialog component - **Right panel**: Added v-model:rightPanelOpen to BaseModalLayout for external panel state control; clicking a node card now auto-opens the info panel - **Cleanup**: Removed unused useResponsiveCollapse composable, TabItem and SearchOption types - **UI tweaks**: Moved action buttons (Install All/Update All) from header-right-area to contentFilter area [manager-capture.webm](https://github.com/user-attachments/assets/2dd6092a-965d-4885-8ba6-6a2cc51f024a) 🤖 Generated with [Claude Code](https://claude.com/claude-code) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8041-refactor-Manager-dialog-simplification-2e86d73d3650815ba699e49a2748b682) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: github-actions <github-actions@github.com>
209 lines
6.4 KiB
TypeScript
209 lines
6.4 KiB
TypeScript
import { storeToRefs } from 'pinia'
|
|
import { computed, readonly } from 'vue'
|
|
|
|
import { t } from '@/i18n'
|
|
import { useToastStore } from '@/platform/updates/common/toastStore'
|
|
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 {
|
|
DISABLED = 'disabled',
|
|
LEGACY_UI = 'legacy',
|
|
NEW_UI = 'new'
|
|
}
|
|
|
|
export function useManagerState() {
|
|
const systemStatsStore = useSystemStatsStore()
|
|
const { systemStats, isInitialized: systemInitialized } =
|
|
storeToRefs(systemStatsStore)
|
|
const managerDialog = useManagerDialog()
|
|
|
|
/**
|
|
* The current manager UI state.
|
|
* Computed once and cached until dependencies change (which they don't during runtime).
|
|
* This follows Vue's conventions and provides better performance through caching.
|
|
*/
|
|
const managerUIState = readonly(
|
|
computed((): ManagerUIState => {
|
|
// Wait for systemStats to be initialized
|
|
if (!systemInitialized.value) {
|
|
// Default to DISABLED while loading
|
|
return ManagerUIState.DISABLED
|
|
}
|
|
|
|
// Get current values
|
|
const clientSupportsV4 =
|
|
api.getClientFeatureFlags().supports_manager_v4_ui ?? false
|
|
|
|
const serverSupportsV4 = api.getServerFeature(
|
|
'extension.manager.supports_v4'
|
|
)
|
|
|
|
// Check command line args first (highest priority)
|
|
// --enable-manager flag enables the manager (opposite of old --disable-manager)
|
|
const hasEnableManager =
|
|
systemStats.value?.system?.argv?.includes('--enable-manager')
|
|
|
|
// If --enable-manager is NOT present, manager is disabled
|
|
if (!hasEnableManager) {
|
|
return ManagerUIState.DISABLED
|
|
}
|
|
|
|
if (
|
|
systemStats.value?.system?.argv?.includes('--enable-manager-legacy-ui')
|
|
) {
|
|
return ManagerUIState.LEGACY_UI
|
|
}
|
|
|
|
// Both client and server support v4 = NEW_UI
|
|
if (clientSupportsV4 && serverSupportsV4 === true) {
|
|
return ManagerUIState.NEW_UI
|
|
}
|
|
|
|
// Server supports v4 but client doesn't = LEGACY_UI
|
|
if (serverSupportsV4 === true && !clientSupportsV4) {
|
|
return ManagerUIState.LEGACY_UI
|
|
}
|
|
|
|
// Server explicitly doesn't support v4 = LEGACY_UI
|
|
if (serverSupportsV4 === false) {
|
|
return ManagerUIState.LEGACY_UI
|
|
}
|
|
|
|
// If server feature flags haven't loaded yet, default to NEW_UI
|
|
// This is a temporary state - feature flags are exchanged immediately on WebSocket connection
|
|
// NEW_UI is the safest default since v2 API is the current standard
|
|
// If the server doesn't support v2, API calls will fail with 404 and be handled gracefully
|
|
if (serverSupportsV4 === undefined) {
|
|
return ManagerUIState.NEW_UI
|
|
}
|
|
|
|
// Should never reach here, but if we do, disable manager
|
|
return ManagerUIState.DISABLED
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Check if manager is enabled (not DISABLED)
|
|
*/
|
|
const isManagerEnabled = readonly(
|
|
computed((): boolean => {
|
|
return managerUIState.value !== ManagerUIState.DISABLED
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Check if manager UI is in NEW_UI mode
|
|
*/
|
|
const isNewManagerUI = readonly(
|
|
computed((): boolean => {
|
|
return managerUIState.value === ManagerUIState.NEW_UI
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Check if manager UI is in LEGACY_UI mode
|
|
*/
|
|
const isLegacyManagerUI = readonly(
|
|
computed((): boolean => {
|
|
return managerUIState.value === ManagerUIState.LEGACY_UI
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Check if install button should be shown (only in NEW_UI mode)
|
|
*/
|
|
const shouldShowInstallButton = readonly(
|
|
computed((): boolean => {
|
|
return isNewManagerUI.value
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Check if manager buttons should be shown (when manager is not disabled)
|
|
*/
|
|
const shouldShowManagerButtons = readonly(
|
|
computed((): boolean => {
|
|
return isManagerEnabled.value
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Opens the manager UI based on current state
|
|
* Centralizes the logic for opening manager across the app
|
|
* @param options - Optional configuration for opening the manager
|
|
* @param options.initialTab - Initial tab to show (for NEW_UI mode)
|
|
* @param options.legacyCommand - Legacy command to execute (for LEGACY_UI mode)
|
|
* @param options.showToastOnLegacyError - Whether to show toast on legacy command failure
|
|
* @param options.isLegacyOnly - If true, shows error in NEW_UI mode instead of opening manager
|
|
*/
|
|
const openManager = async (options?: {
|
|
initialTab?: ManagerTab
|
|
legacyCommand?: string
|
|
showToastOnLegacyError?: boolean
|
|
isLegacyOnly?: boolean
|
|
}): Promise<void> => {
|
|
const state = managerUIState.value
|
|
const dialogService = useDialogService()
|
|
const commandStore = useCommandStore()
|
|
|
|
switch (state) {
|
|
case ManagerUIState.DISABLED:
|
|
dialogService.showSettingsDialog('extension')
|
|
break
|
|
|
|
case ManagerUIState.LEGACY_UI: {
|
|
const command =
|
|
options?.legacyCommand || 'Comfy.Manager.Menu.ToggleVisibility'
|
|
try {
|
|
await commandStore.execute(command)
|
|
} catch {
|
|
// If legacy command doesn't exist
|
|
if (options?.showToastOnLegacyError !== false) {
|
|
useToastStore().add({
|
|
severity: 'error',
|
|
summary: t('g.error'),
|
|
detail: t('manager.legacyMenuNotAvailable'),
|
|
life: 3000
|
|
})
|
|
}
|
|
// Fallback to extensions panel if not showing toast
|
|
if (options?.showToastOnLegacyError === false) {
|
|
dialogService.showSettingsDialog('extension')
|
|
}
|
|
}
|
|
break
|
|
}
|
|
|
|
case ManagerUIState.NEW_UI:
|
|
if (options?.isLegacyOnly) {
|
|
// Legacy command is not available in NEW_UI mode
|
|
useToastStore().add({
|
|
severity: 'error',
|
|
summary: t('g.error'),
|
|
detail: t('manager.legacyMenuNotAvailable'),
|
|
life: 3000
|
|
})
|
|
await managerDialog.show(ManagerTab.All)
|
|
} else {
|
|
await managerDialog.show(options?.initialTab)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
return {
|
|
managerUIState,
|
|
isManagerEnabled,
|
|
isNewManagerUI,
|
|
isLegacyManagerUI,
|
|
shouldShowInstallButton,
|
|
shouldShowManagerButtons,
|
|
openManager
|
|
}
|
|
}
|