@alpaca-editor/contenthub 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +4 -0
- package/package.json +35 -0
- package/src/DamSelector.tsx +57 -0
- package/src/DamSelectorButton.tsx +33 -0
- package/src/index.ts +39 -0
- package/src/types.ts +24 -0
- package/styles.css +1 -0
- package/tsconfig.json +8 -0
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alpaca-editor/contenthub",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./styles.css": "./styles.css"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"lint": "eslint . --max-warnings 0",
|
|
14
|
+
"generate:component": "turbo gen react-component",
|
|
15
|
+
"check-types": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@repo/eslint-config": "*",
|
|
19
|
+
"@repo/typescript-config": "*",
|
|
20
|
+
"@turbo/gen": "^2.4.4",
|
|
21
|
+
"@types/node": "^22.13.9",
|
|
22
|
+
"@types/react": "19.0.10",
|
|
23
|
+
"@types/react-dom": "19.0.4",
|
|
24
|
+
"eslint": "^9.22.0",
|
|
25
|
+
"typescript": "5.8.2"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@tailwindcss/postcss": "^4.0.14",
|
|
29
|
+
"postcss": "^8.5.3",
|
|
30
|
+
"react": "^19.0.0",
|
|
31
|
+
"react-dom": "^19.0.0",
|
|
32
|
+
"tailwindcss": "^4.0.14",
|
|
33
|
+
"primereact": "10.9.1"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Dialog } from 'primereact/dialog';
|
|
2
|
+
import { DialogProps } from '@alpaca-editor/core';
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import { DamImageValue, DamSelectorProps } from './types';
|
|
5
|
+
|
|
6
|
+
export function DamSelector({
|
|
7
|
+
onClose,
|
|
8
|
+
contentHubHost,
|
|
9
|
+
contentHubBrowsePage,
|
|
10
|
+
externalRedirectKey
|
|
11
|
+
}: DamSelectorProps & DialogProps<DamImageValue>) {
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const handleMessage = (message: MessageEvent) => {
|
|
15
|
+
console.log('Received message:', message);
|
|
16
|
+
|
|
17
|
+
const normalizedHost = contentHubHost.replace(/\/$/, '');
|
|
18
|
+
const messageOrigin = message.origin.replace(/\/$/, '');
|
|
19
|
+
|
|
20
|
+
if (messageOrigin !== normalizedHost) {
|
|
21
|
+
console.log('Origin mismatch:', messageOrigin, normalizedHost);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = message.data as DamImageValue;
|
|
26
|
+
if (!data || !data.public_link) {
|
|
27
|
+
console.log('Invalid data received:', data);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log('Processing valid data:', data);
|
|
32
|
+
onClose(data);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
window.addEventListener("message", handleMessage);
|
|
36
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
37
|
+
}, [contentHubHost, onClose]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Dialog
|
|
41
|
+
visible={true}
|
|
42
|
+
onHide={() => onClose(null)}
|
|
43
|
+
header="Insert from Sitecore DAM"
|
|
44
|
+
modal
|
|
45
|
+
style={{ width: '90vw', height: '90vh' }}
|
|
46
|
+
contentStyle={{ padding: 0, height: 'calc(100% - 71px)' }} // 71px accounts for header height
|
|
47
|
+
className="select-medidialog"
|
|
48
|
+
draggable={false}
|
|
49
|
+
resizable={false}
|
|
50
|
+
>
|
|
51
|
+
<iframe
|
|
52
|
+
className="w-full h-full border-none"
|
|
53
|
+
src={`${contentHubHost}${contentHubBrowsePage}?externalRedirectKey=${externalRedirectKey}&externalRedirectUrl=${window.location.href}&hasExternalRedirect=true`}
|
|
54
|
+
/>
|
|
55
|
+
</Dialog>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ClientFieldButton } from "@alpaca-editor/core";
|
|
2
|
+
import { DamSelector } from "./DamSelector";
|
|
3
|
+
import { DamSelectorProps, DamImageValue, ContentHubExtension } from "./types";
|
|
4
|
+
|
|
5
|
+
export const DamSelectorButton: ClientFieldButton = {
|
|
6
|
+
label: "Open Content Hub",
|
|
7
|
+
icon: "pi pi-external-link",
|
|
8
|
+
clientAction: async ({ dialogContext, editContext, field }) => {
|
|
9
|
+
const contentHubConfig = editContext!.configuration.extensions.contentHub as ContentHubExtension;
|
|
10
|
+
console.log("contentHubConfig", contentHubConfig);
|
|
11
|
+
|
|
12
|
+
const data = await dialogContext.openDialog<DamImageValue, DamSelectorProps>(
|
|
13
|
+
DamSelector, {
|
|
14
|
+
contentHubHost: contentHubConfig.contentHubHost,
|
|
15
|
+
contentHubBrowsePage: contentHubConfig.contentHubBrowsePage,
|
|
16
|
+
externalRedirectKey: contentHubConfig.externalRedirectKey
|
|
17
|
+
}
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if (data != null){
|
|
21
|
+
const rawValue = `<image src="${data?.public_link}" dam-id="${data?.['dam-id']}" width="${data?.width}" height="${data?.height}" alt="${data?.alt}" dam-content-type="Image" thumbnailsrc="${data?.thumbnailsrc}" />`;
|
|
22
|
+
|
|
23
|
+
editContext!.operations.editField({
|
|
24
|
+
field: field.descriptor,
|
|
25
|
+
rawValue: rawValue,
|
|
26
|
+
refresh: "immediate",
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
isGenerator: false,
|
|
31
|
+
id: "open-contenthub-dam",
|
|
32
|
+
description: "Opens the Content Hub DAM to select an image",
|
|
33
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { EditorConfiguration } from "@alpaca-editor/core";
|
|
2
|
+
import { ContentHubExtension } from "./types";
|
|
3
|
+
import { DamSelectorButton } from "./DamSelectorButton";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Configures the ContentHub extension for the editor
|
|
7
|
+
* @param configuration - The editor configuration object
|
|
8
|
+
* @param contentHubHost - The base URL of the Content Hub instance (e.g., "https://your-instance.sitecoresandbox.cloud")
|
|
9
|
+
* @param browsePage - The relative path to the browse page (will be appended to contentHubHost)
|
|
10
|
+
* @returns The updated configuration object
|
|
11
|
+
*/
|
|
12
|
+
export function configureContentHub(
|
|
13
|
+
configuration: EditorConfiguration,
|
|
14
|
+
contentHub: ContentHubExtension,
|
|
15
|
+
) {
|
|
16
|
+
configuration.extensions = {
|
|
17
|
+
...configuration.extensions,
|
|
18
|
+
contentHub: {
|
|
19
|
+
contentHubHost: contentHub.contentHubHost,
|
|
20
|
+
contentHubBrowsePage: contentHub.contentHubBrowsePage,
|
|
21
|
+
externalRedirectKey: contentHub.externalRedirectKey
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (!configuration.fieldTypes.image) {
|
|
26
|
+
configuration.fieldTypes.image = {
|
|
27
|
+
editor: () => null,
|
|
28
|
+
buttons: []
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!configuration.fieldTypes.image.buttons) {
|
|
33
|
+
configuration.fieldTypes.image.buttons = [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
configuration.fieldTypes.image.buttons.push(DamSelectorButton);
|
|
37
|
+
|
|
38
|
+
return configuration;
|
|
39
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type DamSelectorProps = {
|
|
2
|
+
contentHubHost: string;
|
|
3
|
+
contentHubBrowsePage: string;
|
|
4
|
+
externalRedirectKey: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type DamImageValue = {
|
|
8
|
+
src: string;
|
|
9
|
+
'dam-id': string;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
alt: string;
|
|
13
|
+
'dam-content-type': string;
|
|
14
|
+
thumbnailsrc: string;
|
|
15
|
+
public_link: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type ContentHubExtension = {
|
|
19
|
+
contentHubHost: string;
|
|
20
|
+
contentHubBrowsePage: string;
|
|
21
|
+
externalRedirectKey: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
package/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@source "./";
|