Skip to content

Commit

Permalink
Merge pull request #1 from dunguyen/custom-datatype
Browse files Browse the repository at this point in the history
feat: add custom datatype for asset
  • Loading branch information
duynguyen authored and GitHub Enterprise committed Mar 21, 2024
2 parents 2416e90 + f12c976 commit 6c2e900
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 58 deletions.
5 changes: 5 additions & 0 deletions src/aem-uex-1/web-src/src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ErrorBoundary from "react-error-boundary";
import { HashRouter as Router, Routes, Route } from "react-router-dom";
import ExtensionRegistration from "./ExtensionRegistration";
import OpenassetpickerModal from "./OpenassetpickerModal";
import Openassetpicker from "./Openassetpicker";

function App() {
return (
Expand All @@ -22,6 +23,10 @@ function App() {
exact path="open-asset-picker-modal"
element={<OpenassetpickerModal />}
/>
<Route
exact path="open-asset-picker"
element={<Openassetpicker />}
/>
{/* @todo YOUR CUSTOM ROUTES SHOULD BE HERE */}
</Routes>
</ErrorBoundary>
Expand Down
3 changes: 2 additions & 1 deletion src/aem-uex-1/web-src/src/components/Constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = {
extensionId: 'om.adobe.universal-editor-assetpicker-extension'
extensionId: 'com.adobe.universal-editor-assetpicker-extension',
assetSelectedEventName: 'assetSelected',
}
36 changes: 6 additions & 30 deletions src/aem-uex-1/web-src/src/components/ExtensionRegistration.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,19 @@ function ExtensionRegistration() {
const guestConnection = await register({
id: extensionId,
methods: {
headerMenu: {
getButtons() {
canvas: {
getRenderers() {
return [
// @todo YOUR HEADER BUTTONS DECLARATION SHOULD BE HERE
// @todo YOUR CUSTOM DATA FIELD RENDERERS DECLARATION SHOULD BE HERE
{
id: 'open-asset-picker',
label: 'Open Asset Picker',
extension: 'asset-picker-field',
dataType: 'custom-asset',
url: '/index.html#/open-asset-picker',
icon: 'OpenIn',
onClick() {
const modalURL = "/index.html#/open-asset-picker-modal";
console.log("Modal URL: ", modalURL);

guestConnection.host.modal.showUrl({
title: "Open Asset Picker",
url: modalURL,
width: "80vw",
height: "70vh",
});
},
},
];
},
},
// rightPanel: {
// addRails() {
// return [
// // @todo YOUR RIGHT PANEL BUTTONS DECLARATION SHOULD BE HERE
// {
// extension: 'open-asset-picker-rail',
// id: 'open-asset-picker-rail',
// header: 'open-asset-picker-rail',
// url: 'open-asset-picker-rail',
// icon: 'OpenIn',
// }
// ];
// },
// },
}
});
};
Expand Down
106 changes: 106 additions & 0 deletions src/aem-uex-1/web-src/src/components/Openassetpicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* <license header>
*/

import React, { useState, useEffect, useRef } from "react";
import { attach } from "@adobe/uix-guest";
import {
Provider,
Content,
defaultTheme,
Flex,
TextField,
ActionButton,
Text,
Image,
} from "@adobe/react-spectrum";
import { extensionId, assetSelectedEventName } from "./Constants";

export default function () {
const customAssetField = useRef(null);
const [guestConnection, setGuestConnection] = useState();
const [model, setModel] = useState({});
const [value, setValue] = useState('');

const handleStorageChange = (event) => {
if (event.key === assetSelectedEventName) {
setValue(event.newValue);
customAssetField.current.focus();
localStorage.removeItem(assetSelectedEventName);
}
};

const onChangeHandler = (event) => {
const newValue = event.target.value;
guestConnection.host.field.onChange(newValue);
};

const init = async () => {
const connection = await attach({
id: extensionId,
});
setGuestConnection(connection);
};

useEffect(() => {
init().catch((e) =>
console.error("Extension got the error during initialization:", e)
);
window.addEventListener('storage', handleStorageChange);

return () => {
window.removeEventListener('storage', handleStorageChange);
};
}, []);

useEffect(() => {
if (!guestConnection) {
return;
}
const getState = async () => {
setModel(await guestConnection.host.field.getModel());
if (!value) {
setValue(await guestConnection.host.field.getValue() || '');
}
};
getState().catch((e) => console.error("Extension error:", e));
}, [guestConnection]);

const showModal = () => {
guestConnection.host.modal.showUrl({
title: "Asset Picker",
url: "/index.html#/open-asset-picker-modal",
width: "80vw",
height: "70vh",
});
};

let url;
let name = '';
try {
url = new URL(value);
name = url?.pathname?.split('/')?.pop() || '';
} catch (e) {}

return (
<Provider theme={defaultTheme} colorScheme='light'>
<Content>
<Flex direction="column">
<Text>Custom asset</Text>
<TextField ref={customAssetField} value={value} flexGrow={1} isReadOnly onFocus={onChangeHandler} />
<ActionButton onPress={showModal} height="size-600" marginStart="size-150" isQuiet>
<Flex alignItems="center" margin="size-100">
{url && <Image width="size-400" height="size-400" src={url?.href || ''} alt={name} objectFit="cover" />}
{url && <Text marginStart="size-150">
{name}
</Text>}
{!url && <Text marginStart="size-150">
No asset selected
</Text>}
</Flex>
</ActionButton>
</Flex>
</Content>
</Provider>
);
}
65 changes: 38 additions & 27 deletions src/aem-uex-1/web-src/src/components/OpenassetpickerModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@
import React, { useState, useEffect } from "react";
import { attach } from "@adobe/uix-guest";
import {
Flex,
Provider,
Content,
defaultTheme,
Text,
ButtonGroup,
Button,
} from "@adobe/react-spectrum";
import { AssetSelector, DestinationSelector } from '@assets/selectors';
import { extensionId } from "./Constants";
import util from 'util';
import { AssetSelector } from '@assets/selectors';
import { assetSelectedEventName, extensionId } from "./Constants";

export default function () {
const [guestConnection, setGuestConnection] = useState();
const [endpoint, setEndpoint] = useState("");
const [token, setToken] = useState("");

const init = async () => {
Expand All @@ -34,11 +30,29 @@ export default function () {
);
}, []);

const onSelectionHandler = (asset) => {
localStorage.setItem(assetSelectedEventName, asset[0]?._links['http://ns.adobe.com/adobecloud/rel/rendition'].href);
onCloseHandler();
};

const onCloseHandler = () => {
guestConnection.host.modal.close();
};

// Get basic state from guestConnection
const filterRepos = (repos) => {
const repoName = endpoint.replace("https://", "").replace(/\/$/, "");
return repos.filter((repo) => {
return (
repo._embedded["http://ns.adobe.com/adobecloud/rel/repository"][
"aem:tier"
] === "delivery" ||
repo._embedded["http://ns.adobe.com/adobecloud/rel/repository"][
"repo:repositoryId"
] === repoName
);
});
};

useEffect(() => {
if (!guestConnection) {
return;
Expand All @@ -47,36 +61,33 @@ export default function () {
const context = guestConnection.sharedContext;
const imsToken = context.get("token");
setToken(imsToken);
const tempEditorState = await guestConnection.host.editorState.get();
const { connections, customTokens } = tempEditorState;
const tempEndpointName = Object.keys(connections).filter((key) =>
connections[key].startsWith("xwalk:")
)[0];
if (tempEndpointName) {
setEndpoint(connections[tempEndpointName].replace("xwalk:", ""));
if (customTokens && customTokens[tempEndpointName]) {
setToken(customTokens[tempEndpointName].replace("Bearer ", ""));
}
}
};
getState().catch((e) => console.log("Extension error:", e));
getState().catch((e) => console.error("Extension error:", e));
}, [guestConnection]);

return (
<Provider theme={defaultTheme} colorScheme='light'>
<Content>
<AssetSelector
aemTierType={['delivery', 'author']}
dialogSize='fullscreen'
apiKey="aem-assets-backend-nr-1"
apiKey="asset_search_service"
imsToken={token}
handleSelection={(asset) => {
console.log(`Selected asset: ${util.inspect(asset, {showHidden: false, depth: null, colors: true})}`);
onCloseHandler();
}}
handleSelection={onSelectionHandler}
onClose={onCloseHandler}
filterRepoList={filterRepos}
/>

{/* <DestinationSelector
discoveryURL="https://aem-discovery.adobe.io"
apiKey="aem-assets-backend-nr-1"
imsOrg={ims.org}
imsToken={ims.token}
/> */}

{/* <Flex width="100%" justifyContent="end" alignItems="center" marginTop="size-400">
<ButtonGroup align="end">
<Button variant="primary" onClick={onCloseHandler}>Close</Button>
</ButtonGroup>
</Flex> */}
</Content>
</Provider>
);
Expand Down

0 comments on commit 6c2e900

Please sign in to comment.