From fc395b423bf0b8a18c2f948eb02cee66a8a27390 Mon Sep 17 00:00:00 2001 From: Erich Champion Date: Fri, 27 Oct 2023 20:06:35 -0700 Subject: [PATCH] MWPW-137941: Improve quiz performance (#1447) * MWPW-125561 - UAR Results Block (#636) * Initial commit * Basic UAR results * Nested UAR results * Style support Resolves: [MWPW-NUMBER](MWPW-URL) **Test URLs:** - Before: https://main--milo--adobecom.hlx.page/?martech=off - After: https://uar-integration--milo--adobecom.hlx.page/?martech=off * UAR Quiz Block Initial Commit (#682) * Initial commit for question flow in UAR * Refactoring v1 * Refactoring v2 * Refactoring CSS * Mwpw 125561 uar results block - data model updates (#680) * MWPW-125561 - UAR Results Block * Initial commit * Basic UAR results * Nested UAR results * Style support Resolves: [MWPW-NUMBER](MWPW-URL) **Test URLs:** - Before: https://main--milo--adobecom.hlx.page/?martech=off - After: https://uar-integration--milo--adobecom.hlx.page/?martech=off * Adjustments to match data structure from quizzes * Finalized UAR Results (#729) * Finalized UAR Results * Lana logging and a debug param to stop redirects (MWPW-125185) * Set a value for pageload analytics (MWPW-128939) * Unit tests (MWPW-130870) Resolves: [MWPW-125185](https://jira.corp.adobe.com/browse/MWPW-125185) Resolves: [MWPW-128939](https://jira.corp.adobe.com/browse/MWPW-128939) Resolves: [MWPW-130870](https://jira.corp.adobe.com/browse/MWPW-130870) **Test URLs:** - Before: https://main--milo--adobecom.hlx.page/?martech=off - After: https://--milo--adobecom.hlx.page/?martech=off * Set error strings as an exported variable. Used the exported variable in unit tests. * [MWPW-125908] [UAR] Step indicator addition to quiz (#714) * Step indicator addition to quiz * Refactored to use visibility for performance * Hiding stray data * Refactored quiz js/css to not be hard coded and add padding on mobile * css refactor for colors, spacing, better selectors * class naming refactor * Adding the current locale code to the local storage key (#800) Co-authored-by: Honwai Wong * [UAR] cards responsive (#844) * [UAR] Card refinement (#873) * spacing fixes, flex for leftover cards, selected card fix * spacing tweak, dot indicator adjustment * MWPW-125274 - UAR Analytics (#871) * Refactoring question flow and adding analytics data * Adding button analytics data * Setting pageLoadHash in local storage * Refactoring * Adding guardrail around result parsing * MWPW-133219: Hide default content before the preact app loads (#898) * Hide the original, classless div elements within the quiz block by default. Then use a specific selector to restore the wrapper div added by the preact app. * Hide div elements within the quiz that aren't marked with a specific class of their own * Removing code to hide siblings of .quiz-container since they will already be hidden * MWPW-127110 - Quiz footer fragment based on string.json (#895) * quiz footer fragment Loader * quiz footer fragment * quiz footer fragment * quiz footer fragment * quiz footer fragment * test * test * stepIndicator correction --------- Co-authored-by: Elaine Borges Co-authored-by: Elaine Borges * MWPW-133738: Use a different comparison to process question values (#949) * MWPW-133759 - Adding logic to account for single products grouped together (#941) * Adding logic to account for single product grouped together * Refactoring * MWPW-133268 - Rename uar-results to quiz-results (#962) * renamed all block files and references * updated unit tests * updated debug query params Resolves: [MWPW-133268](https://jira.corp.adobe.com/browse/MWPW-133268) **Test URLs:** - Before: https://main--milo--adobecom.hlx.page/?martech=off - After: https://--milo--adobecom.hlx.page/?martech=off * [UAR] - Alternate quiz data (#953) * MWPW-126143 added alternate path for JSON data via search params * empty * Fixed step indicator * Changed to use layouteffect, tests * Reverted slash in query param scenario * Refactored tests and quiz url sourcing * MWPW-134269 - Adding nested fragments based upon the primary product as well as secondary (#1071) * Adding nested fragments based on primary and secondary products * Refactoring * Refactoring - v2 --------- Co-authored-by: Erich Champion * MWPW-134131 - Fixing issue when there are more than one rule with same number of grouping (#1112) * Fixing issue when there are more than one rule with same number of grouping * Addressing review comments * MWPW-135198 - Optimizes quiz-results DOM handling (#1117) * Removed a querySelectorAll * Removed iteration through metadata divs * Add lana logging if the block has been misconfigured Resolves: [MWPW-135198](https://jira.corp.adobe.com/browse/MWPW-135198) * MWPW-132277 - Breakpoint content for Quiz Results (#1128) * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * MWPW-132277 work in progress * setting phone-only as default --------- Co-authored-by: Elaine Borges Co-authored-by: Elaine Borges Co-authored-by: Narcis Radu * MWPW-135125 Quiz button fix (#1153) * button responsive fix * height setting to min-height --------- Co-authored-by: Elaine Borges Co-authored-by: Erich Champion * [UAR] Quiz URL States (#1149) * Managing state via url, support back button, hydrate state with params * Refactored url management & handled existing redirect params from results.json * added handler for back button with known params present * Defered popstate * Refactored to fix errors * Fixed back button click new option bug --------- Co-authored-by: Erich Champion * MWPW-134986 - Rendering nested fragments in the order of products (#1186) Rendering nested fragments in the order of products * MWPW-134823 - QUIZ - Fix Acessibility warning (#1192) clean up lorems Co-authored-by: Elaine Borges * MWPW-135442 - Fixing the issue of NOT operator when the order of selection is changed (#1200) * Fixing the issue of NOT operator when the order of selection is changed * Refactoring * MWPW-135903: If nestedObject[fragKey] exists, append to it instead of replacing (#1208) * MWPW-135903: If nestedObject[fragKey] exists, append to it instead of replacing * MWPW-135903: Feedback from Okan * MWPW-135296 - Quiz css and related markup cleanup (#1219) * MWPW-135296 - Quiz css and related markup cleanup * Drastically simplifies quiz css, removing unused css * Simplified markup, removing unused classes and standardizing the rest * Remove caas related css and classes that were creating linting errors * add icon and cover-image types to cards * add top and bottom classes to progress indicators * set all styling to match the comps from consonant for all devices Resolves: [MWPW-135296](https://jira.corp.adobe.com/browse/MWPW-135296) * fix word breaking on card text * pr feedback adjustments * MWPW-125774 - Quiz block accessibility (#1243) * MWPW-125774 - Quiz block accessibility * Quiz options can now be tabbed to with the keyboard * Quiz options can be activated with space or enter keys * Focus is reset to the top of the quiz when moving to the next question Resolves: [MWPW-125774](https://jira.corp.adobe.com/browse/MWPW-125774) * PR feedback to adjust mobile quiz-option width * fix for icons shrinking on mobile longer text * MWPW-133119 - Adding Unit Tests for Quiz (Utils.js) (#1254) * Adding unit tests for quiz * Refactoring * Refactoring again * Quiz tests (#1260) * MWPW-134984, tests. * cleanup * Remove file * MWPW-136619: Update CODEOWNERS for quiz and quiz-results (#1280) * MWPW-136619: Update CODEOWNERS for quiz and quiz-results * MWPW-136619: Removing extra @ * Update libs/blocks/quiz-results/quiz-results.js adjust logged message for analytics when in debug Co-authored-by: Chris Peyer * PR 1264 quiz.js feedback refactor (#1289) * PR 1264 quiz.js feedback refactor * Clarifying const naming * MWPW-136688 Added quiz and quiz results to MILO_BLOCKS (#1299) Added quiz and quiz results to MILO_BLOCKS * PR 1264 quiz_results.js feedback (#1298) Resolves quiz-results.js feedback in PR #1264 * PR 1264 utils.js feedback refactor (#1329) * Addressing review comments for the main PR * Refactoring --------- Co-authored-by: Erich Champion * MWPW-135730 - Results card-list alignment correction (#1349) results card-list alignment correction Co-authored-by: Elaine Borges Co-authored-by: Erich Champion * MWPW-115213 - Addressing review comments (#1356) * MWPW-136165 - Background reset for quiz footer (#1379) * Allow section metadata dark with static links style without background Resolves: [MWPW-136165](https://jira.corp.adobe.com/browse/MWPW-136165) * MWPW-136162 [UAR] Refactored last step signal to dot indicators (#1369) * MWPW-136162 Refactored last step signal to dot indicators * MWPW-136162 refactored empty array --------- Co-authored-by: Erich Champion * MWPW-135119: redirect to result page if next is valid URL * Revert "MWPW-135119: redirect to result page if next is valid URL" This reverts commit 9d43c15e3f1638d1a466c350dbc1b610a07bb25c. * MWPW-137456 refactored for last step detection (#1400) * Quiz property name updates (#1413) * MWPW-137651 - Quiz property name adjustments * Renamed properties to make them more author friendly Resolves: [MWPW-137651](https://jira.corp.adobe.com/browse/MWPW-137651) * pr feedback fixes for storage * MWPW-135119: Redirect to result pages without loading results.json (#1403) * update divider-inherit css to support different color divider * MWPW-135119: redirect to result page if next is valid URL * fix eslint error * update code according to feedback * fix eslint --------- Co-authored-by: xiasun Co-authored-by: Erich Champion * MWPW-136372 - Fixing stuffs to make performance great again.. (#1429) * Fixing stuffs to make performance great again.. * Refactoring * Fixing tests --------- Co-authored-by: Erich Champion --------- Co-authored-by: Cody Lloyd <119891065+colloyd@users.noreply.github.com> Co-authored-by: Sabya Co-authored-by: Brad Johnson Co-authored-by: Honwai Wong Co-authored-by: Elaine Borges <62952234+elaineskpt@users.noreply.github.com> Co-authored-by: Elaine Borges Co-authored-by: Elaine Borges Co-authored-by: xiasun Co-authored-by: Narcis Radu Co-authored-by: Elaine Borges Co-authored-by: Chris Peyer Co-authored-by: Jacky Sun <67350368+JackySun9@users.noreply.github.com> --- libs/blocks/quiz/quiz.css | 11 ++-- libs/blocks/quiz/quiz.js | 83 +++++++++++++++++++------------ libs/blocks/quiz/utils.js | 11 ++-- test/blocks/quiz/mocks/index.html | 4 +- 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/libs/blocks/quiz/quiz.css b/libs/blocks/quiz/quiz.css index dc5ea52dec..cf90a2386e 100644 --- a/libs/blocks/quiz/quiz.css +++ b/libs/blocks/quiz/quiz.css @@ -10,10 +10,6 @@ text-align: center; } -.quiz { - min-height: calc(100vh - 131px); /* window height minus global nav + global footer heights */ -} - .quiz-container { align-items: center; color: var(--color-white); @@ -232,7 +228,7 @@ } .quiz-step:last-of-type { - width:12px; + width:17px; } .quiz-step-container.top { @@ -267,6 +263,11 @@ margin: 0 0 24px; } +.quiz-footer .section, +.quiz-footer .section.dark { + background: inherit; +} + @media screen and (min-width: 768px) { .quiz-foreground { margin: var(--spacing-xxxl) 0; diff --git a/libs/blocks/quiz/quiz.js b/libs/blocks/quiz/quiz.js index b2266917e0..8f47adf4c1 100644 --- a/libs/blocks/quiz/quiz.js +++ b/libs/blocks/quiz/quiz.js @@ -6,7 +6,7 @@ import { GetQuizOption } from './quizoption.js'; import { DecorateBlockBackground, DecorateBlockForeground } from './quizcontainer.js'; import { initConfigPathGlob, handleResultFlow, handleNext, transformToFlowData, getQuizData, - getAnalyticsDataForBtn, getUrlParams, + getAnalyticsDataForBtn, getUrlParams, isValidUrl, } from './utils.js'; import StepIndicator from './stepIndicator.js'; @@ -88,8 +88,20 @@ const App = ({ if (currentFlow && currentFlow.length) { setSelectedQuestion(questionList[currentFlow] || []); } + + const currentFlowData = questionData[currentFlow].data; + let resultsNext = true; + currentFlowData.forEach((item) => { + if (item.next !== 'RESULT') { + resultsNext = false; + } + }); + + if (resultsNext) { + setTotalSteps(totalSteps - 1); + } } - }, [userFlow, questionList]); + }, [userFlow, questionList, totalSteps, questionData]); /** * Updates the analytics data for the next button. @@ -191,13 +203,19 @@ const App = ({ */ const handleOnNextClick = (selCards) => { setIsBtnClicked(true); - const { nextQuizViews, lastStopValue } = handleNext( + const { nextQuizViews } = handleNext( questionData, selectedQuestion, selCards, userFlow, ); const nextQuizViewsLen = nextQuizViews.length; + const [firstQuizView] = nextQuizViews; + + if (nextQuizViewsLen === 1 && isValidUrl(firstQuizView)) { + window.location.href = firstQuizView; + return; + } setNextQuizViewsExist(!!nextQuizViewsLen); setCurrentStep(currentStep + 1); @@ -216,9 +234,6 @@ const App = ({ setTotalSteps(totalSteps); } } - if (lastStopValue && lastStopValue === 'RESET') { - setTotalSteps(totalSteps - 1); - } resetFocus(); }; let minSelections = 0; @@ -253,7 +268,7 @@ const App = ({ useEffect(() => { const getStringValue = (propName) => { - if (!selectedQuestion) return ''; + if (!selectedQuestion?.questions) return ''; const question = stringQList[selectedQuestion.questions]; return question?.[propName] || ''; }; @@ -264,10 +279,11 @@ const App = ({ }, [selectedQuestion, stringQList]); if (!isDataLoaded || !selectedQuestion) { - return html`
Loading
`; + return null; } const getStringValue = (propName) => { + if (!selectedQuestion?.questions) return ''; const question = stringQList[selectedQuestion.questions]; return question?.[propName] || ''; }; @@ -279,41 +295,42 @@ const App = ({ }; return html`
- <${StepIndicator} + ${selectedQuestion.questions && getStringValue('background') !== '' && html`<${StepIndicator} currentStep=${currentStep} totalSteps=${totalSteps} prevStepIndicator=${prevStepIndicator} top="${true}" /> + `} -
+ ${selectedQuestion.questions && html`
${DecorateBlockBackground(getStringValue)} -
+
`} - <${DecorateBlockForeground} + ${selectedQuestion.questions && html`<${DecorateBlockForeground} heading=${getStringValue('heading')} subhead=${getStringValue('sub-head')} - btnText=${getStringValue('btn')} /> + btnText=${getStringValue('btn')} />`} - <${GetQuizOption} - btnText=${getStringValue('btn')} - minSelections=${minSelections} - maxSelections=${maxSelections} - options=${stringData[selectedQuestion.questions]} - countSelectedCards=${countSelectedCards} - selectedCards=${selectedCards} - onOptionClick=${onOptionClick} - getOptionsIcons=${getOptionsIcons} - handleOnNextClick=${handleOnNextClick} - btnAnalyticsData=${btnAnalytics}/> - - <${StepIndicator} - currentStep=${currentStep} - totalSteps=${totalSteps} - prevStepIndicator=${prevStepIndicator} - bottom="${true}" /> - - + ${selectedQuestion.questions && html`<${GetQuizOption} + btnText=${getStringValue('btn')} + minSelections=${minSelections} + maxSelections=${maxSelections} + options=${stringData[selectedQuestion.questions]} + countSelectedCards=${countSelectedCards} + selectedCards=${selectedCards} + onOptionClick=${onOptionClick} + getOptionsIcons=${getOptionsIcons} + handleOnNextClick=${handleOnNextClick} + btnAnalyticsData=${btnAnalytics}/>`} + + ${selectedQuestion.questions && html` + <${StepIndicator} + currentStep=${currentStep} + totalSteps=${totalSteps} + prevStepIndicator=${prevStepIndicator} + bottom="${true}" /> + `} + `; }; diff --git a/libs/blocks/quiz/utils.js b/libs/blocks/quiz/utils.js index a96f3fde1a..eddf0473bc 100644 --- a/libs/blocks/quiz/utils.js +++ b/libs/blocks/quiz/utils.js @@ -5,11 +5,12 @@ import { getConfig } from '../../utils/utils.js'; const QUESTIONS_EP_NAME = 'questions.json'; const STRINGS_EP_NAME = 'strings.json'; const RESULTS_EP_NAME = 'results.json'; +const VALID_URL_RE = /^(http(s):\/\/.)[-a-z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-z0-9@:%_+.~#?&//=]*)/; let configPath; let quizKey; let analyticsType; let analyticsQuiz; let metaData; const initConfigPath = (quizMetaData) => { - const quizConfigPath = quizMetaData.quizurl.text.toLowerCase(); + const quizConfigPath = quizMetaData.data.text; const urlParams = new URLSearchParams(window.location.search); const stringsPath = urlParams.get('quiz-data'); return (filepath) => `${stringsPath || quizConfigPath}${filepath}`; @@ -17,7 +18,7 @@ const initConfigPath = (quizMetaData) => { const initQuizKey = () => { const { locale } = getConfig(); - quizKey = metaData.storagepath?.text; + quizKey = metaData.storage?.text; return locale?.ietf ? `${quizKey}-${locale.ietf}` : quizKey; }; @@ -355,7 +356,6 @@ export const handleNext = (questionsData, selectedQuestion, userInputSelections, const allcards = Object.keys(userInputSelections); let nextQuizViews = []; let hasResultTrigger = false; - let lastStopValue; allcards.forEach((selection) => { // for each elem in current selection, find its coresponding @@ -373,7 +373,6 @@ export const handleNext = (questionsData, selectedQuestion, userInputSelections, nextQuizViews = []; // Resetting the nextQuizViews // eslint-disable-next-line no-param-reassign userFlow = []; // Resetting the userFlow as well - lastStopValue = 'RESET'; } if (!hasResultTrigger) { @@ -404,7 +403,7 @@ export const handleNext = (questionsData, selectedQuestion, userInputSelections, // Filtering out the NOT() from the nextQuizViews. nextQuizViews = nextQuizViews.filter((view) => view.startsWith('NOT(') === false); - return { nextQuizViews: [...new Set([...userFlow, ...nextQuizViews])], lastStopValue }; + return { nextQuizViews: [...new Set([...userFlow, ...nextQuizViews])] }; }; export const transformToFlowData = (userSelection) => { @@ -431,3 +430,5 @@ export const getAnalyticsDataForLocalStorage = (answers) => { const analyticsHash = `type=${analyticsType}&quiz=${analyticsQuiz}&selectedOptions=${formattedAnswerString}`; return analyticsHash; }; + +export const isValidUrl = (url) => VALID_URL_RE.test(url); diff --git a/test/blocks/quiz/mocks/index.html b/test/blocks/quiz/mocks/index.html index 9e64c7af0c..0b92342598 100644 --- a/test/blocks/quiz/mocks/index.html +++ b/test/blocks/quiz/mocks/index.html @@ -1,7 +1,7 @@
@@ -9,7 +9,7 @@
custom css
-
storagePath
+
storage
cc-quiz