diff --git a/src/platform/assets/components/AssetCard.vue b/src/platform/assets/components/AssetCard.vue index 0b18ac97c..299599e5e 100644 --- a/src/platform/assets/components/AssetCard.vue +++ b/src/platform/assets/components/AssetCard.vue @@ -127,6 +127,7 @@ import { useFeatureFlags } from '@/composables/useFeatureFlags' import AssetBadgeGroup from '@/platform/assets/components/AssetBadgeGroup.vue' import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser' import { assetService } from '@/platform/assets/services/assetService' +import { getAssetDisplayName } from '@/platform/assets/utils/assetMetadataUtils' import { useSettingStore } from '@/platform/settings/settingStore' import { useToastStore } from '@/platform/updates/common/toastStore' import { useDialogStore } from '@/stores/dialogStore' @@ -181,7 +182,9 @@ const descId = useId() const isEditing = ref(false) const newNameRef = ref() -const displayName = computed(() => newNameRef.value ?? asset.name) +const displayName = computed( + () => newNameRef.value ?? getAssetDisplayName(asset) +) const showAssetOptions = computed( () => @@ -260,10 +263,10 @@ async function assetRename(newName?: string) { newNameRef.value = newName try { const result = await assetService.updateAsset(asset.id, { - name: newName + user_metadata: { name: newName } }) // Update with the actual name once the server responds - newNameRef.value = result.name + newNameRef.value = getAssetDisplayName(result) } catch (err: unknown) { console.error(err) toastStore.add({ diff --git a/src/platform/assets/schemas/assetSchema.ts b/src/platform/assets/schemas/assetSchema.ts index 8a8cf6099..9fb44cb65 100644 --- a/src/platform/assets/schemas/assetSchema.ts +++ b/src/platform/assets/schemas/assetSchema.ts @@ -90,6 +90,11 @@ export type AsyncUploadResponse = z.infer export type ModelFolder = z.infer export type ModelFile = z.infer +/** Payload for updating an asset via PUT /assets/:id */ +export type AssetUpdatePayload = Partial< + Pick +> + // Legacy interface for backward compatibility (now aligned with Zod schema) export interface ModelFolderInfo { name: string diff --git a/src/platform/assets/services/assetService.ts b/src/platform/assets/services/assetService.ts index da87681bb..edabfb2d3 100644 --- a/src/platform/assets/services/assetService.ts +++ b/src/platform/assets/services/assetService.ts @@ -10,6 +10,7 @@ import type { AssetItem, AssetMetadata, AssetResponse, + AssetUpdatePayload, AsyncUploadResponse, ModelFile, ModelFolder @@ -298,7 +299,7 @@ function createAssetService() { */ async function updateAsset( id: string, - newData: Partial + newData: AssetUpdatePayload ): Promise { const res = await api.fetchApi(`${ASSETS_ENDPOINT}/${id}`, { method: 'PUT', diff --git a/src/platform/assets/utils/assetMetadataUtils.ts b/src/platform/assets/utils/assetMetadataUtils.ts index 2d50f3dbe..0e913a683 100644 --- a/src/platform/assets/utils/assetMetadataUtils.ts +++ b/src/platform/assets/utils/assetMetadataUtils.ts @@ -32,20 +32,29 @@ export function getAssetBaseModel(asset: AssetItem): string | null { * @returns The display name or filename */ export function getAssetDisplayName(asset: AssetItem): string { - return typeof asset.user_metadata?.display_name === 'string' - ? asset.user_metadata.display_name + return typeof asset.user_metadata?.name === 'string' + ? asset.user_metadata.name : asset.name } /** - * Safely extracts source URL from asset metadata + * Constructs source URL from asset's source_arn * @param asset - The asset to extract source URL from - * @returns The source URL or null if not present + * @returns The source URL or null if not present/parseable */ export function getAssetSourceUrl(asset: AssetItem): string | null { - return typeof asset.user_metadata?.source_url === 'string' - ? asset.user_metadata.source_url - : null + const sourceArn = asset.user_metadata?.source_arn + if (typeof sourceArn !== 'string') return null + + const civitaiMatch = sourceArn.match( + /^civitai:model:(\d+):version:(\d+)(?::file:\d+)?$/ + ) + if (civitaiMatch) { + const [, modelId, versionId] = civitaiMatch + return `https://civitai.com/models/${modelId}?modelVersionId=${versionId}` + } + + return null } /** @@ -54,7 +63,7 @@ export function getAssetSourceUrl(asset: AssetItem): string | null { * @returns Array of trigger phrases */ export function getAssetTriggerPhrases(asset: AssetItem): string[] { - const phrases = asset.user_metadata?.trigger_phrases + const phrases = asset.user_metadata?.trained_words if (Array.isArray(phrases)) { return phrases.filter((p): p is string => typeof p === 'string') }