Skip to content

Commit

Permalink
Sync main with stage (#198)
Browse files Browse the repository at this point in the history
* universal promo terms 1st commit

* Added API failure case handler

* Remove console.log and updated the failure case.

* nit: typo

* Setting default api_key

* nit: TODO

* icon / other original content support, css to hide header/footer completely.

* poc reviewd

* api key updated

* nit: eslint update

* nit: eslint update

* nit: eslint update

* nit: eslint update

* nit: eslint update

* nit: eslint update

* test added

* added test

* MWPW-142280 Firefly single feature marquee (#191)

* firefly single feature

* fix lint issue

* fix blinking cursor issue on mobile and tablet

* optimize

---------

Co-authored-by: Ruchika Sinha <tek10248@Ruchikas-MacBook-Pro.local>

* MWPW-143215 [sidenav]  make re-ordering possible with camel case (#192)

* service_providers is now optional as api_key

* update test

* MWPW-143533-Handle css for 2 values in selector tray (#195)

* MWPW-143533

* fix issues

---------

Co-authored-by: Ruchika Sinha <tek10248@Ruchikas-MacBook-Pro.local>

* [Universal promo terms] update env logic (#197)

* stage condition added for env

* check prod URL instead

---------

Co-authored-by: Sean Choi <seanchoi@adobe.com>
Co-authored-by: Ruchika Sinha <tek10248@Ruchikas-MacBook-Pro.local>
Co-authored-by: Nicolas Peltier <1032754+npeltier@users.noreply.github.com>
  • Loading branch information
4 people authored Mar 4, 2024
1 parent ee2a98d commit f57f7c6
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 30 deletions.
2 changes: 1 addition & 1 deletion creativecloud/blocks/sidenav/sidenav.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '../../deps/merch-sidenav.js';
const CATEGORY_ID_PREFIX = 'categories/';
const TYPE_ID_PREFIX = 'types/';

const getIdLeaf = (id) => (id?.substring(id.lastIndexOf('/') + 1) || id);
const getIdLeaf = (id) => (id?.substring(id.lastIndexOf('/') + 1) || id).toLowerCase();

const getCategories = (items, isMultilevel, mapCategories) => {
const configuration = { manageTabIndex: true };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@media (min-width: 900px) {
body .feds-topnav-wrapper {
border: 0;
}
}

body .global-footer {
background: none;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const OFFER_ID_API_BASE = 'https://aos.adobe.io/offers/';
const SELECTOR_ID_API_BASE = 'https://aos.adobe.io/offers:search.selector';
const STAGE_OFFER_ID_API_BASE = 'https://aos-stage.adobe.io/offers/';
const STAGE_SELECTOR_ID_API_BASE = 'https://aos-stage.adobe.io/offers:search.selector';
const API_KEY = 'universalPromoTerm';
const SERVICE_PROVIDERS = 'PROMO_TERMS';

function getEnv(env) {
if (env) return env;
if (window.location.origin.hostname === 'www.adobe.com') return 'production';
return 'stage';
}

async function getTermsHTML(params, el, env, search) {
const locationSearch = search ?? window.location.search;
let promoTerms;
if (!params.get('offer_selector_ids')) {
let fetchURL = `${env === 'stage' ? STAGE_OFFER_ID_API_BASE : OFFER_ID_API_BASE}${params.get('offer_id')}${locationSearch}`;
fetchURL += params.get('api_key') ? '' : `&api_key=${API_KEY}`;
fetchURL += params.get('service_providers') ? '' : `&service_providers=${SERVICE_PROVIDERS}`;

const res = await fetch(fetchURL);
if (!res.ok) return false;
const json = await res.json();
promoTerms = json[0]?.promo_terms;
} else {
let fetchURL = `${env === 'stage' ? STAGE_SELECTOR_ID_API_BASE : SELECTOR_ID_API_BASE}${locationSearch}`;
fetchURL += params.get('api_key') ? '' : `&api_key=${API_KEY}`;
fetchURL += params.get('service_providers') ? '' : `&service_providers=${SERVICE_PROVIDERS}`;

const res = await fetch(fetchURL);
if (!res.ok) return false;
const json = await res.json();
promoTerms = json[0]?.offers[0]?.promo_terms;
}

if (!promoTerms || !promoTerms.header || !promoTerms.text) {
return false;
}
return `<div class="container">${el.innerHTML}<h1>${promoTerms.header}</h1><p>${promoTerms.text}</p></div>`;
}

export default async function init(el, search) {
const params = new URLSearchParams(search ?? window.location.search);
const env = getEnv(params.get('env'));
const termsHTML = await getTermsHTML(params, el, env, search);
if (!termsHTML && env !== 'stage') {
window.location = '404.html';
} else {
el.innerHTML = termsHTML;
}
}
32 changes: 28 additions & 4 deletions creativecloud/features/firefly/firefly-interactive.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,34 @@

@media (max-width: 600px) {
.firefly-selectortray {
min-width: 110%;
margin-inline: -22px 16px;
justify-content: center;
margin-top: -7px;
margin-bottom: 24px;
width: 80%;
margin-inline-start: 20px;
}

.firefly-selectortray.three-options {
width: 110%;
margin-inline: -22px 16px;
}

.interactive-marquee.firefly .interactive-container {
height: 440px;
}

.interactive-marquee.firefly .media {
top: 8px;
top: 24px;
}

.interactive-marquee.firefly .foreground {
padding-top: 0;
}

.interactive-marquee.firefly.ff-text-effects .interactive-container,
.interactive-marquee.firefly.ff-text-to-image .interactive-container {
height: 346px;
}
}

@media (min-width: 600px) and (max-width: 1199px) {
Expand All @@ -113,6 +123,11 @@

.firefly-selectortray {
top: 0;
width: 50%;
margin-inline: 126px;
}

.firefly-selectortray.three-options {
margin-inline: 42px;
width: 80%;
}
Expand All @@ -124,15 +139,24 @@
.interactive-marquee.firefly .foreground {
padding-top: 0;
}

.interactive-marquee.firefly.ff-text-effects .interactive-container,
.interactive-marquee.firefly.ff-text-to-image .interactive-container {
height: 662px;
}
}

@media screen and (min-width: 1200px) {
.firefly-selectortray {
top: 144px;
top: 187px;
position: absolute;
right: -122px;
}

.firefly-selectortray.three-options {
top: 144px;
}

[dir="rtl"] .firefly-selectortray {
left: -122px;
right: 446px;
Expand Down
66 changes: 44 additions & 22 deletions creativecloud/features/firefly/firefly-interactive.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import { getLibs } from '../../scripts/utils.js';

const { default: defineDeviceByScreenSize } = await import('../../scripts/decorate.js');

function focusOnInput(media, createTag) {
const input = media.querySelector('.prompt-text');
if (input) {
input.focus();
const device = defineDeviceByScreenSize();
const blinkingCursor = createTag('div', { class: 'blinking-cursor' });
if (input.classList.contains('light')) blinkingCursor.classList.add('blink-light');
if (device === 'MOBILE' || device === 'TABLET') {
input.insertAdjacentElement('beforebegin', blinkingCursor);
} else input.focus();
input.addEventListener('focusout', () => {
if (document.querySelector('.locale-modal-v2')) {
const blinkingCursor = createTag('div', { class: 'blinking-cursor' });
if (document.querySelector('.locale-modal-v2') && device === 'DESKTOP') {
input.insertAdjacentElement('beforebegin', blinkingCursor);
if (input.classList.contains('light')) blinkingCursor.classList.add('blink-light');
}
}, { once: true });
input.addEventListener('click', () => { document.querySelector('.blinking-cursor')?.remove(); });
}
}

function eventOnGenerate(generateButton, media) {
function eventOnGenerate(generateButton, media, fireflyfeature = '') {
const btnConfigs = {
TextToImage: ['SubmitTextToImage', 'SubmitTextToImageUserContent', 'goToFirefly'],
TextEffects: ['SubmitTextEffects', 'SubmitTextEffectsUserContent', 'goToFireflyEffects'],
Expand All @@ -24,8 +29,11 @@ function eventOnGenerate(generateButton, media) {
const userprompt = media.querySelector('.prompt-text')?.value;
const placeholderprompt = media.querySelector('.prompt-text')?.getAttribute('placeholder');
const prompt = userprompt || placeholderprompt;
const selected = media.querySelector('.selected');
const className = selected.getAttribute('class').split(' ')[1].trim();
let className = '';
if (fireflyfeature === '') {
const selected = media.querySelector('.selected');
className = selected.getAttribute('class').split(' ')[1].trim();
} else className = fireflyfeature;
if (Object.keys(btnConfigs).includes(className)) {
const btnConfig = btnConfigs[className];
const dall = userprompt === '' ? btnConfig[0] : btnConfig[1];
Expand Down Expand Up @@ -86,6 +94,16 @@ async function eventOnSelectorOption(option, prompt, media, mediaP, createPrompt
}
}

async function singleFireflyFeature(promptDet, mode, createPromptField, media, feature, createTag) {
const firstOptionDetail = promptDet.innerText.split('|');
const fireflyPrompt = await createPromptField(`${firstOptionDetail[0]}`, `${firstOptionDetail[1]}`, mode);
fireflyPrompt.classList.add('firefly-prompt');
media.appendChild(fireflyPrompt);
const generateButton = media.querySelector('#promptbutton');
eventOnGenerate(generateButton, media, feature);
focusOnInput(media, createTag);
}

export default async function setInteractiveFirefly(el) {
const enticementMode = el.classList.contains('light') ? 'light' : 'dark';
const interactiveElemMode = el.classList.contains('light') ? 'dark' : 'light';
Expand Down Expand Up @@ -128,7 +146,6 @@ export default async function setInteractiveFirefly(el) {
};
selections.push(option);
});

[...allP].forEach((s) => { if (!s.querySelector('picture') && !s.querySelector('video')) s.remove(); });
const mediaP = media.querySelectorAll('p:not(:empty)');
[...mediaP].forEach((image) => { image.classList.add('hide'); });
Expand All @@ -139,52 +156,57 @@ export default async function setInteractiveFirefly(el) {
const enticementIcon = allAnchorTag[0].href;
const enticementDiv = await createEnticement(`${enticementText}|${enticementIcon}`, enticementMode);
media.appendChild(enticementDiv, media.firstChild);

const { createTag } = await import(`${getLibs()}/utils/utils.js`);
if (el.classList.contains('ff-text-effects')) {
mediaP[0].classList.remove('hide');
singleFireflyFeature(allP[2], interactiveElemMode, createPromptField, media, 'TextEffects', createTag);
return;
}
if (el.classList.contains('ff-text-to-image')) {
mediaP[0].classList.remove('hide');
singleFireflyFeature(allP[2], interactiveElemMode, createPromptField, media, 'TextToImage', createTag);
return;
}
const fireflyOptions = await createSelectorTray(selections, interactiveElemMode);
fireflyOptions.classList.add('firefly-selectortray');
if (selections.length === 3) fireflyOptions.classList.add('three-options');
media.append(fireflyOptions);

const ttiOption = media.querySelector('.TextToImage');
const genFillOption = media.querySelector('.GenerativeFill');
const teOption = media.querySelector('.TextEffects');
const firstOption = media.querySelector('.selector-tray > button');

hideRemoveElements(firstOption, media, mediaP);
const { createTag } = await import(`${getLibs()}/utils/utils.js`);

const genfillPrompt = createGenFillPrompt(genfDetail.promptpos, createTag);

// Create prompt field for first option on page load
const firstOptionDetail = allP[3].innerText.split('|');
const fireflyPrompt = await createPromptField(`${firstOptionDetail[0]}`, `${firstOptionDetail[1]}`, interactiveElemMode);
const mode = firstOption.classList.contains('GenerativeFill') ? 'genfill' : interactiveElemMode;
const fireflyPrompt = await createPromptField(`${firstOptionDetail[0]}`, `${firstOptionDetail[1]}`, mode);
if (firstOption.classList.contains('TextToImage') || firstOption.classList.contains('TextEffects')) {
fireflyPrompt.classList.add('firefly-prompt');
media.appendChild(fireflyPrompt);
const generateButton = media.querySelector('#promptbutton');
eventOnGenerate(generateButton, media);
} else if (firstOption.classList.contains('GenerativeFill')) {
fireflyPrompt.classList.add('genfill-promptbar');
const genfillPrompt = createGenFillPrompt(genfDetail.promptpos, createTag);
media.append(genfillPrompt, fireflyPrompt);
const genFillButton = media.querySelector('#genfill');
genFillButton.addEventListener('click', async () => {
const { default: signIn } = await import('./firefly-susi.js');
signIn('', 'goToFireflyGenFill');
});
}

focusOnInput(media, createTag);
/* Handle action on click of each firefly option button */

ttiOption.addEventListener('click', () => {
ttiOption?.addEventListener('click', () => {
eventOnSelectorOption(ttiOption, ttiDetail, media, mediaP, createPromptField, createTag);
});

genFillOption.addEventListener('click', () => {
genFillOption?.addEventListener('click', () => {
eventOnSelectorOption(genFillOption, genfDetail, media, mediaP, createPromptField);
const genfillPrompt = createGenFillPrompt(genfDetail.promptpos, createTag);
media.appendChild(genfillPrompt);
});

teOption.addEventListener('click', () => {
teOption?.addEventListener('click', () => {
eventOnSelectorOption(teOption, teDetail, media, mediaP, createPromptField, createTag);
});
}
4 changes: 2 additions & 2 deletions test/blocks/sidenav/sidenav.test.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ <h2 id="refine-your-results">REFINE YOUR RESULTS</h2>
<li>Social-media</li>
<li>Pdf</li>
<li>Esignatures</li>
<li>Coldfusion</li>
<li>Elearning</li>
<li>ColdFusion</li>
<li>ELearning</li>
<li>Print-imaging</li>
<li>Technical-communication</li>
<li>Insight-audiences</li>
Expand Down
7 changes: 6 additions & 1 deletion test/blocks/sidenav/sidenav.test.html.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ runTests(async () => {
expect(newRoot.title).to.equal('REFINE YOUR RESULTS');
const items = newRoot.querySelectorAll('sp-sidenav-item');
expect(items.length).to.equal(expectedItemCount);
const found = Array.from(items).find((item) => item.getAttribute('label') === 'ColdFusion');
expect(found).to.not.be.undefined;
expect(found.getAttribute('value')).to.equal('coldfusion');
const search = newRoot.querySelector('sp-search');
expect(search.getAttribute('placeholder')).to.equal('Search all your products');
expect(newRoot.querySelectorAll('sp-checkbox').length).to.equal(3);
Expand All @@ -49,7 +52,9 @@ runTests(async () => {
});

it('does create nice reordered categories sidenav', async () => {
await testCategorySidenav('.reordered-categories', 17, 11);
// 16 items from html requirements, 2 parents from taxonomy,
// and special-offer special case is 19
await testCategorySidenav('.reordered-categories', 19, 13);
});

it('does create nice plans sidenav', async () => {
Expand Down
3 changes: 3 additions & 0 deletions test/blocks/universal-promo-terms/mocks/body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
<div class="universal-promo-terms"></div>
</div>
22 changes: 22 additions & 0 deletions test/blocks/universal-promo-terms/universal.promo.terms.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { readFile } from '@web/test-runner-commands';
import { expect } from '@esm-bundle/chai';
import sinon from 'sinon';

document.body.innerHTML = await readFile({ path: './mocks/body.html' });
const { default: init } = await import('../../../creativecloud/blocks/universal-promo-terms/universal-promo-terms.js');

describe('universal-promo-terms', () => {
const block = document.body.querySelector('.universal-promo-terms');
beforeEach(() => {
sinon.spy(console, 'log');
});

afterEach(() => {
console.log.restore();
});

it('Get API from query parameters', async () => {
await init(block, '?offer_id=1B365A793986BBEEE26F3E372BDAAB09&locale=de_DE&promotion_code=fixed_dis_20&country=DE&env=stage');
expect(document.querySelector('.universal-promo-terms').textContent).to.not.equal('false');
});
});
Loading

0 comments on commit f57f7c6

Please sign in to comment.