import { langEnum } from "../types/lang" import type { GenericObjectType } from "@contentstack/app-sdk/dist/src/types/common.types" import type { Config, FocalPoint, ImageVaultAsset, InsertResponse, PublishDetails, } from "../types/imagevault" import type { Lang } from "../types/lang" const metaIds = { [langEnum.de]: { altText: 68, title: 77 }, [langEnum.da]: { altText: 67, title: 76 }, [langEnum.fi]: { altText: 70, title: 78 }, [langEnum.no]: { altText: 71, title: 79 }, [langEnum.sv]: { altText: 74, title: 82 }, [langEnum.en]: { altText: 69, title: 65 }, } export function getMetaIds(lang: Lang) { return metaIds[lang] } export type EntryDataPublishDetails = { branch: string contentTypeUid: string locale: Lang stackApiKey: string title: string uid: string } export function getPublishDetails( baseUrl: string, { branch, contentTypeUid, locale, stackApiKey, title, uid, }: EntryDataPublishDetails ): PublishDetails { const text = `${title} (${uid})` const url = `${baseUrl}#!/stack/${stackApiKey}/content-type/${contentTypeUid}/${locale}/entry/${uid}/edit?branch=${branch}` return { text, url } } export function isInsertResponse( res: InsertResponse | GenericObjectType | null | undefined ): res is InsertResponse { return (res as InsertResponse)?.MediaConversions !== undefined } export function isImageVaultAsset( res: ImageVaultAsset | InsertResponse | GenericObjectType | null | undefined ): res is ImageVaultAsset { return (res as ImageVaultAsset)?.url !== undefined } export type ImageVaultDAMConfig = { imageVaultUrl: string baseUrl: string formatId: string } export function isImageVaultDAMConfig( config: Record ): config is ImageVaultDAMConfig { return !!(config.baseUrl && config.formatId && config.imageVaultUrl) } // Utility function to get ImageVaultAsset from either InsertResponse or ImageVaultAsset // Because we currently have both types saved in Contentstack, we need to account for both when retrieving the data of the asset. export function getImageVaultAssetFromData( data: InsertResponse | ImageVaultAsset | GenericObjectType | null | undefined ): ImageVaultAsset | null { if (isImageVaultAsset(data)) { return data } if (isInsertResponse(data)) { return mapInsertResponseToImageVaultAsset(data, { x: 50, y: 50 }) } return null } // Utility function to convert InsertResponse to ImageVaultAsset function mapInsertResponseToImageVaultAsset( response: InsertResponse, focalPoint: FocalPoint ): ImageVaultAsset { let image = response.MediaConversions.find( (conversion) => conversion.MediaFormatName === "Original" && conversion.ContentType === "image/jpeg" ) // We only receive one alt and title is in the response, depending on the language of the entry // This is why we're getting the first one found const alt = response.Metadata?.find((meta) => meta.Name.includes("AltText_"))?.Value || "" const caption = response.Metadata?.find((meta) => meta.Name.includes("Title_"))?.Value || "" if (!image) { const imageAsJpeg = response.MediaConversions.find( (conversion) => conversion.ContentType === "image/jpeg" ) image = imageAsJpeg || response.MediaConversions[0] } return { imageVaultId: response.Id, url: image.Url, meta: { alt, caption, }, fileName: response.Name, dimensions: { width: image.Width, height: image.Height, aspectRatio: image.AspectRatio, }, focalPoint: response.FocalPoint || focalPoint, } } export type openImageVaultParams = { config: ImageVaultDAMConfig entryData: EntryDataPublishDetails onSuccess: (result: ImageVaultAsset) => void onClose?: () => void } export function openImageVault({ config, entryData, onSuccess, onClose, }: openImageVaultParams) { if (window.ImageVault) { const publishDetails = getPublishDetails(config.baseUrl, entryData) const metaIdsForLocale = getMetaIds(entryData.locale) const insertMediaWindowOptions: Config = { imageVaultUiUrl: config.imageVaultUrl, uiLang: "en", pageLang: "en", publishingSource: config.baseUrl, mediaUrlBase: config.imageVaultUrl, formatId: config.formatId, publishDetails, insertMultiple: false, success: (result) => { const imageVaultAsset = mapInsertResponseToImageVaultAsset( result.response, { x: 50, y: 50 } ) onSuccess(imageVaultAsset) }, close: () => { if (typeof onClose === "function") { onClose() } windowInserter.containerWindow?.close() }, } if (metaIdsForLocale) { const additionalMetadataIds = Object.values(metaIdsForLocale).join(",") insertMediaWindowOptions.additionalMetadataIds = additionalMetadataIds } const windowInserter = new window.ImageVault.InsertMediaWindow( insertMediaWindowOptions, `left=0,top=0,width=${window.screen.width},height=${window.screen.height}` ) windowInserter.openImageVault() } else { console.error("Missing ImageVault global. ImageVault script not loaded?") } }