mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-02 20:22:08 +00:00
fix: use WidgetSelectDropdown for models (#6607)
## Summary As the commit says, the model loaders were broken in cloud if you enabled Vue Nodes (not a thing I think user does yet). This fixes it by configuring the `WidgetSelectDropdown` to load so the user load models like they would load a input or output asset. ## Review Focus Probably `useAssetWidgetData` to make sure it's idomatic. This part of [assetsStore](https://github.com/Comfy-Org/ComfyUI_frontend/pull/6607/files#diff-18a5914c9f12c16d9c9c3a9f6d0e203a9c00598414d3d1c8637da9ca77339d83R158-R234) as well. ## Screenshots <img width="1196" height="1005" alt="Screenshot 2025-11-05 at 5 34 22 PM" src="https://github.com/user-attachments/assets/804cd3c4-3370-4667-b606-bed52fcd6278" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6607-fix-use-WidgetSelectDropdown-for-models-2a36d73d36508143b185d06d736e4af9) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -1,10 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, provide, ref, watch } from 'vue'
|
||||
import { capitalize } from 'es-toolkit'
|
||||
import { computed, provide, ref, toRef, watch } from 'vue'
|
||||
|
||||
import { useWidgetValue } from '@/composables/graph/useWidgetValue'
|
||||
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
|
||||
import { t } from '@/i18n'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import FormDropdown from '@/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdown.vue'
|
||||
import { AssetKindKey } from '@/renderer/extensions/vueNodes/widgets/components/form/dropdown/types'
|
||||
import type {
|
||||
DropdownItem,
|
||||
FilterOption,
|
||||
LayoutMode,
|
||||
SelectedKey
|
||||
} from '@/renderer/extensions/vueNodes/widgets/components/form/dropdown/types'
|
||||
import WidgetLayoutField from '@/renderer/extensions/vueNodes/widgets/components/layout/WidgetLayoutField.vue'
|
||||
import { useAssetWidgetData } from '@/renderer/extensions/vueNodes/widgets/composables/useAssetWidgetData'
|
||||
import type { ResultItemType } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useAssetsStore } from '@/stores/assetsStore'
|
||||
@@ -16,21 +27,15 @@ import {
|
||||
filterWidgetProps
|
||||
} from '@/utils/widgetPropFilter'
|
||||
|
||||
import FormDropdown from './form/dropdown/FormDropdown.vue'
|
||||
import { AssetKindKey } from './form/dropdown/types'
|
||||
import type {
|
||||
DropdownItem,
|
||||
FilterOption,
|
||||
SelectedKey
|
||||
} from './form/dropdown/types'
|
||||
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
widget: SimplifiedWidget<string | number | undefined>
|
||||
modelValue: string | number | undefined
|
||||
nodeType?: string
|
||||
assetKind?: AssetKind
|
||||
allowUpload?: boolean
|
||||
uploadFolder?: ResultItemType
|
||||
isAssetMode?: boolean
|
||||
defaultLayoutMode?: LayoutMode
|
||||
}>()
|
||||
|
||||
provide(
|
||||
@@ -59,12 +64,26 @@ const combinedProps = computed(() => ({
|
||||
...transformCompatProps.value
|
||||
}))
|
||||
|
||||
const getAssetData = () => {
|
||||
if (props.isAssetMode && props.nodeType) {
|
||||
return useAssetWidgetData(toRef(() => props.nodeType))
|
||||
}
|
||||
return null
|
||||
}
|
||||
const assetData = getAssetData()
|
||||
|
||||
const filterSelected = ref('all')
|
||||
const filterOptions = ref<FilterOption[]>([
|
||||
{ id: 'all', name: 'All' },
|
||||
{ id: 'inputs', name: 'Inputs' },
|
||||
{ id: 'outputs', name: 'Outputs' }
|
||||
])
|
||||
const filterOptions = computed<FilterOption[]>(() => {
|
||||
if (props.isAssetMode) {
|
||||
const categoryName = assetData?.category.value ?? 'All'
|
||||
return [{ id: 'all', name: capitalize(categoryName) }]
|
||||
}
|
||||
return [
|
||||
{ id: 'all', name: 'All' },
|
||||
{ id: 'inputs', name: 'Inputs' },
|
||||
{ id: 'outputs', name: 'Outputs' }
|
||||
]
|
||||
})
|
||||
|
||||
const selectedSet = ref<Set<SelectedKey>>(new Set())
|
||||
|
||||
@@ -132,9 +151,16 @@ const outputItems = computed<DropdownItem[]>(() => {
|
||||
})
|
||||
|
||||
const allItems = computed<DropdownItem[]>(() => {
|
||||
if (props.isAssetMode && assetData) {
|
||||
return assetData.dropdownItems.value
|
||||
}
|
||||
return [...inputItems.value, ...outputItems.value]
|
||||
})
|
||||
const dropdownItems = computed<DropdownItem[]>(() => {
|
||||
if (props.isAssetMode) {
|
||||
return allItems.value
|
||||
}
|
||||
|
||||
switch (filterSelected.value) {
|
||||
case 'inputs':
|
||||
return inputItems.value
|
||||
@@ -169,7 +195,10 @@ const mediaPlaceholder = computed(() => {
|
||||
return t('widgets.uploadSelect.placeholder')
|
||||
})
|
||||
|
||||
const uploadable = computed(() => props.allowUpload === true)
|
||||
const uploadable = computed(() => {
|
||||
if (props.isAssetMode) return false
|
||||
return props.allowUpload === true
|
||||
})
|
||||
|
||||
const acceptTypes = computed(() => {
|
||||
// Be permissive with accept types because backend uses libraries
|
||||
@@ -186,6 +215,8 @@ const acceptTypes = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const layoutMode = ref<LayoutMode>(props.defaultLayoutMode ?? 'grid')
|
||||
|
||||
watch(
|
||||
localValue,
|
||||
(currentValue) => {
|
||||
@@ -313,6 +344,7 @@ function getMediaUrl(
|
||||
<FormDropdown
|
||||
v-model:selected="selectedSet"
|
||||
v-model:filter-selected="filterSelected"
|
||||
v-model:layout-mode="layoutMode"
|
||||
:items="dropdownItems"
|
||||
:placeholder="mediaPlaceholder"
|
||||
:multiple="false"
|
||||
|
||||
Reference in New Issue
Block a user