mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
## Summary When a workflow is loaded with missing models, users currently have no way to identify or resolve them from within the UI. This PR adds a full missing-model detection and resolution pipeline that surfaces missing models in the Errors tab, allowing users to install or import them without leaving the editor. ## Changes ### Missing Model Detection - Scan all COMBO widgets across root graph and subgraphs for model-like filenames during workflow load - Enrich candidates with embedded workflow metadata (url, hash, directory) when available - Verify asset-supported candidates against the asset store asynchronously to confirm installation status - Propagate missing model state to `executionErrorStore` alongside existing node/prompt errors ### Errors Tab UI — Model Resolution - Group missing models by directory (e.g. `checkpoints`, `loras`, `vae`) with collapsible category cards - Each model row displays: - Model name with copy-to-clipboard button - Expandable list of referencing nodes with locate-on-canvas button - **Library selector**: Pick an alternative from the user's existing models to substitute the missing model with one click - **URL import**: Paste a Civitai or HuggingFace URL to import a model directly; debounced metadata fetch shows filename and file size before confirming; type-mismatch warnings (e.g. importing a LoRA into checkpoints directory) are surfaced with an "Import Anyway" option - **Upgrade prompt**: In cloud environment, free-tier subscribers are shown an upgrade modal when attempting URL import - Separate "Import Not Supported" section for custom-node models that cannot be auto-resolved - Status card with live download progress, completion, failure, and category-mismatch states ### Canvas Integration - Highlight nodes and widgets that reference missing models with error indicators - Propagate missing-model badges through subgraph containers so issues are visible at every graph level ### Code Cleanup - Simplify `surfacePendingWarnings` in workflowService, remove stale widget-detected model merging logic - Add `flattenWorkflowNodes` utility to workflowSchema for traversing nested subgraph structures - Extract `MissingModelUrlInput`, `MissingModelLibrarySelect`, `MissingModelStatusCard` as focused single-responsibility components ## Testing - Unit tests for scan pipeline (`missingModelScan.test.ts`): enrichment, skip-installed, subgraph flattening - Unit tests for store (`missingModelStore.test.ts`): state management, removal helpers - Unit tests for interactions (`useMissingModelInteractions.test.ts`): combo select, URL input, import flow, library confirm - Component tests for `MissingModelCard` and error grouping (`useErrorGroups.test.ts`) - Updated `workflowService.test.ts` and `workflowSchema.test.ts` for new logic ## Review Focus - Missing model scan + enrichment pipeline in `missingModelScan.ts` - Interaction composable `useMissingModelInteractions.ts` — URL metadata fetch, library install, upload fallback - Store integration and canvas-level error propagation ## Screenshots https://github.com/user-attachments/assets/339a6d5b-93a3-43cd-98dd-0fb00681b66f ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9743-feat-Surface-missing-models-in-Errors-tab-Cloud-3206d73d365081678326d3a16c2165d8) by [Unito](https://www.unito.io)
84 lines
2.5 KiB
Vue
84 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import type { SelectContentEmits, SelectContentProps } from 'reka-ui'
|
|
import {
|
|
SelectContent,
|
|
SelectPortal,
|
|
SelectViewport,
|
|
useForwardPropsEmits
|
|
} from 'reka-ui'
|
|
import type { HTMLAttributes } from 'vue'
|
|
import { computed } from 'vue'
|
|
|
|
import { cn } from '@/utils/tailwindUtil'
|
|
|
|
import SelectScrollDownButton from './SelectScrollDownButton.vue'
|
|
import SelectScrollUpButton from './SelectScrollUpButton.vue'
|
|
|
|
defineOptions({
|
|
inheritAttrs: false
|
|
})
|
|
|
|
const {
|
|
position = 'popper',
|
|
// Safari has issues with click events on portaled content inside dialogs.
|
|
// Set disablePortal to true when using Select inside a Dialog on Safari.
|
|
// See: https://github.com/chakra-ui/ark/issues/1782
|
|
disablePortal = false,
|
|
class: className,
|
|
...restProps
|
|
} = defineProps<
|
|
SelectContentProps & {
|
|
class?: HTMLAttributes['class']
|
|
disablePortal?: boolean
|
|
}
|
|
>()
|
|
const emits = defineEmits<SelectContentEmits>()
|
|
|
|
const delegatedProps = computed(() => ({
|
|
position,
|
|
...restProps
|
|
}))
|
|
|
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|
</script>
|
|
|
|
<template>
|
|
<SelectPortal :disabled="disablePortal">
|
|
<SelectContent
|
|
v-bind="{ ...forwarded, ...$attrs }"
|
|
:class="
|
|
cn(
|
|
'relative z-3000 max-h-96 min-w-32 overflow-hidden',
|
|
'mt-2 rounded-lg p-2',
|
|
'bg-base-background text-base-foreground',
|
|
'border border-solid border-border-default',
|
|
'shadow-md',
|
|
'data-[state=closed]:animate-out data-[state=open]:animate-in',
|
|
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
|
|
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
position === 'popper' &&
|
|
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
|
className
|
|
)
|
|
"
|
|
>
|
|
<slot name="prepend" />
|
|
<SelectScrollUpButton />
|
|
<SelectViewport
|
|
:class="
|
|
cn(
|
|
'flex scrollbar-custom flex-col gap-0',
|
|
position === 'popper' &&
|
|
'h-(--reka-select-trigger-height) w-full min-w-(--reka-select-trigger-width)'
|
|
)
|
|
"
|
|
>
|
|
<slot />
|
|
</SelectViewport>
|
|
<SelectScrollDownButton />
|
|
</SelectContent>
|
|
</SelectPortal>
|
|
</template>
|