mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-03 12:10:11 +00:00
Feat: Add model import button to Vue model list popover. (#7085)
## Summary Adds a button to trigger the model upload on the Asset dropdown. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7085-Feat-Add-model-import-button-to-Vue-model-list-popover-2bd6d73d365081958c8ef23de55a341e) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
size="md"
|
||||
class="!h-10 [&>span]:hidden md:[&>span]:inline"
|
||||
:label="$t('assetBrowser.uploadModel')"
|
||||
:on-click="handleUploadClick"
|
||||
:on-click="showUploadDialog"
|
||||
>
|
||||
<template #icon>
|
||||
<i class="icon-[lucide--package-plus]" />
|
||||
@@ -70,17 +70,14 @@ import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import SearchBox from '@/components/input/SearchBox.vue'
|
||||
import BaseModalLayout from '@/components/widget/layout/BaseModalLayout.vue'
|
||||
import LeftSidePanel from '@/components/widget/panel/LeftSidePanel.vue'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import AssetFilterBar from '@/platform/assets/components/AssetFilterBar.vue'
|
||||
import AssetGrid from '@/platform/assets/components/AssetGrid.vue'
|
||||
import UploadModelDialog from '@/platform/assets/components/UploadModelDialog.vue'
|
||||
import UploadModelDialogHeader from '@/platform/assets/components/UploadModelDialogHeader.vue'
|
||||
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
|
||||
import { useAssetBrowser } from '@/platform/assets/composables/useAssetBrowser'
|
||||
import { useModelUpload } from '@/platform/assets/composables/useModelUpload'
|
||||
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
||||
import { assetService } from '@/platform/assets/services/assetService'
|
||||
import { formatCategoryLabel } from '@/platform/assets/utils/categoryLabel'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useModelToNodeStore } from '@/stores/modelToNodeStore'
|
||||
import { OnCloseKey } from '@/types/widgetTypes'
|
||||
|
||||
@@ -95,7 +92,6 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const dialogStore = useDialogStore()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'asset-select': [asset: AssetDisplayItem]
|
||||
@@ -189,25 +185,5 @@ function handleAssetSelectAndEmit(asset: AssetDisplayItem) {
|
||||
props.onSelect?.(asset)
|
||||
}
|
||||
|
||||
const { flags } = useFeatureFlags()
|
||||
const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled)
|
||||
|
||||
function handleUploadClick() {
|
||||
dialogStore.showDialog({
|
||||
key: 'upload-model',
|
||||
headerComponent: UploadModelDialogHeader,
|
||||
component: UploadModelDialog,
|
||||
props: {
|
||||
onUploadSuccess: async () => {
|
||||
await execute()
|
||||
}
|
||||
},
|
||||
dialogComponentProps: {
|
||||
pt: {
|
||||
header: 'py-0! pl-0!',
|
||||
content: 'p-0!'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const { isUploadButtonEnabled, showUploadDialog } = useModelUpload(execute)
|
||||
</script>
|
||||
|
||||
35
src/platform/assets/composables/useModelUpload.ts
Normal file
35
src/platform/assets/composables/useModelUpload.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import UploadModelDialog from '@/platform/assets/components/UploadModelDialog.vue'
|
||||
import UploadModelDialogHeader from '@/platform/assets/components/UploadModelDialogHeader.vue'
|
||||
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import type { UseAsyncStateReturn } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
|
||||
export function useModelUpload(
|
||||
execute?: UseAsyncStateReturn<AssetItem[], [], true>['execute']
|
||||
) {
|
||||
const dialogStore = useDialogStore()
|
||||
const { flags } = useFeatureFlags()
|
||||
const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled)
|
||||
|
||||
function showUploadDialog() {
|
||||
dialogStore.showDialog({
|
||||
key: 'upload-model',
|
||||
headerComponent: UploadModelDialogHeader,
|
||||
component: UploadModelDialog,
|
||||
props: {
|
||||
onUploadSuccess: async () => {
|
||||
await execute?.()
|
||||
}
|
||||
},
|
||||
dialogComponentProps: {
|
||||
pt: {
|
||||
header: 'py-0! pl-0!',
|
||||
content: 'p-0!'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return { isUploadButtonEnabled, showUploadDialog }
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import { useModelUpload } from '@/platform/assets/composables/useModelUpload'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
import type { FilterOption, OptionId } from './types'
|
||||
@@ -8,10 +10,12 @@ defineProps<{
|
||||
}>()
|
||||
|
||||
const filterSelected = defineModel<OptionId>('filterSelected')
|
||||
|
||||
const { isUploadButtonEnabled, showUploadDialog } = useModelUpload()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-secondary mb-4 flex gap-1 px-4">
|
||||
<div class="text-secondary mb-4 flex gap-1 px-4 justify-between">
|
||||
<div
|
||||
v-for="option in filterOptions"
|
||||
:key="option.id"
|
||||
@@ -30,5 +34,15 @@ const filterSelected = defineModel<OptionId>('filterSelected')
|
||||
>
|
||||
{{ option.name }}
|
||||
</div>
|
||||
<IconTextButton
|
||||
v-if="isUploadButtonEnabled"
|
||||
:label="$t('g.import')"
|
||||
type="secondary"
|
||||
@click="showUploadDialog"
|
||||
>
|
||||
<template #icon>
|
||||
<i class="icon-[lucide--folder-input]" />
|
||||
</template>
|
||||
</IconTextButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user