fix(upload-model): UI/UX improvements for Upload Model Dialog (#7969)

## Summary

Addresses UI/UX feedback on the Upload Model Dialog (BYOM feature).

## Changes

1. **Standardize link styling** - Use consistent `text-muted-foreground
underline` for all links in both URL input variants
2. **Increase warning/example text font size** - Changed from 12px
(`text-xs`) to 14px (`text-sm`) for better readability
3. **Fix padding inconsistency** - Aligned padding between model name
box and SingleSelect dropdown; moved "Not sure?" help text inline with
the label
4. **Add "Upload Another" button** - Allows users to upload multiple
models without closing and reopening the dialog

## Testing

- Verified link styling consistency across both Civitai and generic URL
input components
- Confirmed padding alignment in confirmation step
- Tested Upload Another button resets wizard to step 1

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7969-fix-upload-model-UI-UX-improvements-for-Upload-Model-Dialog-2e66d73d3650815c8184cedb3d02672d)
by [Unito](https://www.unito.io)
This commit is contained in:
Alexander Brown
2026-01-12 17:25:01 -08:00
committed by GitHub
parent dfb78b2e87
commit c6f2ae3130
7 changed files with 60 additions and 27 deletions

View File

@@ -2311,6 +2311,7 @@
"filterBy": "Filter by", "filterBy": "Filter by",
"findInLibrary": "Find it in the {type} section of the models library.", "findInLibrary": "Find it in the {type} section of the models library.",
"finish": "Finish", "finish": "Finish",
"importAnother": "Import Another",
"genericLinkPlaceholder": "Paste link here", "genericLinkPlaceholder": "Paste link here",
"jobId": "Job ID", "jobId": "Job ID",
"loadingModels": "Loading {type}...", "loadingModels": "Loading {type}...",

View File

@@ -5,7 +5,7 @@
{{ $t('assetBrowser.modelAssociatedWithLink') }} {{ $t('assetBrowser.modelAssociatedWithLink') }}
</p> </p>
<div <div
class="flex items-center gap-3 rounded-lg bg-secondary-background p-3" class="flex items-center gap-3 rounded-lg bg-secondary-background px-4 py-2"
> >
<img <img
v-if="previewImage" v-if="previewImage"
@@ -21,9 +21,15 @@
<!-- Model Type Selection --> <!-- Model Type Selection -->
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<label class=""> <div class="flex items-center gap-2">
{{ $t('assetBrowser.modelTypeSelectorLabel') }} <label>
</label> {{ $t('assetBrowser.modelTypeSelectorLabel') }}
</label>
<i class="icon-[lucide--circle-question-mark] text-muted-foreground" />
<span class="text-muted-foreground">
{{ $t('assetBrowser.notSureLeaveAsIs') }}
</span>
</div>
<SingleSelect <SingleSelect
v-model="modelValue" v-model="modelValue"
:label=" :label="
@@ -35,10 +41,6 @@
:disabled="isLoading" :disabled="isLoading"
data-attr="upload-model-step2-type-selector" data-attr="upload-model-step2-type-selector"
/> />
<div class="flex items-center gap-2">
<i class="icon-[lucide--circle-question-mark]" />
<span>{{ $t('assetBrowser.notSureLeaveAsIs') }}</span>
</div>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -48,6 +48,7 @@
@fetch-metadata="handleFetchMetadata" @fetch-metadata="handleFetchMetadata"
@upload="handleUploadModel" @upload="handleUploadModel"
@close="handleClose" @close="handleClose"
@import-another="resetWizard"
/> />
</div> </div>
</template> </template>
@@ -85,7 +86,8 @@ const {
canUploadModel, canUploadModel,
fetchMetadata, fetchMetadata,
uploadModel, uploadModel,
goToPreviousStep goToPreviousStep,
resetWizard
} = useUploadModelWizard(modelTypes) } = useUploadModelWizard(modelTypes)
async function handleFetchMetadata() { async function handleFetchMetadata() {

View File

@@ -80,21 +80,33 @@
<i v-if="isUploading" class="icon-[lucide--loader-circle] animate-spin" /> <i v-if="isUploading" class="icon-[lucide--loader-circle] animate-spin" />
<span>{{ $t('assetBrowser.upload') }}</span> <span>{{ $t('assetBrowser.upload') }}</span>
</Button> </Button>
<Button <template
v-else-if=" v-else-if="
currentStep === 3 && currentStep === 3 &&
(uploadStatus === 'success' || uploadStatus === 'processing') (uploadStatus === 'success' || uploadStatus === 'processing')
" "
variant="secondary"
data-attr="upload-model-step3-finish-button"
@click="emit('close')"
> >
{{ <Button
uploadStatus === 'processing' variant="muted-textonly"
? $t('g.close') size="lg"
: $t('assetBrowser.finish') data-attr="upload-model-step3-import-another-button"
}} @click="emit('importAnother')"
</Button> >
{{ $t('assetBrowser.importAnother') }}
</Button>
<Button
variant="secondary"
size="lg"
data-attr="upload-model-step3-finish-button"
@click="emit('close')"
>
{{
uploadStatus === 'processing'
? $t('g.close')
: $t('assetBrowser.finish')
}}
</Button>
</template>
<VideoHelpDialog <VideoHelpDialog
v-model="showCivitaiHelp" v-model="showCivitaiHelp"
video-url="https://media.comfy.org/compressed_768/civitai_howto.webm" video-url="https://media.comfy.org/compressed_768/civitai_howto.webm"
@@ -134,5 +146,6 @@ const emit = defineEmits<{
(e: 'fetchMetadata'): void (e: 'fetchMetadata'): void
(e: 'upload'): void (e: 'upload'): void
(e: 'close'): void (e: 'close'): void
(e: 'importAnother'): void
}>() }>()
</script> </script>

View File

@@ -20,7 +20,7 @@
:href="civitaiUrl" :href="civitaiUrl"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
class="text-muted underline" class="text-muted-foreground underline"
> >
{{ $t('assetBrowser.providerCivitai') }}</a {{ $t('assetBrowser.providerCivitai') }}</a
><span>,</span> ><span>,</span>
@@ -35,7 +35,7 @@
:href="huggingFaceUrl" :href="huggingFaceUrl"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
class="text-muted underline" class="text-muted-foreground underline"
> >
{{ $t('assetBrowser.providerHuggingFace') }} {{ $t('assetBrowser.providerHuggingFace') }}
</a> </a>
@@ -58,7 +58,7 @@
class="icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500" class="icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500"
/> />
</div> </div>
<p v-if="error" class="text-xs text-error"> <p v-if="error" class="text-sm text-error">
{{ error }} {{ error }}
</p> </p>
<p v-else-if="!flags.asyncModelUploadEnabled" class="text-foreground"> <p v-else-if="!flags.asyncModelUploadEnabled" class="text-foreground">

View File

@@ -11,7 +11,7 @@
<a <a
href="https://civitai.com/models" href="https://civitai.com/models"
target="_blank" target="_blank"
class="text-muted-foreground" class="text-muted-foreground underline"
> >
{{ $t('assetBrowser.uploadModelDescription2Link') }} {{ $t('assetBrowser.uploadModelDescription2Link') }}
</a> </a>
@@ -51,14 +51,14 @@
class="icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500" class="icon-[lucide--circle-check-big] absolute top-1/2 right-3 size-5 -translate-y-1/2 text-green-500"
/> />
</div> </div>
<p v-if="error" class="text-xs text-error"> <p v-if="error" class="text-sm text-error">
{{ error }} {{ error }}
</p> </p>
<i18n-t <i18n-t
v-else v-else
keypath="assetBrowser.civitaiLinkExample" keypath="assetBrowser.civitaiLinkExample"
tag="p" tag="p"
class="text-xs" class="text-sm"
> >
<template #example> <template #example>
<strong>{{ $t('assetBrowser.civitaiLinkExampleStrong') }}</strong> <strong>{{ $t('assetBrowser.civitaiLinkExampleStrong') }}</strong>
@@ -67,7 +67,7 @@
<a <a
href="https://civitai.com/models/10706/luisap-z-image-and-qwen-pixel-art-refiner?modelVersionId=2225295" href="https://civitai.com/models/10706/luisap-z-image-and-qwen-pixel-art-refiner?modelVersionId=2225295"
target="_blank" target="_blank"
class="text-muted-foreground" class="text-muted-foreground underline"
> >
{{ $t('assetBrowser.civitaiLinkExampleUrl') }} {{ $t('assetBrowser.civitaiLinkExampleUrl') }}
</a> </a>

View File

@@ -284,6 +284,20 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) {
} }
} }
function resetWizard() {
currentStep.value = 1
isFetchingMetadata.value = false
isUploading.value = false
uploadStatus.value = undefined
uploadError.value = ''
wizardData.value = {
url: '',
name: '',
tags: []
}
selectedModelType.value = undefined
}
return { return {
// State // State
currentStep, currentStep,
@@ -302,6 +316,7 @@ export function useUploadModelWizard(modelTypes: Ref<ModelTypeOption[]>) {
// Actions // Actions
fetchMetadata, fetchMetadata,
uploadModel, uploadModel,
goToPreviousStep goToPreviousStep,
resetWizard
} }
} }