Skip to content

Conversation

@luke-mino-altherr
Copy link
Contributor

@luke-mino-altherr luke-mino-altherr commented Dec 9, 2025

Summary

Stores and displays base64-encoded preview images from Civitai during the model upload flow, uploading the preview as a separate asset linked to the model.

Changes

  • Schema: Added preview_image field to AssetMetadata schema
  • Service: Added uploadAssetFromBase64 method to convert base64 data to blob and upload via FormData
  • Upload Flow: Modified wizard to first upload preview image as asset, then link it to model via preview_id
  • UI: Display 56x56px preview thumbnail alongside model filename in confirmation and success steps

Review Focus

  • Base64 to blob conversion and FormData upload implementation
  • Sequential upload flow (preview first, then model with preview_id reference)

┆Issue is synchronized with this Notion page by Unito

@luke-mino-altherr luke-mino-altherr requested a review from a team as a code owner December 9, 2025 04:16
@luke-mino-altherr luke-mino-altherr added enhancement New feature or request area:models labels Dec 9, 2025
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 9, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

📝 Walkthrough

Walkthrough

Adds optional preview-image support to the model upload flow: schema, wizard state, a base64 asset upload helper, preview upload and preview_id propagation during main asset upload, and UI components updated to accept and render the preview image.

Changes

Cohort / File(s) Summary
UI Components
src/platform/assets/components/UploadModelConfirmation.vue, src/platform/assets/components/UploadModelProgress.vue
Added optional previewImage?: string prop; templates render an image preview when provided and adjust layout and alt text; relaxed metadata/modelType prop types to optional.
Dialog Integration
src/platform/assets/components/UploadModelDialog.vue
Wired :preview-image="wizardData.previewImage" into UploadModelConfirmation and UploadModelProgress to pass preview data through dialog steps.
Upload Wizard Logic
src/platform/assets/composables/useUploadModelWizard.ts
Made WizardData.metadata optional and added previewImage?: string; when metadata includes preview data, store it; upload preview (base64) first via new service method, capture preview_id and include it in main asset upload payload; continue main upload if preview upload fails.
Schema and Types
src/platform/assets/schemas/assetSchema.ts
Added optional preview_image: z.string().optional() to zAssetMetadata, updating inferred AssetMetadata to include preview_image.
Asset Service
src/platform/assets/services/assetService.ts
Added uploadAssetFromBase64(...): validates data URL, converts to Blob, sends FormData POST to assets endpoint, throws on non-OK, returns parsed asset with created_new; exported from service alongside uploadAssetFromUrl.

Sequence Diagram

sequenceDiagram
    participant UI as Upload Dialog UI
    participant Wizard as useUploadModelWizard
    participant Service as Asset Service
    participant API as Backend API

    UI->>Wizard: request metadata for model URL
    Wizard->>API: GET /assets/metadata
    API-->>Wizard: metadata (may include preview_image)
    Wizard->>Wizard: store previewImage

    alt preview_image present
        Wizard->>Service: uploadAssetFromBase64(previewImage, name)
        Service->>API: POST /assets (FormData with file)
        API-->>Service: preview asset response (id)
        Service-->>Wizard: preview_id
    else no preview_image
        Wizard->>Wizard: preview_id = null
    end

    Wizard->>Service: uploadAssetFromUrl(asset_url, preview_id?)
    Service->>API: POST /assets (payload includes preview_id if set)
    API-->>Service: asset response
    Service-->>Wizard: upload result
    Wizard-->>UI: update progress/state (include previewImage)
Loading

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch luke-mino-altherr/civitai-image-preview

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5774a90 and 3db5fff.

