feat: Contentstack <-> ImageVault integration
This commit is contained in:
149
utils/imagevault.ts
Normal file
149
utils/imagevault.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import { langEnum } from '../types/lang';
|
||||
|
||||
import type { GenericObjectType } from '@contentstack/app-sdk/dist/src/types/common.types';
|
||||
import type { Lang } from '../types/lang';
|
||||
import type {
|
||||
Config,
|
||||
ImageVaultAsset,
|
||||
InsertResponse,
|
||||
PublishDetails,
|
||||
} from "../types/imagevault";
|
||||
|
||||
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
|
||||
): res is InsertResponse {
|
||||
return (res as InsertResponse).MediaConversions !== undefined;
|
||||
}
|
||||
|
||||
export type ImageVaultDAMConfig = {
|
||||
imageVaultUrl: string;
|
||||
baseUrl: string;
|
||||
formatId: string;
|
||||
};
|
||||
|
||||
export function isImageVaultDAMConfig(
|
||||
config: Record<string, string>
|
||||
): config is ImageVaultDAMConfig {
|
||||
return !!(config.baseUrl && config.formatId && config.imageVaultUrl);
|
||||
}
|
||||
|
||||
// Utility function to convert InsertResponse to ImageVaultAsset, used mainly for custom field images
|
||||
// For RTE this function is not enough since rte:s also need attrs, like position and the size thats
|
||||
// chosen in the editor
|
||||
export function insertResponseToImageVaultAsset(
|
||||
response: InsertResponse
|
||||
): ImageVaultAsset {
|
||||
const alt = response.Metadata?.find((meta) =>
|
||||
meta.Name.includes("AltText_")
|
||||
)?.Value;
|
||||
|
||||
const caption = response.Metadata?.find((meta) =>
|
||||
meta.Name.includes("Title_")
|
||||
)?.Value;
|
||||
|
||||
return {
|
||||
url: response.MediaConversions[0].Url,
|
||||
id: response.Id,
|
||||
meta: {
|
||||
alt,
|
||||
caption,
|
||||
},
|
||||
title: response.Name,
|
||||
dimensions: {
|
||||
width: response.MediaConversions[0].Width,
|
||||
height: response.MediaConversions[0].Height,
|
||||
aspectRatio: response.MediaConversions[0].FormatAspectRatio,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type openImageVaultParams = {
|
||||
config: ImageVaultDAMConfig;
|
||||
entryData: EntryDataPublishDetails;
|
||||
onSuccess: (result: InsertResponse) => 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) => {
|
||||
onSuccess(result.response);
|
||||
},
|
||||
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?");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user