Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion web-src/src/components/ApplicationProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import React, {
} from 'react';
import { useSetRecoilState } from 'recoil';
import { FirefallService } from '../services/FirefallService.js';
import { ExpressSDKService } from '../services/ExpressSDKService.js';
import actions from '../config.json';
import { useShellContext } from './ShellProvider.js';
import { loadPromptTemplates, promptTemplatesState } from '../state/PromptTemplatesState.js';
Expand Down Expand Up @@ -59,6 +60,12 @@ export const ApplicationProvider = ({ children }) => {

const websiteUrl = getWebsiteUrl();
const promptTemplatesPath = getPromptTemplatesPath();
const expressSDKService = new ExpressSDKService({
// TODO: replace with our own client ID
clientId: 'aem-genai-assistant',
appName: 'AEM Sites GenAI Assistant',
user,
});

setApplication({
appVersion: APP_VERSION,
Expand All @@ -70,6 +77,7 @@ export const ApplicationProvider = ({ children }) => {
imsOrg: user.imsOrg,
accessToken: user.imsToken,
}),
expressSDKService,
});

loadPromptTemplates(websiteUrl, promptTemplatesPath).then((templates) => {
Expand All @@ -82,7 +90,7 @@ export const ApplicationProvider = ({ children }) => {
}, [user, done, setApplication]);

if (!application) {
return <Fragment/>;
return <Fragment />;
}

return (
Expand Down
62 changes: 54 additions & 8 deletions web-src/src/components/MainSidePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,54 @@ import FileTxt from '../assets/file-txt.svg';
import { sessionHistoryState } from '../state/SessionHistoryState.js';
import { sessionState } from '../state/SessionState.js';
import { ViewType, viewTypeState } from '../state/ViewType.js';
import { useShellContext } from './ShellProvider.js';

export function MainSidePanel(props) {
const { appVersion } = useApplicationContext();
const { appVersion, expressSDKService } = useApplicationContext();
const sessions = useRecoilValue(sessionHistoryState);
const [currentSession, setCurrentSession] = useRecoilState(sessionState);
const [viewType, setViewType] = useRecoilState(viewTypeState);
const { user } = useShellContext();

let ccEverywhereInstance = null;

const createDesign = async () => {
if (ccEverywhereInstance == null) {
ccEverywhereInstance = await expressSDKService.initExpressEditor();
}
const userInfo = {
profile: {
userId: user.imsProfile.userId,
serviceCode: null,
serviceLevel: null,
},
serviceCode: null,
serviceLevel: null,
};
const authInfo = {
accessToken: user.imsToken,
useJumpUrl: false,
forceJumpCheck: false,
};

// eslint-disable-next-line max-len
// https://docs.cc-embed.adobe.com/v3/release/1p/classes/sdk_src_1p_CCEverywhere.CCEverywhere.html#createDesign
ccEverywhereInstance.createDesign(
// CreateDesignParams
{
outputParams: {
outputType: 'base64',
},
inputParams: {
templateType: 'brochure',
// You can also load an image into the project
// asset : "..."
},
},
userInfo,
authInfo,
);
};

const style = {
headerText: css`
Expand Down Expand Up @@ -109,34 +151,38 @@ export function MainSidePanel(props) {

<Flex direction={'column'} gridArea={'menu'} gap={'size-100'}>
<ul className={style.menu}>
<li className={viewType === ViewType.CurrentSession ? derivedStyle.clickedMenuItem : style.menuItem}>
<Image src={PromptsIcon} width={'20px'} alt={'*New - Adobe Express'} />
<Link href="#" UNSAFE_className={style.menuItemLink} onPress={() => createDesign()}>*New - Adobe Express</Link>
</li>
<li className={viewType === ViewType.NewSession ? derivedStyle.clickedMenuItem : style.menuItem}>
<Image src={PromptsIcon} width={'20px'} alt={'New prompt template'}/>
<Image src={PromptsIcon} width={'20px'} alt={'New prompt template'} />
<Link href="#" UNSAFE_className={style.menuItemLink} onPress={() => setViewType(ViewType.NewSession)}>Prompt Templates</Link>
</li>
<li className={viewType === ViewType.Favorites ? derivedStyle.clickedMenuItem : style.menuItem}>
<Image src={FavoritesIcon} width={'20px'} alt={'Favorites'}/>
<Image src={FavoritesIcon} width={'20px'} alt={'Favorites'} />
<Link href="#" UNSAFE_className={style.menuItemLink} onPress={() => setViewType(ViewType.Favorites)}>Favorites</Link>
</li>
<li className={style.menuItem}>
<Image src={RecentsIcon} width={'20px'} alt={'Recents'}/>
<Image src={RecentsIcon} width={'20px'} alt={'Recents'} />
<Text>Recents</Text>
</li>
{ (sessions && sessions.length > 0) && sessions.map((session) => (
{(sessions && sessions.length > 0) && sessions.map((session) => (
// eslint-disable-next-line max-len
<li className={currentSession && viewType === ViewType.CurrentSession && session && session.id === currentSession.id ? derivedStyle.clickedSubMenuItem : style.subMenuItem} key={session.id}>
<Link href="#" UNSAFE_className={style.menuItemLink} onPress={() => handleRecent(session)}>{session.name}</Link>
</li>
)) }
))}
</ul>
</Flex>

<Flex direction={'column'} gridArea={'footer'} gap={'16px'}>
<Flex direction={'row'} justifyContent={'start'} alignItems={'center'} gap={'12px'}>
<Image src={HelpIcon} width={'20px'} alt={'Help'}/>
<Image src={HelpIcon} width={'20px'} alt={'Help'} />
<Link href="https://www.aem.live/docs/sidekick-generate-variations" target="_blank" UNSAFE_className={style.menu}>Help & FAQ</Link>
</Flex>
<Flex direction={'row'} justifyContent={'start'} alignItems={'center'} gap={'12px'}>
<Image src={FileTxt} width={'20px'} alt={'Guidelines'}/>
<Image src={FileTxt} width={'20px'} alt={'Guidelines'} />
<Link href={USER_GUIDELINES_URL} target="_blank" UNSAFE_className={style.menu}>User Guidelines</Link>
</Flex>
<Text UNSAFE_className={style.copyright}>Copyright © 2023 Adobe. All rights reserved</Text>
Expand Down
1 change: 1 addition & 0 deletions web-src/src/components/ShellProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const ShellProvider = ({ children, runtime }) => {
user: {
imsToken,
imsOrg,
imsProfile,
},
isUserAuthorized: isAuthorized(imsProfile, imsOrg),
done: page.done,
Expand Down
74 changes: 74 additions & 0 deletions web-src/src/services/ExpressSDKService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2023 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
export class ExpressSDKService {
CDN_URL = 'https://sdk-1p.cc-embed.adobe.com/v3/CCEverywhere.js';
// 'https://sdk.cc-embed.adobe.com/v3/CCEverywhere.js';

constructor({
clientId,
appName,
user, // ShellProvider user
}) {
this.clientId = clientId;
this.appName = appName;
this.user = user;
}

async initExpressEditor() {
const loadExpressSDK = (document, url) => {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = async () => {
if (!window.CCEverywhere) {
reject(new Error('CCEverywhere SDK not found'));
return;
}
try {
// eslint-disable-next-line max-len
// https://docs.cc-embed.adobe.com/v3/release/1p/interfaces/shared_src_types_Authentication_types.UserProfile.html
const userInfo = {
profile: {
userId: this.user.imsProfile.userId,
serviceCode: null,
serviceLevel: null,
},
serviceCode: null,
serviceLevel: null,
};
const authInfo = {
accessToken: this.user.imsToken,
useJumpUrl: false,
forceJumpCheck: false,
};
const ccEverywhere = await window.CCEverywhere.initialize(
{
clientId: this.clientId,
appName: this.appName,
},
{}, // config
userInfo,
authInfo,
);
resolve(ccEverywhere);
} catch (error) {
reject(error);
}
};
script.onerror = () => reject(new Error('Failed to load CCEverywhere SDK'));
document.body.appendChild(script);
});
};

return loadExpressSDK(document, this.CDN_URL);
}
}