📒 Files selected for processing (6)
  • src/platform/assets/components/UploadModelConfirmation.vue (2 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (2 hunks)
  • src/platform/assets/components/UploadModelProgress.vue (2 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (4 hunks)
  • src/platform/assets/schemas/assetSchema.ts (1 hunks)
  • src/platform/assets/services/assetService.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
🧠 Learnings (16)
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: User-friendly and actionable error messages in error handling

Applied to files:

  • src/platform/assets/services/assetService.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Use VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Use Suspense for async components

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use Teleport/Suspense when needed for component rendering

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Implement proper error handling in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
🧬 Code graph analysis (1)
src/platform/assets/services/assetService.ts (2)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (74-74)
src/scripts/api.ts (1)
  • api (1289-1289)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (9)
src/platform/assets/schemas/assetSchema.ts (1)

57-57: LGTM! Schema extension is clean and appropriate.

The optional preview_image field correctly extends AssetMetadata to support base64-encoded preview data. Using .optional() is the correct Zod v3 pattern.

src/platform/assets/components/UploadModelDialog.vue (1)

17-17: LGTM! Preview image prop bindings are correct.

The :preview-image bindings correctly wire wizardData.previewImage through to the confirmation and progress steps, enabling preview display throughout the upload flow.

Also applies to: 27-27

src/platform/assets/services/assetService.ts (2)

395-446: LGTM! Base64 upload implementation is solid.

The data URL validation, Blob conversion, FormData construction, and error handling are all correct. The detailed error messages are appropriate for internal debugging as confirmed by the author.


458-459: LGTM! Service exports are complete.

Both uploadAssetFromUrl and uploadAssetFromBase64 are correctly exported, making the new preview upload capability available to the wizard.

src/platform/assets/components/UploadModelProgress.vue (1)

72-74: LGTM! Props are correctly typed.

The optional props (metadata?, modelType?, previewImage?) correctly reflect that preview data may not always be available in all states.

src/platform/assets/composables/useUploadModelWizard.ts (4)

12-12: LGTM! Interface changes properly support optional preview data.

The metadata? and previewImage? fields correctly reflect that preview data is optional throughout the wizard flow.

Also applies to: 15-15


94-95: LGTM! Preview image storage is straightforward.

Storing metadata.preview_image into wizardData.previewImage correctly propagates the preview through the wizard state.


140-166: LGTM! Preview upload orchestration is well-designed.

The sequential upload flow (preview first, then model with preview_id) is correct. Key strengths:

  • Extension extraction from data URL MIME type handles various formats
  • jpeg → jpg mapping is correct
  • Fallback to 'png' is reasonable
  • Try/catch ensures main upload continues even if preview fails
  • Error logging aids debugging

177-177: LGTM! Preview ID propagation completes the flow.

Including preview_id in the final upload payload correctly links the preview asset to the model asset.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/09/2025, 11:45:18 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/10/2025, 12:30:15 AM UTC

📈 Summary

  • Total Tests: 488
  • Passed: 467 ✅
  • Failed: 0
  • Flaky: 12 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 458 / ❌ 0 / ⚠️ 12 / ⏭️ 9
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

Bundle Size Report

Summary

  • Raw size: 17.1 MB baseline 17.1 MB — 🔴 +2.95 kB
  • Gzip: 3.39 MB baseline 3.38 MB — 🔴 +544 B
  • Brotli: 2.6 MB baseline 2.6 MB — 🔴 +655 B
  • Bundles: 97 current • 97 baseline • 37 added / 37 removed

Category Glance
UI Components 🔴 +1.98 kB (178 kB) · App Entry Points 🔴 +968 B (3.22 MB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · Graph Workspace ⚪ 0 B (988 kB) · Panels & Settings ⚪ 0 B (298 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.22 MB (baseline 3.22 MB) • 🔴 +968 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CDex3DwY.js (new) 3 MB 🔴 +3 MB 🔴 +623 kB 🔴 +474 kB
assets/index-H0G4eM5E.js (removed) 3 MB 🟢 -3 MB 🟢 -623 kB 🟢 -474 kB
assets/index-3thAHLlq.js (removed) 223 kB 🟢 -223 kB 🟢 -47.6 kB 🟢 -39.2 kB
assets/index-BBj0epJv.js (new) 223 kB 🔴 +223 kB 🔴 +47.6 kB 🔴 +39.3 kB
assets/index-DdZyzLtR.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -231 B
assets/index-nrA6lnea.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +231 B

Status: 3 added / 3 removed

Graph Workspace — 988 kB (baseline 988 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-DkslEKLs.js (removed) 988 kB 🟢 -988 kB 🟢 -191 kB 🟢 -145 kB
assets/GraphView-Dw28xL1J.js (new) 988 kB 🔴 +988 kB 🔴 +191 kB 🔴 +145 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-CfvzKUOW.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.9 kB
assets/UserSelectView-DXC8etFo.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.9 kB

Status: 1 added / 1 removed

Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-B6OLgVfC.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/CreditsPanel-DXDYFnCb.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.15 kB 🔴 +4.49 kB
assets/KeybindingPanel-BLuobXLz.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.01 kB
assets/KeybindingPanel-DmTUBtN5.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.02 kB
assets/ExtensionPanel-BaCpLkx0.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.58 kB 🟢 -2.26 kB
assets/ExtensionPanel-VFdPlmzT.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.26 kB
assets/AboutPanel--1dxLDob.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/AboutPanel-D_5Y4s8o.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.2 kB
assets/ServerConfigPanel-DDqKdHd9.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/ServerConfigPanel-ozGsIiyG.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/UserPanel-CAAm0TpQ.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-Cjyc4pqe.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 178 kB (baseline 176 kB) • 🔴 +1.98 kB

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-CvZL0JI6.js (new) 53.9 kB 🔴 +53.9 kB 🔴 +8.52 kB 🔴 +7.31 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-DQX2fy_K.js (removed) 53.9 kB 🟢 -53.9 kB 🟢 -8.52 kB 🟢 -7.31 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CcyzCSif.js (removed) 48.1 kB 🟢 -48.1 kB 🟢 -10.4 kB 🟢 -9 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DViTv22p.js (new) 48.1 kB 🔴 +48.1 kB 🔴 +10.4 kB 🔴 +8.98 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-Bkpe_g-S.js (new) 48 kB 🔴 +48 kB 🔴 +10.6 kB 🔴 +9.32 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-zvU7S2zS.js (removed) 46 kB 🟢 -46 kB 🟢 -10.3 kB 🟢 -8.99 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BXJWV81N.js (new) 12.9 kB 🔴 +12.9 kB 🔴 +3.37 kB 🔴 +2.96 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CYRi_U1f.js (removed) 12.9 kB 🟢 -12.9 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/ComfyQueueButton-B3P0aYrK.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.21 kB
assets/ComfyQueueButton-DeYx2uYj.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/MediaTitle.vue_vue_type_script_setup_true_lang-BnRaUUNj.js (removed) 897 B 🟢 -897 B 🟢 -503 B 🟢 -434 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-VNehejMf.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +430 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-BkTMAMst.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CMkR1knv.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-6ZIklFyS.js 2.26 kB 2.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-B1Oyd_f3.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.84 kB 🟢 -1.58 kB
assets/keybindingService-DEygpPAw.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.57 kB
assets/audioService-BDn-_Q4R.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +963 B 🔴 +827 B
assets/audioService-o_aOTCYb.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -963 B 🟢 -824 B
assets/serverConfigStore-L3qzi_1Z.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 3.18 kB (baseline 3.18 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CoWjarGl.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +651 B 🔴 +554 B
assets/audioUtils-CQcgEM8G.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -652 B 🟢 -578 B
assets/mathUtil-CD4DsosH.js 1.32 kB 1.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DJFoH6N_.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BZV8aGUB.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-CkvDSSUa.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-Cmu0_BY4.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Bz22sFex.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-cV_e_qh3.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.24 kB 🟢 -4.63 kB
assets/WidgetRecordAudio-vlTJX3F3.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.64 kB
assets/AudioPreviewPlayer-Bs2-GtpK.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.4 kB 🔴 +3.04 kB
assets/AudioPreviewPlayer-BXozKGOh.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.4 kB 🟢 -3.04 kB
assets/WidgetGalleria-CNyGFoa9.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.31 kB
assets/WidgetGalleria-hgYGepry.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.3 kB
assets/WidgetColorPicker-C5HaOXEj.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-CjIpU-Mv.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.37 kB 🔴 +1.23 kB
assets/WidgetMarkdown-CGHRD6Zc.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.12 kB
assets/WidgetMarkdown-D_eigofH.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetTextarea-DVP1dHoB.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.16 kB 🔴 +1.04 kB
assets/WidgetTextarea-xwWA8f94.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.17 kB 🟢 -1.04 kB
assets/WidgetAudioUI-C2e9qD-1.js (new) 2.85 kB 🔴 +2.85 kB 🔴 +1.16 kB 🔴 +1.05 kB
assets/WidgetAudioUI-CiVlmlg6.js (removed) 2.85 kB 🟢 -2.85 kB 🟢 -1.16 kB 🟢 -1.06 kB
assets/WidgetInputText-BMo5dYVp.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -917 B 🟢 -824 B
assets/WidgetInputText-CUe7MCp2.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +914 B 🔴 +854 B
assets/MediaImageBottom-Czle8Zw6.js (removed) 1.57 kB 🟢 -1.57 kB 🟢 -742 B 🟢 -649 B
assets/MediaImageBottom-YNpVnTVi.js (new) 1.57 kB 🔴 +1.57 kB 🔴 +738 B 🔴 +649 B
assets/MediaAudioBottom-Btur6eQk.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -739 B 🟢 -655 B
assets/MediaAudioBottom-HqKYqOyq.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +742 B 🔴 +656 B
assets/MediaVideoBottom-BWpl0bk7.js (removed) 1.52 kB 🟢 -1.52 kB 🟢 -739 B 🟢 -655 B
assets/MediaVideoBottom-wZLZyvv4.js (new) 1.52 kB 🔴 +1.52 kB 🔴 +737 B 🔴 +658 B
assets/Media3DBottom-B9pRzSH0.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +732 B 🔴 +652 B
assets/Media3DBottom-C-tuaM3s.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -730 B 🟢 -651 B
assets/Media3DTop-B0PibdgK.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -765 B 🟢 -655 B
assets/Media3DTop-Bfvm5Z-p.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +763 B 🔴 +655 B
assets/WidgetSelect-CtskdY90.js (new) 655 B 🔴 +655 B 🔴 +341 B 🔴 +288 B
assets/WidgetSelect-DjRG_6s2.js (removed) 655 B 🟢 -655 B 🟢 -343 B 🟢 -288 B
assets/WidgetInputNumber-DaWrBskH.js (new) 595 B 🔴 +595 B 🔴 +328 B 🔴 +279 B
assets/WidgetInputNumber-DTxv-fZy.js (removed) 595 B 🟢 -595 B 🟢 -330 B 🟢 -275 B
assets/Load3D-BMkhMnGt.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +224 B
assets/Load3D-CSFXC_N3.js (removed) 424 B 🟢 -424 B 🟢 -268 B 🟢 -223 B
assets/WidgetLegacy-DiE8_OgK.js (removed) 364 B 🟢 -364 B 🟢 -239 B 🟢 -194 B
assets/WidgetLegacy-DXtEibAN.js (new) 364 B 🔴 +364 B 🔴 +237 B 🔴 +224 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BPDWO8-i.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-BtY1hGDO.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-ehTZdDBw.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BC3OlaIn.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BsqN8-W1.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CK2saYDx.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cm5kR4Hi.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CMrh-uxB.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DlUIOit1.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DNu_xoP2.js 282 kB 282 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DpcvlpZe.js 303 kB 303 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-IyjOYIl-.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-DhnqAfj7.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-DFci1T8T.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-D6b0vE-q.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 17 added / 17 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/platform/assets/composables/useUploadModelWizard.ts (1)

138-165: Sequential preview → model upload flow is correct; consider two small refinements

The sequencing and error handling look good:

  • Preview is uploaded first when wizardData.previewImage is present.
  • On success, previewId is captured and passed as preview_id to uploadAssetFromUrl.
  • If preview upload fails, you log the error and still proceed with the model upload, which matches the non‑blocking requirement.

Two optional refinements to consider:

  1. File name vs. content type

    You always name the preview ${filename}_preview.png, even though the underlying Blob MIME type comes from the data URL. If you care about extensions matching content, you could derive an extension from wizardData.previewImage:

    const ext =
      wizardData.value.previewImage.startsWith('data:image/jpeg') ? 'jpg' : 'png'
    const previewName = `${filename}_preview.${ext}`
  2. Awareness of orphan previews

    If the model upload fails after a successful preview upload, you’ll end up with an unreferenced preview asset. This is a reasonable tradeoff for now, but it’s worth being aware of in case you later add cleanup or retry logic.

Overall, the implementation meets the stated behavior.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0a99a0 and ddc1ff9.

📒 Files selected for processing (6)
  • src/platform/assets/components/UploadModelConfirmation.vue (2 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (2 hunks)
  • src/platform/assets/components/UploadModelProgress.vue (2 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (5 hunks)
  • src/platform/assets/schemas/assetSchema.ts (1 hunks)
  • src/platform/assets/services/assetService.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/components/UploadModelDialog.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/services/assetService.ts
🧠 Learnings (2)
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/services/assetService.ts
🧬 Code graph analysis (2)
src/platform/assets/composables/useUploadModelWizard.ts (1)
src/platform/assets/services/assetService.ts (1)
  • assetService (459-459)
src/platform/assets/services/assetService.ts (3)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (74-74)
src/scripts/api.ts (1)
  • api (1289-1289)
src/i18n.ts (1)
  • st (208-210)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (3)
src/platform/assets/components/UploadModelDialog.vue (1)

17-18: Preview image wiring looks correct

wizardData.previewImage is correctly passed to both confirmation and progress steps via preview-image and matches the children’s previewImage?: string | null props, so the data flow is sound.

Also applies to: 27-28

src/platform/assets/schemas/assetSchema.ts (1)

49-59: Schema extension for preview_image is straightforward and type-safe

Adding preview_image: z.string().optional() cleanly extends AssetMetadata and aligns with how the wizard consumes it as an optional string.

If the backend spec guarantees this is always a data URL (vs. arbitrary string), it might be worth documenting that in a comment for future maintainers, but it’s not required for correctness.

src/platform/assets/composables/useUploadModelWizard.ts (1)

8-14: Wizard data and metadata mapping for previewImage are consistent

Adding previewImage: string | null to WizardData, initializing it to null, and then assigning metadata.preview_image || null in fetchMetadata gives you a clean, well-typed flow from the backend schema into the wizard state. This also ensures old previews are cleared when new metadata lacks a preview.

No issues here.

Also applies to: 28-34, 92-94

@luke-mino-altherr luke-mino-altherr force-pushed the luke-mino-altherr/civitai-image-preview branch from ddc1ff9 to e05b960 Compare December 9, 2025 04:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddc1ff9 and e05b960.

📒 Files selected for processing (6)
  • src/platform/assets/components/UploadModelConfirmation.vue (2 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (2 hunks)
  • src/platform/assets/components/UploadModelProgress.vue (2 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (5 hunks)
  • src/platform/assets/schemas/assetSchema.ts (1 hunks)
  • src/platform/assets/services/assetService.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
  • src/platform/assets/schemas/assetSchema.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
🧠 Learnings (4)
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/schemas/assetSchema.ts
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Prefer `useModel` to separately defining a prop and emit in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelConfirmation.vue
🧬 Code graph analysis (2)
src/platform/assets/services/assetService.ts (2)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (74-74)
src/scripts/api.ts (1)
  • api (1289-1289)
src/platform/assets/composables/useUploadModelWizard.ts (1)
src/platform/assets/services/assetService.ts (1)
  • assetService (463-463)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: test
🔇 Additional comments (11)
src/platform/assets/components/UploadModelConfirmation.vue (2)

7-19: Preview image rendering looks good with proper accessibility.

The conditional rendering and alt text fallback are implemented correctly. The 56×56px preview with object-cover provides consistent visual presentation.

One consideration: the previewImage is a base64 data URL sourced from Civitai metadata. While this is a trusted source in the current flow, ensure the data URL is validated upstream (in the composable or service) to contain only expected image MIME types (data:image/png;base64, or similar) to prevent potential XSS if the source changes in the future.


51-54: Props definition follows Vue 3.5 conventions.

The optional previewImage prop is correctly typed as string | null and uses the modern TypeScript-first prop declaration style.

src/platform/assets/components/UploadModelDialog.vue (2)

17-17: Preview image prop correctly wired to confirmation step.

The binding wizardData.previewImage is correctly passed to the child component.


27-27: Preview image prop correctly wired to progress step.

Consistent with the confirmation step, the preview image is passed through to display in the success state.

src/platform/assets/schemas/assetSchema.ts (1)

57-57: Schema extension is correct and follows existing patterns.

The preview_image field uses the same z.string().optional() pattern as other optional fields in the schema. This correctly extends AssetMetadata to include the base64 preview image data.

src/platform/assets/components/UploadModelProgress.vue (2)

27-45: Success state preview rendering is well-implemented.

The preview image block integrates cleanly with the existing success state layout. The flex-row items-center gap-3 alignment ensures proper visual flow when the image is present, and the conditional v-if="previewImage" correctly handles the absent-image case without layout issues.


69-75: Props definition is correct and complete.

All props are properly typed, and the optional previewImage follows the same pattern as the confirmation component.

src/platform/assets/composables/useUploadModelWizard.ts (3)

10-16: WizardData interface correctly extended with preview image field.

The previewImage: string | null type aligns with how it's used throughout the wizard flow.


96-98: Preview image storage from metadata is correct.

The nullish coalescing to null ensures consistent typing when preview_image is undefined.


159-169: Model upload correctly includes optional preview_id.

The preview_id is only included when the preview upload succeeds, which maintains backward compatibility with the API when no preview is available.

src/platform/assets/services/assetService.ts (1)

458-459: Exporting uploadAssetFromBase64 from the asset service looks correct

Including uploadAssetFromBase64 alongside uploadAssetFromUrl in the returned service object is consistent with the existing API surface and enables clean consumption from composables.

Comment on lines +406 to +446
async function uploadAssetFromBase64(params: {
data: string
name: string
tags?: string[]
user_metadata?: Record<string, any>
}): Promise<AssetItem & { created_new: boolean }> {
// Validate that data is a data URL
if (!params.data || !params.data.startsWith('data:')) {
throw new Error(
'Invalid data URL: expected a string starting with "data:"'
)
}

// Convert base64 data URL to Blob
const blob = await fetch(params.data).then((r) => r.blob())

// Create FormData and append the blob
const formData = new FormData()
formData.append('file', blob, params.name)

if (params.tags) {
formData.append('tags', JSON.stringify(params.tags))
}

if (params.user_metadata) {
formData.append('user_metadata', JSON.stringify(params.user_metadata))
}

const res = await api.fetchApi(ASSETS_ENDPOINT, {
method: 'POST',
body: formData
})

if (!res.ok) {
throw new Error(
`Failed to upload asset from base64: ${res.status} ${res.statusText}`
)
}

return await res.json()
}
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

uploadAssetFromBase64 implementation is solid; align error handling & i18n with uploadAssetFromUrl

The data URL guard, Blob conversion, and FormData upload look correct. To keep UX and localization consistent with uploadAssetFromUrl, consider reusing the same localized error message (assetBrowser.errorUploadFailed) instead of hard-coded English strings and interpolated status text:

   async function uploadAssetFromBase64(params: {
     data: string
     name: string
     tags?: string[]
     user_metadata?: Record<string, any>
   }): Promise<AssetItem & { created_new: boolean }> {
-    // Validate that data is a data URL
-    if (!params.data || !params.data.startsWith('data:')) {
-      throw new Error(
-        'Invalid data URL: expected a string starting with "data:"'
-      )
-    }
+    // Validate that data is a data URL
+    if (!params.data || !params.data.startsWith('data:')) {
+      throw new Error(
+        st(
+          'assetBrowser.errorUploadFailed',
+          'Failed to upload asset. Please try again.'
+        )
+      )
+    }
@@
-    const res = await api.fetchApi(ASSETS_ENDPOINT, {
+    const res = await api.fetchApi(ASSETS_ENDPOINT, {
       method: 'POST',
       body: formData
     })
 
-    if (!res.ok) {
-      throw new Error(
-        `Failed to upload asset from base64: ${res.status} ${res.statusText}`
-      )
-    }
+    if (!res.ok) {
+      throw new Error(
+        st(
+          'assetBrowser.errorUploadFailed',
+          'Failed to upload asset. Please try again.'
+        )
+      )
+    }
 
     return await res.json()
   }

This keeps failure behavior consistent across both upload paths and avoids leaking raw status text to end users while respecting the existing i18n pattern.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function uploadAssetFromBase64(params: {
data: string
name: string
tags?: string[]
user_metadata?: Record<string, any>
}): Promise<AssetItem & { created_new: boolean }> {
// Validate that data is a data URL
if (!params.data || !params.data.startsWith('data:')) {
throw new Error(
'Invalid data URL: expected a string starting with "data:"'
)
}
// Convert base64 data URL to Blob
const blob = await fetch(params.data).then((r) => r.blob())
// Create FormData and append the blob
const formData = new FormData()
formData.append('file', blob, params.name)
if (params.tags) {
formData.append('tags', JSON.stringify(params.tags))
}
if (params.user_metadata) {
formData.append('user_metadata', JSON.stringify(params.user_metadata))
}
const res = await api.fetchApi(ASSETS_ENDPOINT, {
method: 'POST',
body: formData
})
if (!res.ok) {
throw new Error(
`Failed to upload asset from base64: ${res.status} ${res.statusText}`
)
}
return await res.json()
}
async function uploadAssetFromBase64(params: {
data: string
name: string
tags?: string[]
user_metadata?: Record<string, any>
}): Promise<AssetItem & { created_new: boolean }> {
// Validate that data is a data URL
if (!params.data || !params.data.startsWith('data:')) {
throw new Error(
st(
'assetBrowser.errorUploadFailed',
'Failed to upload asset. Please try again.'
)
)
}
// Convert base64 data URL to Blob
const blob = await fetch(params.data).then((r) => r.blob())
// Create FormData and append the blob
const formData = new FormData()
formData.append('file', blob, params.name)
if (params.tags) {
formData.append('tags', JSON.stringify(params.tags))
}
if (params.user_metadata) {
formData.append('user_metadata', JSON.stringify(params.user_metadata))
}
const res = await api.fetchApi(ASSETS_ENDPOINT, {
method: 'POST',
body: formData
})
if (!res.ok) {
throw new Error(
st(
'assetBrowser.errorUploadFailed',
'Failed to upload asset. Please try again.'
)
)
}
return await res.json()
}
🤖 Prompt for AI Agents
In src/platform/assets/services/assetService.ts around lines 406 to 446, replace
the hard-coded English error thrown on upload failure with the existing i18n
error used by uploadAssetFromUrl (assetBrowser.errorUploadFailed) so user-facing
messages are localized and consistent; do not surface raw HTTP statusText to end
users — if you need the status for diagnostics, include it in a debug/process
log or attach it to an internal error property but throw the localized message
to callers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are internal facing errors. The current error messages give us more detail about what actually went wrong

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@luke-mino-altherr Understood! That makes sense for internal tooling—keeping the detailed status information (${res.status} ${res.statusText}) is valuable for debugging. I'll leave the error messages as-is. 👍


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: User-friendly and actionable error messages in error handling

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/platform/assets/composables/useUploadModelWizard.ts (1)

142-158: Preview upload has good error resilience, but hardcodes PNG extension.

The try-catch pattern that logs and continues on preview failure is appropriate—model upload shouldn't be blocked by preview issues.

However, the filename at line 150 still hardcodes .png regardless of the actual image format in the base64 data. As previously noted, this can cause MIME type mismatches if Civitai returns JPEG or WebP previews.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e05b960 and 031b504.

📒 Files selected for processing (1)
  • src/platform/assets/composables/useUploadModelWizard.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
🧠 Learnings (1)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: lint-and-format
  • GitHub Check: test
🔇 Additional comments (4)
src/platform/assets/composables/useUploadModelWizard.ts (4)

15-15: LGTM! Clean type definition for preview image.

The nullable string type appropriately handles the optional nature of preview images.


36-37: LGTM! Proper initialization.

The previewImage field is correctly initialized to null, consistent with the interface definition.


96-97: LGTM! Clean metadata extraction.

The preview image is correctly extracted from metadata with proper null handling.


168-169: LGTM! Clean integration of preview_id.

The preview_id is correctly passed to the upload call, with proper handling of the undefined case when no preview exists.

// Upload preview image first if available
if (wizardData.value.previewImage) {
try {
const baseFilename = filename.split('.')[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider more robust extension stripping.

split('.')[0] only captures text before the first dot, so my.model.safetensors becomes my. Consider using filename.replace(/\.[^.]+$/, '') or finding the last dot index to preserve the full base name.

Apply this diff to improve base filename extraction:

-        const baseFilename = filename.split('.')[0]
+        const lastDotIndex = filename.lastIndexOf('.')
+        const baseFilename = lastDotIndex !== -1 ? filename.slice(0, lastDotIndex) : filename
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const baseFilename = filename.split('.')[0]
const lastDotIndex = filename.lastIndexOf('.')
const baseFilename = lastDotIndex !== -1 ? filename.slice(0, lastDotIndex) : filename
🤖 Prompt for AI Agents
In src/platform/assets/composables/useUploadModelWizard.ts around line 147, the
current extraction const baseFilename = filename.split('.')[0] only keeps text
before the first dot and breaks names like "my.model.safetensors"; replace it
with a robust method such as using filename.replace(/\.[^.]+$/, '') or using
lastDot = filename.lastIndexOf('.') and taking filename.substring(0, lastDot ===
-1 ? filename.length : lastDot) so the full base name is preserved while still
stripping only the final extension.

@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.34 Backport PRs for cloud 1.34 labels Dec 9, 2025
@luke-mino-altherr luke-mino-altherr force-pushed the luke-mino-altherr/civitai-image-preview branch from 8c8e6cb to 0104dbc Compare December 9, 2025 19:31
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
src/platform/assets/services/assetService.ts (1)

395-446: Base64 upload helper is solid; align errors with existing i18n pattern

The uploadAssetFromBase64 flow looks correct: guarding for data: URLs, converting to a Blob, sending via FormData, and reusing the existing endpoint.

To stay consistent with uploadAssetFromUrl and the i18n guidelines, consider:

  • Using the same localized failure message for non-OK responses:
if (!res.ok) {
  throw new Error(
    st(
      'assetBrowser.errorUploadFailed',
      'Failed to upload asset. Please try again.'
    )
  )
}
  • Similarly, for the invalid data guard, either:
    • Throw the same localized upload-failed message, or
    • Throw a more internal-facing error but ensure callers don’t surface it directly to users.

This keeps future callers of uploadAssetFromBase64 from accidentally exposing raw technical or HTTP status text to end users.

Also applies to: 458-459

src/platform/assets/composables/useUploadModelWizard.ts (1)

15-16: Preview-first upload flow is correct; consider more robust base filename extraction

The wizard changes look good overall:

  • previewImage is correctly carried in WizardData and populated from metadata.preview_image.
  • The upload sequence sensibly uploads the preview first, captures previewId, and then includes preview_id in the main uploadAssetFromUrl call.
  • Failure to upload the preview is handled gracefully in a try/catch without blocking the main model upload.

One small refinement: const baseFilename = filename.split('.')[0] will truncate names with multiple dots (e.g. 'my.model.safetensors''my'). Using the last dot is more robust, e.g.:

const lastDotIndex = filename.lastIndexOf('.')
const baseFilename =
  lastDotIndex !== -1 ? filename.slice(0, lastDotIndex) : filename

so the generated preview name preserves the full base model name.

Also applies to: 32-38, 96-98, 142-180

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 031b504 and 0104dbc.

📒 Files selected for processing (6)
  • src/platform/assets/components/UploadModelConfirmation.vue (2 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (2 hunks)
  • src/platform/assets/components/UploadModelProgress.vue (2 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (5 hunks)
  • src/platform/assets/schemas/assetSchema.ts (1 hunks)
  • src/platform/assets/services/assetService.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Minimize the surface area (exported values) of each module and composable
Use es-toolkit for utility functions

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: Write expressive and self-documenting code to reduce the need for comments; clean redundant comments as you go
Consider if there is a simpler way to introduce functionality before writing code; choose the simpler approach when possible
Use refactoring to make complex code simpler
Keep functions short and functional
Minimize nesting in code (e.g., if () { ... } or for () { ... }) to avoid arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions (especially testable ones)
Watch out for code smells and refactor to avoid them
Implement proper error handling in code
If a complex type definition is inlined in multiple related places, extract and name it for reuse

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{js,ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively (no new JavaScript)

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Do not use any type in TypeScript code
Do not use as any type assertions in TypeScript code; fix the underlying type issue
Style formatting: 2 space indent, single quotes, no trailing semicolons, 80 character width
Import statements should be sorted and grouped by plugin; run pnpm format before committing
ESLint rules: no floating promises, no unused imports, i18n raw text restrictions in templates

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use vue-i18n in Composition API for string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs with Composition API only (.vue files)
Use Tailwind 4 styling and avoid <style> blocks in Vue components
Use <script setup lang="ts"> for component logic in Vue components
Use Vue 3.5 TypeScript style of default prop declaration with reactive props destructuring
Do not use withDefaults or runtime props declaration in Vue components
Prefer useModel to separately defining a prop and emit in Vue components
Use ref for reactive state in Vue components
Implement computed properties with computed() instead of using ref and watch
Use watch and watchEffect for side effects in Vue components
Use provide/inject for dependency injection only when simpler alternatives (Store or composable) are not suitable
Do not use the dark: Tailwind variant; use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use import { cn } from '@/utils/tailwindUtil' to merge class names instead of :class="[]"
Avoid new usage of PrimeVue components
Use VueUse functions for performance-enhancing styles in Vue components
Do not import Vue macros unnecessarily in components
Be judicious with addition of new refs or other state; prefer using props or composables when possible
Do not add a computed if it's possible to use a ref or prop directly
Do not use a watch if a computed would work instead
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
🧠 Learnings (5)
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Check assets/ directory for test data when writing tests

Applied to files:

  • src/platform/assets/services/assetService.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/services/assetService.ts
  • src/platform/assets/schemas/assetSchema.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
📚 Learning: 2025-12-09T02:44:38.234Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T02:44:38.234Z
Learning: Applies to **/*.vue : Implement proper props and emits definitions in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelProgress.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelConfirmation.vue
🧬 Code graph analysis (2)
src/platform/assets/services/assetService.ts (2)
src/platform/assets/schemas/assetSchema.ts (1)
  • AssetItem (74-74)
src/scripts/api.ts (1)
  • api (1289-1289)
src/platform/assets/composables/useUploadModelWizard.ts (1)
src/platform/assets/services/assetService.ts (1)
  • assetService (463-463)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (2)
src/platform/assets/schemas/assetSchema.ts (1)

49-58: AssetMetadata preview_image field is consistent with usage

Adding preview_image: z.string().optional() cleanly models the new metadata field and aligns with how it’s consumed in the wizard (metadata.preview_image || null).

src/platform/assets/components/UploadModelDialog.vue (1)

13-28: Forwarding previewImage through dialog steps is correct

Binding wizardData.previewImage into both UploadModelConfirmation and UploadModelProgress via preview-image cleanly propagates the preview data without affecting existing behavior.

Comment on lines +7 to +19
<div
class="flex items-center gap-3 bg-secondary-background p-3 rounded-lg"
>
<img
v-if="previewImage"
:src="previewImage"
:alt="metadata?.filename || metadata?.name || 'Model preview'"
class="w-14 h-14 rounded object-cover flex-shrink-0"
/>
<p class="m-0 text-base-foreground">
{{ metadata?.filename || metadata?.name }}
</p>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Preview thumbnail wiring looks good; localize fallback alt text

The preview block and previewImage prop are correctly integrated and handle the optional image well. To comply with the i18n guidelines, consider replacing the hard-coded 'Model preview' fallback in the alt binding with a localized string, e.g.:

:alt="
  metadata?.filename ||
  metadata?.name ||
  $t('assetBrowser.modelPreviewAlt', 'Model preview')
"

and add assetBrowser.modelPreviewAlt to src/locales/en/main.json.

Also applies to: 51-54

🤖 Prompt for AI Agents
In src/platform/assets/components/UploadModelConfirmation.vue around lines 7-19
(and similarly at lines 51-54), replace the hard-coded fallback alt text 'Model
preview' with a localized lookup using $t('assetBrowser.modelPreviewAlt', 'Model
preview') so the alt binding becomes: metadata?.filename || metadata?.name ||
$t('assetBrowser.modelPreviewAlt', 'Model preview'); then add the key
"assetBrowser.modelPreviewAlt": "Model preview" to src/locales/en/main.json to
provide the English default.

Comment on lines +28 to +35
class="flex flex-row items-center gap-3 p-4 bg-modal-card-background rounded-lg"
>
<img
v-if="previewImage"
:src="previewImage"
:alt="metadata?.filename || metadata?.name || 'Model preview'"
class="w-14 h-14 rounded object-cover flex-shrink-0"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Success preview behavior is good; localize alt fallback

The success-state preview image is correctly wired and optional, and the new previewImage prop is well-scoped. As in the confirmation step, the hard-coded 'Model preview' fallback in the alt binding should be localized, for example:

:alt="
  metadata?.filename ||
  metadata?.name ||
  $t('assetBrowser.modelPreviewAlt', 'Model preview')
"

with assetBrowser.modelPreviewAlt added to src/locales/en/main.json.

Also applies to: 69-75

🤖 Prompt for AI Agents
In src/platform/assets/components/UploadModelProgress.vue around lines 28-35
(and also update the similar occurrence around lines 69-75), the img alt binding
currently falls back to the hard-coded string 'Model preview'; replace that
literal with a localized fallback using the translation helper, e.g.
:alt="metadata?.filename || metadata?.name || $t('assetBrowser.modelPreviewAlt',
'Model preview')", and add the key "assetBrowser.modelPreviewAlt": "Model
preview" to src/locales/en/main.json so the fallback is localized.

<div
class="flex items-center gap-3 bg-secondary-background p-3 rounded-lg"
>
<img
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error?: string
metadata: AssetMetadata | null
modelType: string | undefined
previewImage?: string | null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
previewImage?: string | null
previewImage?: string

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of these, I think we should have a single "absent" value.

DrJKL
DrJKL previously approved these changes Dec 9, 2025
@DrJKL DrJKL force-pushed the luke-mino-altherr/civitai-image-preview branch from bce3934 to 5774a90 Compare December 9, 2025 23:03
luke-mino-altherr and others added 5 commits December 9, 2025 15:43
- Add descriptive alt text to preview images in UploadModelConfirmation and UploadModelProgress components
- Add data URL validation in uploadAssetFromBase64 to fail fast with descriptive error
- Replace generic localized errors with specific technical error messages for better debugging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Prevents double extensions like "model.safetensors_preview.png" by extracting the base filename before appending "_preview.png"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace `null` types with optional `undefined` types in upload model
wizard for consistency with TypeScript best practices.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@luke-mino-altherr luke-mino-altherr force-pushed the luke-mino-altherr/civitai-image-preview branch from 5774a90 to 3db5fff Compare December 9, 2025 23:43
@luke-mino-altherr luke-mino-altherr enabled auto-merge (squash) December 10, 2025 00:31
@luke-mino-altherr luke-mino-altherr merged commit ce4837a into main Dec 10, 2025
27 checks passed
@luke-mino-altherr luke-mino-altherr deleted the luke-mino-altherr/civitai-image-preview branch December 10, 2025 00:32
github-actions bot pushed a commit that referenced this pull request Dec 10, 2025
…7274)

## Summary
Stores and displays base64-encoded preview images from Civitai during
the model upload flow, uploading the preview as a separate asset linked
to the model.

## Changes
- **Schema**: Added `preview_image` field to `AssetMetadata` schema
- **Service**: Added `uploadAssetFromBase64` method to convert base64
data to blob and upload via FormData
- **Upload Flow**: Modified wizard to first upload preview image as
asset, then link it to model via `preview_id`
- **UI**: Display 56x56px preview thumbnail alongside model filename in
confirmation and success steps

## Review Focus
- Base64 to blob conversion and FormData upload implementation
- Sequential upload flow (preview first, then model with preview_id
reference)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7274-feat-display-and-upload-Civitai-preview-images-in-model-upload-flow-2c46d73d365081ff9b74c1791d23f6dd)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <[email protected]>
@comfy-pr-bot
Copy link
Member

@luke-mino-altherr Successfully backported to #7301

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Dec 10, 2025
Enferlain pushed a commit to Enferlain/ComfyUI_frontend that referenced this pull request Dec 10, 2025
…omfy-Org#7274)

## Summary
Stores and displays base64-encoded preview images from Civitai during
the model upload flow, uploading the preview as a separate asset linked
to the model.

## Changes
- **Schema**: Added `preview_image` field to `AssetMetadata` schema
- **Service**: Added `uploadAssetFromBase64` method to convert base64
data to blob and upload via FormData
- **Upload Flow**: Modified wizard to first upload preview image as
asset, then link it to model via `preview_id`
- **UI**: Display 56x56px preview thumbnail alongside model filename in
confirmation and success steps

## Review Focus
- Base64 to blob conversion and FormData upload implementation
- Sequential upload flow (preview first, then model with preview_id
reference)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7274-feat-display-and-upload-Civitai-preview-images-in-model-upload-flow-2c46d73d365081ff9b74c1791d23f6dd)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <[email protected]>
christian-byrne pushed a commit that referenced this pull request Dec 10, 2025
… in model upload flow (#7301)

Backport of #7274 to `cloud/1.34`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7301-backport-cloud-1-34-feat-display-and-upload-Civitai-preview-images-in-model-upload-flo-2c56d73d3650814caedbc0b64480cb9c)
by [Unito](https://www.unito.io)

Co-authored-by: Luke Mino-Altherr <[email protected]>
Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:models cloud/1.34 Backport PRs for cloud 1.34 enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants