From 072f5147a93f3de7efdde731bc2de0c0b764a7e8 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 14 Apr 2022 12:58:15 -0400 Subject: [PATCH 01/18] QA environment --- azure-pipelines.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e58f51862..7b96087d9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -79,4 +79,41 @@ stages: __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) __VUE_APP_HERITAGE_FUNNEL__: $(__VUE_APP_HERITAGE_FUNNEL__) + cfDistributionId: $(cfDistributionId) + + + # QA Build/Deploy + - stage: Qa + variables: + - group: FixMyGlassQa + jobs: + - deployment: qaBuildDeployment + displayName: Build and Deploy FMG - QA + environment: digitalCloud-qa + container: node + workspace: + clean: all + strategy: + runOnce: + deploy: + steps: + - checkout: self + clean: true + - template: templates/digital/step-build-vue.yml@AzureDevOps + parameters: + buildOutputDir: dist + - template: templates/digital/step-deploy-vue.yml@AzureDevOps + parameters: + artifactName: vueDist + awsProfile: $(qaDeploymentProfile) + outputPath: /fmg/ + deployBuckets: + safelite-qa-fmg-us-east-1: + clearFolder: true + deployFolder: '' + region: us-east-1 + appDeployVariables: + __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) + __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) + __VUE_APP_HERITAGE_FUNNEL__: $(__VUE_APP_HERITAGE_FUNNEL__) cfDistributionId: $(cfDistributionId) \ No newline at end of file From 20d1b346f17c259ea1de2cb945cd93eb4a907140 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 21 Apr 2022 11:23:26 -0400 Subject: [PATCH 02/18] GTM/GA for Vue --- azure-pipelines.yml | 3 +++ public/index.html | 12 ++++++++++++ vue.config.js | 8 +++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7b96087d9..2760d6a1a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -79,6 +79,9 @@ stages: __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) __VUE_APP_HERITAGE_FUNNEL__: $(__VUE_APP_HERITAGE_FUNNEL__) + indexDeployVariables: + __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) + __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) cfDistributionId: $(cfDistributionId) diff --git a/public/index.html b/public/index.html index b926ca739..b8a80e384 100644 --- a/public/index.html +++ b/public/index.html @@ -1,6 +1,10 @@ + + @@ -11,9 +15,17 @@ <%= htmlWebpackPlugin.options.title %> + + + + +
diff --git a/vue.config.js b/vue.config.js index c3cf92368..b58adc020 100644 --- a/vue.config.js +++ b/vue.config.js @@ -3,7 +3,13 @@ process.env.VUE_APP_CONSUMER_API_GATEWAY = process.env.VUE_APP_HERITAGE_FUNNEL = "http://localhost:38000/default.aspx"; process.env.VUE_APP_GOOGLE_PLACES_API_KEY = - "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo" + "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo"; + +// GA & GTM +process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+ '>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x';f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-M6XCRH');"; + +process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = "https://www.googletagmanager.com/ns.html?id=GTM-M6XCRH>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x"; + module.exports = { outputDir: "dist/fmg", From ec47baea6f3b3050e07688bf3e65f6920cb277a7 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 21 Apr 2022 11:47:34 -0400 Subject: [PATCH 03/18] include vue.config.release --- vue.release.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vue.release.config.js b/vue.release.config.js index 86563f59e..bb6a6194e 100644 --- a/vue.release.config.js +++ b/vue.release.config.js @@ -2,6 +2,10 @@ process.env.VUE_APP_CONSUMER_API_GATEWAY = "__VUE_APP_CONSUMER_API_GATEWAY__"; process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__"; process.env.VUE_APP_HERITAGE_FUNNEL = "__VUE_APP_HERITAGE_FUNNEL__"; +// GA & GTM +process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__"; +process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = "__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__" + module.exports = { outputDir: "dist/fmg", publicPath: "/fmg", From d61a1aa1a73d5c4ef158516d7337ad56f80a01ea Mon Sep 17 00:00:00 2001 From: bmauger Date: Thu, 21 Apr 2022 12:43:01 -0400 Subject: [PATCH 04/18] Updates to validation error styling when alert is displayed. --- .../button-question/button-question.vue | 1 + src/styles/common-error-styles.scss | 177 ++++++++++-------- 2 files changed, 104 insertions(+), 74 deletions(-) diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index 91c83fc2a..e29f1fd93 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -35,6 +35,7 @@ :selectedValues="selectedValues" data-test="button" :validationRules="validationRules" + :class="[suppressError ? 'alertError' : '']" /> diff --git a/src/styles/common-error-styles.scss b/src/styles/common-error-styles.scss index 1602778d3..f99dc4751 100644 --- a/src/styles/common-error-styles.scss +++ b/src/styles/common-error-styles.scss @@ -1,85 +1,114 @@ -.has-error { - &.list-button, - &.list-card { - border: 1px solid $red; - color: $red; - input[type=checkbox]:focus + label, - input[type=radio]:focus + label { - box-shadow: 0 0 0 2.5px $red; - } - input[type=checkbox]:checked + label { - box-shadow: 0 0 0 1px $red !important; - } - &:hover { - box-shadow: 0px 0px 0px 4px $red-200; - border-radius: 10px !important; - } - } - &.list-button-horizontal { - color: $red; - label { +html { + .has-error { + &.list-button, + &.list-card { border: 1px solid $red; + color: $red; + input[type=checkbox]:focus + label, + input[type=radio]:focus + label { + box-shadow: 0 0 0 2.5px $red; + } + input[type=checkbox]:checked + label { + box-shadow: 0 0 0 1px $red; + } &:hover { box-shadow: 0px 0px 0px 4px $red-200; + border-radius: 10px; } } - input[type=checkbox]:focus + label, - input[type=radio]:focus + label { - box-shadow: 0 0 1px $red !important; - } - } - &.ui-radio, - &.ui-checkbox { - input[type=checkbox], - input[type=radio], - input[type=radio]+label:before, - input[type=checkbox]+label:before { - border: 1px solid $red; - } - input[type=checkbox]:checked + label:before { - border: 1px solid $blue; - } - } - &.textbox-question, - &.dropdown-question { - p { + &.list-button-horizontal { color: $red; - } - input, - select { - border: 1px solid $red; - &:focus { - border: 1px solid transparent; + label { + border: 1px solid $red; + &:hover { + box-shadow: 0px 0px 0px 4px $red-200; + } + } + input[type=checkbox]:focus + label, + input[type=radio]:focus + label { + box-shadow: 0 0 1px $red; } } - select { - background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%23d4281c'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right 0.75rem center; - background-size: 16px 12px; + &.ui-radio, + &.ui-checkbox { + input[type=checkbox], + input[type=radio], + input[type=radio]+label:before, + input[type=checkbox]+label:before { + border: 1px solid $red; + } + input[type=checkbox]:checked + label:before { + border: 1px solid $blue; + } + } + &.textbox-question, + &.dropdown-question { + p { + color: $red; + } + input, + select { + border: 1px solid $red; + &:focus { + border: 1px solid transparent; + } + } + select { + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%23d4281c'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 16px 12px; + } + } + } + //Restore to default style if alert box is present + .alertError { + .has-error { + &.list-button, + &.list-card { + border: 1px solid $gray-500; + input:not(:focus) { + + label { + box-shadow: 0 0 0 1px $gray-500; + border-radius: .5rem; + } + } + input:focus { + border: 1px solid $gray-500; + + label { + box-shadow: 0 0 0 2.5px transparent; + } + } + &:hover { + box-shadow: 0 0 0 4px $blue-300; + + label { + box-shadow: 0 0 0 2.5px transparent; + border: 1px solid $blue; + } + } + } + } + } + + .form-test-error { + color: $red; + font-size: .875rem; + font-weight: 500; + } + + .form-test-invalid { + &.btn.btn-primary { + color: $gray; + background: $gray-200; + cursor: pointer; + pointer-events: all; + } + &.btn.btn-primary:hover, + &.btn.btn-primary:focus, + &.btn.btn-primary:focus-visible { + color: $gray !important; + background: $gray-200; + box-shadow: none; } } } - -.form-test-error { - color: $red; - font-size: .875rem; - font-weight: 500; -} - -.form-test-invalid { - &.btn.btn-primary { - color: $gray; - background: $gray-200; - cursor: pointer; - pointer-events: all; - } - &.btn.btn-primary:hover, - &.btn.btn-primary:focus, - &.btn.btn-primary:focus-visible { - color: $gray !important; - background: $gray-200 !important; - box-shadow: none !important; - } - -} From 3fda76124bd1d2cde66603483c6985ec7f24029e Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 21 Apr 2022 12:53:40 -0400 Subject: [PATCH 05/18] Add 2016 to list of test vehicle years for QA --- src/layouts/vehicle-damage/vehicle-damage.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index f15b862ac..543a02bef 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -281,7 +281,7 @@ export default { navigateForward(partsData){ // Temporary easter egg to navigate to heritage funnel. - const vehicleYearsToShowHeritageFunnel = [ 2001, 2002, 2010 ]; + const vehicleYearsToShowHeritageFunnel = [ 2001, 2002, 2010, 2016 ]; if (vehicleYearsToShowHeritageFunnel.includes(store.getters.vehicle.year)) { navigateToHeritageFunnel(); return; From 80ef6b85ddb25dc103cb7ed41d03a0c995dbe214 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 21 Apr 2022 13:28:17 -0400 Subject: [PATCH 06/18] GA event methods --- src/mixins/base-mixin.js | 41 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index b5a954c43..757583999 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -11,10 +11,10 @@ export default { }; }, methods: { - setCmsContent(cmsContent){ + setCmsContent(cmsContent) { this.$root.cmsContentByWidget = cmsContent; }, - getCmsContent(widgetName, fieldName){ + getCmsContent(widgetName, fieldName) { return this.$root.cmsContentByWidget?.[widgetName]?.[fieldName] ? this.$root.cmsContentByWidget[widgetName][fieldName] : ''; }, dispatchNonBlockingStoreAction(type, payload, encodePayload = true) { @@ -25,10 +25,10 @@ export default { return store.dispatch(type, payload); }, - savePageDataToStore(page, data){ + savePageDataToStore(page, data) { store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data }); }, - onSubmit() {}, // DO NOT REMOVE; needed to prevent default form submit behavior + onSubmit() { }, // DO NOT REMOVE; needed to prevent default form submit behavior onInvalidSubmit({ values, errors, results }) { // identify the first error field and put focus on it // get error names array @@ -40,6 +40,28 @@ export default { el && el.focus(); } }, + + pushEventToGA(category, action, label, value) { + const eventToBePushed = { + 'event': 'ga_event', + 'category': category, + 'action': action, + 'label': label, + 'value': value, + 'path': '/fmg/' + getQueryStringValue('fmgPage') + } + pushToDataLayerIfDefined(eventToBePushed); + }, + + pushPageViewToGA() { + const pageViewEvent = { + 'event': 'logPageview', + 'pagePath': '/fmg/' + getQueryStringValue('fmgPage'), + 'pageTitle': getQueryStringValue('fmgPage') + }; + pushToDataLayerIfDefined(pageViewEvent); + } + }, computed: { storeActions() { @@ -65,3 +87,14 @@ function encodeUriData(payload) { }); } } + +function getQueryStringValue(key) { + var queryStrings = new URLSearchParams(location.search); + return queryStrings.get(key); +} + +function pushToDataLayerIfDefined(data) { + if (window.dataLayer !== undefined) { + window.dataLayer.push(data); + } +} From 723ad593350d1a411dbd37f594af19d517e188ae Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 21 Apr 2022 14:05:35 -0400 Subject: [PATCH 07/18] Test page views --- src/mixins/base-mixin.js | 16 ++++++---------- src/router/index.js | 5 +++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 757583999..11947f26a 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -3,6 +3,7 @@ import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; +import { queryStrings } from "@/constants/query-strings"; export default { data() { @@ -41,23 +42,23 @@ export default { } }, - pushEventToGA(category, action, label, value) { + pushEventToGA(category, action, label, value, pageName) { const eventToBePushed = { 'event': 'ga_event', 'category': category, 'action': action, 'label': label, 'value': value, - 'path': '/fmg/' + getQueryStringValue('fmgPage') + 'path': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}` } pushToDataLayerIfDefined(eventToBePushed); }, - pushPageViewToGA() { + pushPageViewToGA(pageName) { const pageViewEvent = { 'event': 'logPageview', - 'pagePath': '/fmg/' + getQueryStringValue('fmgPage'), - 'pageTitle': getQueryStringValue('fmgPage') + 'pagePath': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}`, + 'pageTitle': pageName }; pushToDataLayerIfDefined(pageViewEvent); } @@ -88,11 +89,6 @@ function encodeUriData(payload) { } } -function getQueryStringValue(key) { - var queryStrings = new URLSearchParams(location.search); - return queryStrings.get(key); -} - function pushToDataLayerIfDefined(data) { if (window.dataLayer !== undefined) { window.dataLayer.push(data); diff --git a/src/router/index.js b/src/router/index.js index ace5b43cc..54c0bfac2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,6 +4,7 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; +import { queryStrings } from "@/constants/query-strings"; // Heritage integration import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; @@ -120,6 +121,10 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- +router.afterEach((to, from) => { + baseMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); +}); + router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { navigate(scenario, currentRoute, false, optionalQuery, optionalParams, optionalPageData); } From 32fc80bbadb5a00faacaf8fca02e1749d4f1912f Mon Sep 17 00:00:00 2001 From: bmauger Date: Thu, 21 Apr 2022 16:59:17 -0400 Subject: [PATCH 08/18] Update border color for input (validation). --- src/styles/common-error-styles.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/styles/common-error-styles.scss b/src/styles/common-error-styles.scss index f99dc4751..165101177 100644 --- a/src/styles/common-error-styles.scss +++ b/src/styles/common-error-styles.scss @@ -73,6 +73,18 @@ html { border-radius: .5rem; } } + input:checked:focus { + + label { + box-shadow: 0 0 0 1px $blue; + border-radius: .5rem; + } + } + input:checked:not(:focus) { + + label { + box-shadow: 0 0 0 1px $blue; + border-radius: .5rem; + } + } input:focus { border: 1px solid $gray-500; + label { From a5faabc3e3ed55f0540ed35a3896b8cf3ea8b5bb Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 22 Apr 2022 16:19:49 -0400 Subject: [PATCH 09/18] CSR-508 Use consistent naming for accountNumber --- src/helpers/heritage-integration/cookie-helper.js | 2 +- src/helpers/heritage-integration/navigation-helper.js | 2 +- src/helpers/heritage-integration/order-helper.js | 1 + src/store/index.js | 10 ++++++---- src/store/store.spec.js | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index bf1c56b72..a0be40075 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -18,7 +18,7 @@ export function updateOrCreateFunnelCookie() { ReferralNumber: store.getters.order.referralNumber, ReferralDate: store.getters.order.referralDate, ReferralCorrelationId: store.getters.order.referralCorrelationId, - ReferralParentAccountNumber: store.getters.order.parentAccountNumber, + ReferralParentAccountNumber: store.getters.order.accountNumber, }); } diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 581d81bb6..724b13f7d 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -48,7 +48,7 @@ export async function navigateToHeritageFunnel() { externalUrls.HERITAGE_FUNNEL, { corid: store.getters.order.referralCorrelationId, - src: "concept-funnel" + src: "concept-funnel", } ); } diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index 73ffa0b7c..35c3b8570 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -41,6 +41,7 @@ export async function saveOrder() { referralNumber: savedOrderInfo.data.referralNumber, referralCorrelationId: savedOrderInfo.data.referralCorrelationId, referralDate: savedOrderInfo.data.referralDate, + accountNumber: savedOrderInfo.data.accountNumber }, false); // Update the cookie with the referral information when saved. diff --git a/src/store/index.js b/src/store/index.js index 33fa6e0f0..5accba70d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -54,7 +54,7 @@ const getDefaultState = () => { referralNumber: null, referralDate: null, referralCorrelationId: null, - parentAccountNumber: 0, + accountNumber: 0, }, applicationUser: { eventBus: [], @@ -124,7 +124,7 @@ export const mutations = { state.order.referralDate = referralDate; }, updateParentAcctNumber(state, parentAcctNumber) { - state.order.parentAccountNumber = parentAcctNumber; + state.order.accountNumber = parentAcctNumber; }, updateIsInsurance(state, isInsurance) { state.order.payment.isInsurance = isInsurance; @@ -222,7 +222,7 @@ export const mutations = { state.order.damage.numberOfChips = orderInformation.numberOfChips; state.order.lineItems.glassParts = orderInformation.parts; - state.order.parentAccountNumber = orderInformation.parentAccountNumber; + state.order.accountNumber = orderInformation.accountNumber; state.order.serviceLocation.zipCode = orderInformation.zipCode; state.order.payment.isInsurance = orderInformation.IsInsuranceOrder; @@ -438,12 +438,14 @@ export const actions = { make: vehicle.make, model: vehicle.model, style: vehicle.style, + vin: vehicle.vin }, numberOfChips: damage.numberOfChips, zipCode: 43215, // TODO CSR-416, should not be hardcoded (state.order.serviceLocation.zipCode) glassToReplace: damage.glassToReplace, referralNumber: context.state.order.referralNumber, - referralDate: context.state.order.referralDate + referralDate: context.state.order.referralDate, + accountNumber: context.state.order.accountNumber }, }); }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 7618cc25a..0f8aab73a 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -221,7 +221,7 @@ describe("Mutations", () => { isRepair: false, numberOfChips: 0, parts: [], - parentAccountNumber: "123456789", + accountNumber: "123456789", insuranceInfo: {} }); From ce988ee1205afd35b4d55e8d5a5da4bc855e9ab9 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 25 Apr 2022 08:39:17 -0400 Subject: [PATCH 10/18] CSR-18 log page events --- src/constants/endpoints.js | 4 +++ src/constants/store-actions.js | 1 + .../heritage-integration/cookie-helper.js | 15 +++++++- src/router/index.js | 33 +++++++++++++++-- src/store/index.js | 36 +++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 2325c29cd..322dab574 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -66,6 +66,10 @@ const endpoints = { LogExperimentExposureIfAssigned:{ url: "/analytics/api/v1/analytics/log-experiment-exposure", method: "POST", + }, + LogActivity:{ + url: "/analytics/api/v1/analytics/activity", + method: "POST", } }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 9e87416d4..7587907dc 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -18,6 +18,7 @@ const storeActions = { SET_REFERRAL_INFORMATION: "setReferralInformation", VALIDATE_ZIP: "validateZip", LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", + LOG_ACTIVITY: "logActivity", // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleAndDependencies", diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index bf1c56b72..d9cabc734 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -72,7 +72,7 @@ export function getDeviceIdValue(){ return cookieValueMatch[0].split('=')[1]; } - return ''; + return '00000000-0000-0000-0000-000000000000'; } /* @@ -88,6 +88,19 @@ export function getSessionKeyValue(){ return 0; } +/* + Gets value of skey cookie, returns 0 if not found. +*/ +export function getSessionIdValue(){ + const cookieValue = getCookieValueByName(cookieNames.SESSION_ID); + + if(cookieValue){ + return cookieValue; + } + + return '00000000-0000-0000-0000-000000000000'; +} + /* =========================== = PRIVATE FUNCTIONS = diff --git a/src/router/index.js b/src/router/index.js index ace5b43cc..fadcf66a1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -18,6 +18,8 @@ import store from "@/store"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; +import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; +import { settleAllPromises } from "@/helpers/layout-helper"; const routes = [ { @@ -36,7 +38,6 @@ const routes = [ async beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. try { - // If the saved session has timed out, clear the session, execute 404 logic. if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await GoToFunnelStartOn404(next); @@ -76,6 +77,7 @@ const routes = [ await GoToFunnelStartOn404(next); } + logPageEvent(to.query.fmgPage); return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } @@ -97,6 +99,8 @@ const routes = [ await GoToFunnelStartOn404(next); } + logPageEvent(to.query.fmgPage); + // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, @@ -162,7 +166,7 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery if (getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) { await saveOrder(); } - + router.push({ name: "root", query: Object.assign(optionalQuery, { @@ -264,4 +268,29 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } +async function logPageEvent(destinationFmgPageValue){ + const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, + { + userId: getDeviceIdValue(), + sessionKey: getSessionKeyValue(), + pageName: destinationFmgPageValue, + sessionId: getSessionIdValue(), + shouldUseSessionId: true, + pageEvent: { + action: '', + event: 'ENTRY', + } + }, false); + + // Settle promises and get results + const promiseResultMap = [ + { + resultKey: "logActivity", + promise: logActivityPromise, + }, + ]; + + let resultMap = await settleAllPromises(promiseResultMap); +} + export default router; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 33fa6e0f0..04c966518 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -409,6 +409,42 @@ export const actions = { }); }, + logActivity(context, { userId, sessionKey, pageName, sessionId, pageEvent, customEvent, shouldUseSessionId }) { + var customEventData = {}; + customEvent?.forEach(function(event) + { + var category = event.category; + var action = event.action; + var label = event.label; + var value = event.value; + customEventData[category] = { + category: category, + action: action, + label: label, + value: value + }; + }) + + return globalMethods.callHttpClient({ + method: endpoints.LogActivity.method, + endpoint: endpoints.LogActivity.url, + payload: { + userId: userId, + sessionKey: sessionKey, + sessionId: sessionId, + pageName: pageName, + applicationName: 'SafeliteContent', + shouldUseSessionId: shouldUseSessionId, + pageEvent: { + action: pageEvent.action, + event: pageEvent.event, + }, + customEvent: customEventData + } + }); + }, + + // Parts API Actions getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) { return globalMethods.callHttpClient({ From c71056db22ffee5b80c4a56373e5983e7b061167 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 25 Apr 2022 13:32:36 -0400 Subject: [PATCH 11/18] CSR-18 specs --- .../cookie-helper.spec.js | 16 +++++++++++- src/helpers/unit-test-helper.js | 1 + src/router/index.js | 10 ++++--- .../router-constants/analytics-page-events.js | 5 ++++ src/store/index.js | 2 +- src/store/store.spec.js | 26 +++++++++++++++++++ 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/router/router-constants/analytics-page-events.js diff --git a/src/helpers/heritage-integration/cookie-helper.spec.js b/src/helpers/heritage-integration/cookie-helper.spec.js index b4498f61b..03fca51b5 100644 --- a/src/helpers/heritage-integration/cookie-helper.spec.js +++ b/src/helpers/heritage-integration/cookie-helper.spec.js @@ -1,4 +1,4 @@ -import {getFunnelCookie, getDeviceIdValue, getSessionKeyValue} from "@/helpers/heritage-integration/cookie-helper.js"; +import {getFunnelCookie, getDeviceIdValue, getSessionKeyValue, getSessionIdValue} from "@/helpers/heritage-integration/cookie-helper.js"; import { removeAllTestCookies, setupCookies } from "@/helpers/unit-test-helper"; describe("cookies", () => { @@ -126,5 +126,19 @@ describe("cookies", () => { }); }); + + describe("getSessionIdValue", () => { + test("getSessionIdValue, should return GUID", () => { + // Arrange + setupCookies({}); + + // Act + const result = getSessionIdValue(); + + //Assert + expect(result).toBe('cba0c3d1-3c1b-4305-bb56-31aa50f58e27'); + + }); + }); }) \ No newline at end of file diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 20fad7ba2..753465886 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -62,6 +62,7 @@ export const cookies = { "anotherCookie": "{}", "someOtherCookie": "{}", "dxdev": "did=21b9b94a-ec23-42c1-aaac-e2ae4e4dbffe", + "sid": "cba0c3d1-3c1b-4305-bb56-31aa50f58e27", "skey": "12345" }; diff --git a/src/router/index.js b/src/router/index.js index 57a1cc3e2..985d90e11 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -21,6 +21,7 @@ import ComponentTest from "@/layouts/component-test/component-test.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import { analyticsPageEvents } from "./router-constants/analytics-page-events"; const routes = [ { @@ -78,7 +79,7 @@ const routes = [ await GoToFunnelStartOn404(next); } - logPageEvent(to.query.fmgPage); + // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } @@ -100,7 +101,7 @@ const routes = [ await GoToFunnelStartOn404(next); } - logPageEvent(to.query.fmgPage); + // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); // Assign current query string parameters, as well as our fmgPage one. next({ @@ -127,6 +128,7 @@ const router = createRouter({ router.afterEach((to, from) => { baseMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); + logPageEvent(to.query[queryStrings.FMG_PAGE], analyticsPageEvents.ENTRY); }); router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { @@ -273,7 +275,7 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } -async function logPageEvent(destinationFmgPageValue){ +async function logPageEvent(destinationFmgPageValue, pageEvent){ const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, { userId: getDeviceIdValue(), @@ -283,7 +285,7 @@ async function logPageEvent(destinationFmgPageValue){ shouldUseSessionId: true, pageEvent: { action: '', - event: 'ENTRY', + event: pageEvent, } }, false); diff --git a/src/router/router-constants/analytics-page-events.js b/src/router/router-constants/analytics-page-events.js new file mode 100644 index 000000000..ab4753b3d --- /dev/null +++ b/src/router/router-constants/analytics-page-events.js @@ -0,0 +1,5 @@ +const analyticsPageEvents = { + ENTRY: "ENTRY", +}; + +export { analyticsPageEvents }; diff --git a/src/store/index.js b/src/store/index.js index 04c966518..85b3e7a70 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -433,7 +433,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteContent', + applicationName: 'SafeliteDotCom', shouldUseSessionId: shouldUseSessionId, pageEvent: { action: pageEvent.action, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 7618cc25a..e5903ad64 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -617,6 +617,32 @@ describe("Actions", () => { expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, "xxx-xxx-xxx"); }); + it("logActivity action, should return nothing", async () => { + + // Arrange + const context = state; + var pageEvent = { + action: "", + event: "ENTRY", + } + + var customEvent = [{ + category: "tstCat", + action: "click", + label: "damage", + value: "psych" + }]; + + // Act + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ }); + }); + + // Assert + const response = await actions.logActivity(context, { userId: "userId", sessionKey: "sessionKey", pageName: "pageName", sessionId: "sessionId", pageEvent: pageEvent, customEvent: customEvent, shouldUseSessionId: true }); + expect(response).toEqual({}); + }); + }); describe("Getters", () => { From 8d04bc48450460faffd4fed585fd6ae0ecc95404 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Apr 2022 09:09:22 -0400 Subject: [PATCH 12/18] CSR-447: fix groupName so it can be used as an ID --- src/layouts/vehicle-make/make-question/make-question.vue | 2 +- src/layouts/vehicle-model/model-question/model-question.vue | 2 +- src/layouts/vehicle-style/style-question/style-question.vue | 2 +- src/layouts/vehicle-year/year-question/year-question.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/layouts/vehicle-make/make-question/make-question.vue b/src/layouts/vehicle-make/make-question/make-question.vue index 559568236..e1493c536 100644 --- a/src/layouts/vehicle-make/make-question/make-question.vue +++ b/src/layouts/vehicle-make/make-question/make-question.vue @@ -5,7 +5,7 @@ selectingInitiatesLoad :questionText="questionText" :answers="makes" - groupName="Choose Vehicle Make" + groupName="ChooseVehicleMake" textPosition="text-start" v-model="selectedValueAsArray" isRequired=true diff --git a/src/layouts/vehicle-model/model-question/model-question.vue b/src/layouts/vehicle-model/model-question/model-question.vue index c05732352..e3a56e8c7 100644 --- a/src/layouts/vehicle-model/model-question/model-question.vue +++ b/src/layouts/vehicle-model/model-question/model-question.vue @@ -5,7 +5,7 @@ selectingInitiatesLoad :questionText="questionText" :answers="models" - groupName="Choose Vehicle Model" + groupName="ChooseVehicleModel" textPosition="text-start" v-model="selectedValueAsArray" isRequired=true diff --git a/src/layouts/vehicle-style/style-question/style-question.vue b/src/layouts/vehicle-style/style-question/style-question.vue index 0d3dd54ac..e7a289bfd 100644 --- a/src/layouts/vehicle-style/style-question/style-question.vue +++ b/src/layouts/vehicle-style/style-question/style-question.vue @@ -5,7 +5,7 @@ selectingInitiatesLoad :questionText="questionText" :answers="styles" - groupName="Choose Vehicle Style" + groupName="ChooseVehicleStyle" textPosition="text-start" v-model="selectedValueAsArray" isRequired=true diff --git a/src/layouts/vehicle-year/year-question/year-question.vue b/src/layouts/vehicle-year/year-question/year-question.vue index 8a53e83db..16bac5442 100644 --- a/src/layouts/vehicle-year/year-question/year-question.vue +++ b/src/layouts/vehicle-year/year-question/year-question.vue @@ -5,7 +5,7 @@ selectingInitiatesLoad :questionText="questionText" :answers="years" - groupName="Choose Vehicle Year" + groupName="ChooseVehicleYear" textPosition="text-start" v-model="selectedValueAsArray" isRequired=true From 61dbd2fc038115d9bf9911dbdfa509b8d604bbd5 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 26 Apr 2022 09:17:21 -0400 Subject: [PATCH 13/18] CSR-18 refactors --- src/mixins/analytics-mixin.js | 66 ++++++++++++++++++++++++++++++ src/mixins/analytics-mixin.spec.js | 21 ++++++++++ src/mixins/base-mixin.js | 29 ------------- src/router/index.js | 35 ++-------------- 4 files changed, 90 insertions(+), 61 deletions(-) create mode 100644 src/mixins/analytics-mixin.js create mode 100644 src/mixins/analytics-mixin.spec.js diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js new file mode 100644 index 000000000..a62a0bd1a --- /dev/null +++ b/src/mixins/analytics-mixin.js @@ -0,0 +1,66 @@ +import { storeActions } from "@/constants/store-actions"; +import baseMixin from "@/mixins/base-mixin"; +import { settleAllPromises } from "@/helpers/layout-helper"; +import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; +import { queryStrings } from "@/constants/query-strings"; + +export default { + methods: { + async logPageEvent(destinationFmgPageValue, pageEvent){ + const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, + { + userId: getDeviceIdValue(), + sessionKey: getSessionKeyValue(), + pageName: destinationFmgPageValue, + sessionId: getSessionIdValue(), + shouldUseSessionId: true, + pageEvent: { + action: '', + event: pageEvent, + } + }, false); + + // Settle promises and get results + const promiseResultMap = [ + { + resultKey: "logActivity", + promise: logActivityPromise, + }, + ]; + + let resultMap = await settleAllPromises(promiseResultMap); + }, + + pushEventToGA(category, action, label, value, pageName) { + const eventToBePushed = { + 'event': 'ga_event', + 'category': category, + 'action': action, + 'label': label, + 'value': value, + 'path': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}` + } + pushToDataLayerIfDefined(eventToBePushed); + }, + + pushPageViewToGA(pageName) { + const pageViewEvent = { + 'event': 'logPageview', + 'pagePath': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}`, + 'pageTitle': pageName + }; + pushToDataLayerIfDefined(pageViewEvent); + } + }, + computed: { + storeActions() { + return storeActions; + }, + }, +}; + +function pushToDataLayerIfDefined(data) { + if (window.dataLayer !== undefined) { + window.dataLayer.push(data); + } +} \ No newline at end of file diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js new file mode 100644 index 000000000..c85a637fc --- /dev/null +++ b/src/mixins/analytics-mixin.spec.js @@ -0,0 +1,21 @@ +import analyticsMixin from "@/mixins/analytics-mixin"; +import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { storeActions } from "@/constants/store-actions"; + +describe("analyticsMixin.js", () => { + test("logPageEvent: calls dispatch with type and payload", () => { + const type = ""; + const payload = {}; + + const mockData = { + actionList: [{ + actionName: storeActions.LOG_ACTIVITY + }], + } + var mocks = setupMocksForJsFiles(mockData); + + analyticsMixin.methods.logPageEvent(type, payload); + + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toBeCalled(); + }); +}); \ No newline at end of file diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 11947f26a..43ce3f6f0 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -3,7 +3,6 @@ import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; -import { queryStrings } from "@/constants/query-strings"; export default { data() { @@ -41,28 +40,6 @@ export default { el && el.focus(); } }, - - pushEventToGA(category, action, label, value, pageName) { - const eventToBePushed = { - 'event': 'ga_event', - 'category': category, - 'action': action, - 'label': label, - 'value': value, - 'path': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}` - } - pushToDataLayerIfDefined(eventToBePushed); - }, - - pushPageViewToGA(pageName) { - const pageViewEvent = { - 'event': 'logPageview', - 'pagePath': `/fmg/?${queryStrings.FMG_PAGE}=${pageName}`, - 'pageTitle': pageName - }; - pushToDataLayerIfDefined(pageViewEvent); - } - }, computed: { storeActions() { @@ -88,9 +65,3 @@ function encodeUriData(payload) { }); } } - -function pushToDataLayerIfDefined(data) { - if (window.dataLayer !== undefined) { - window.dataLayer.push(data); - } -} diff --git a/src/router/index.js b/src/router/index.js index 985d90e11..1d46eec5f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -15,12 +15,11 @@ import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel } from "@/helpe import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; +import analyticsMixin from "@/mixins/analytics-mixin"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; -import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; -import { settleAllPromises } from "@/helpers/layout-helper"; import { analyticsPageEvents } from "./router-constants/analytics-page-events"; const routes = [ @@ -79,7 +78,6 @@ const routes = [ await GoToFunnelStartOn404(next); } - // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } @@ -101,8 +99,6 @@ const routes = [ await GoToFunnelStartOn404(next); } - // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); - // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, @@ -127,8 +123,8 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- router.afterEach((to, from) => { - baseMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); - logPageEvent(to.query[queryStrings.FMG_PAGE], analyticsPageEvents.ENTRY); + analyticsMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); + analyticsMixin.methods.logPageEvent(to.query[queryStrings.FMG_PAGE], analyticsPageEvents.ENTRY); }); router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { @@ -275,29 +271,4 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } -async function logPageEvent(destinationFmgPageValue, pageEvent){ - const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, - { - userId: getDeviceIdValue(), - sessionKey: getSessionKeyValue(), - pageName: destinationFmgPageValue, - sessionId: getSessionIdValue(), - shouldUseSessionId: true, - pageEvent: { - action: '', - event: pageEvent, - } - }, false); - - // Settle promises and get results - const promiseResultMap = [ - { - resultKey: "logActivity", - promise: logActivityPromise, - }, - ]; - - let resultMap = await settleAllPromises(promiseResultMap); -} - export default router; \ No newline at end of file From ff8b2d06e7346357c2b0d14874a390645fccf720 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 26 Apr 2022 09:45:23 -0400 Subject: [PATCH 14/18] CSR-18 add mixin to main --- src/main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.js b/src/main.js index fd53bde6d..6a81170db 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,7 @@ import App from "./App.vue"; import router from "./router"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; +import analyticsMixin from "@/mixins/analytics-mixin.js"; import "../node_modules/bootstrap/dist/js/bootstrap.js"; // Vue App Setup @@ -15,5 +16,6 @@ vueApp.use(store); vueApp.use(LoadScript); vueApp.use(Maska); vueApp.mixin(baseMixin); +vueApp.mixin(analyticsMixin); vueApp.mount("#app"); From f991b73f663bbf6757bb5588bedf09119be99716 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Apr 2022 09:51:13 -0400 Subject: [PATCH 15/18] CSR-447: refactoring logic of buttons and events, remove unused logic --- .../list-button-horizontal.vue | 66 +++++++++++------ src/ux-components/list-button/list-button.vue | 60 ++++++++++------ src/ux-components/list-card/list-card.vue | 70 +++++++++++++------ src/ux-components/radio/radio.vue | 20 +++--- 4 files changed, 139 insertions(+), 77 deletions(-) diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index bd1977ba3..006718bed 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -2,8 +2,12 @@
@@ -77,27 +84,47 @@ export default { checkValue: Boolean, }; }, - created(){ - if(Array.isArray(this.selectedValues)){ - this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0]; + created() { + if (Array.isArray(this.selectedValues)) { + this.checkValue = this.isMultiSelect + ? this.selectedValues.includes(this.value) + : this.selectedValues[0]; } }, methods: { displayLoader() { this.isLoaderDisplayed = true; }, - handleClick(value) { - if(this.selectingInitiatesLoad) { - this.displayLoader(); + handleInputChange() { + if(!this.selectingInitiatesLoad) { + this.handleCheckChange(); + } + }, + handleKeyupArrow() { + if (this.isMultiSelect) { + return; // Prevent arrow keys from doing anything if element is a checkbox + } + + if(!this.selectingInitiatesLoad) { this.handleCheckChange(); } - this.handleChange(value); + this.handleChange(this.value); }, - handleCheckChange(newValue, oldValue){ - const isInitialization = typeof(oldValue) === 'function'; - if (!isInitialization) { - this.$emit('isCheckedChanged', { checkValue: this.checkValue, value: this.value.toString() }); + triggerButton() { + if(this.selectingInitiatesLoad) { + this.displayLoader(); + this.handleCheckChange(); } + this.handleChange(this.value); + }, + handleCheckChange() { + const emitEvent = { + checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question + value: this.value.toString(), + buttonId: this.buttonID && this.buttonID.toString(), + }; + this.$emit("isCheckedChanged", emitEvent); + this.$emit("update:modelValue", emitEvent); } }, components: { @@ -105,6 +132,7 @@ export default { }, setup(props) { const inputType = props.isMultiSelect ? "checkbox" : "radio"; + const fieldOptions = { type: inputType, checkedValue: props.value, @@ -118,13 +146,11 @@ export default { } const { - checked, handleChange, errors, } = useField(props.groupName, props.validationRules, fieldOptions); return { - checked, handleChange, errors, fieldOptions, // only need to expose this for unit test purposes diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index d48b2407d..300bf6baa 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -2,8 +2,12 @@
@@ -80,33 +84,47 @@ export default { checkValue: Boolean, }; }, - created(){ - if(Array.isArray(this.selectedValues)){ - this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0]; + created() { + if (Array.isArray(this.selectedValues)) { + this.checkValue = this.isMultiSelect + ? this.selectedValues.includes(this.value) + : this.selectedValues[0]; } }, methods: { displayLoader() { this.isLoaderDisplayed = true; }, - handleClick(value) { + handleInputChange() { + if(!this.selectingInitiatesLoad) { + this.handleCheckChange(); + } + }, + handleKeyupArrow() { + if (this.isMultiSelect) { + return; // Prevent arrow keys from doing anything if element is a checkbox + } + + if(!this.selectingInitiatesLoad) { + this.handleCheckChange(); + } + this.handleChange(this.value); + }, + triggerButton() { if(this.selectingInitiatesLoad) { this.displayLoader(); this.handleCheckChange(); } - this.handleChange(value); + this.handleChange(this.value); }, - handleCheckChange(value, oldValue){ - const isInitialization = typeof(oldValue) === 'function'; - if (!isInitialization) { - const emitEvent = { - checkValue: this.checkValue, - value: this.value.toString(), - buttonId: this.buttonID.toString(), - }; - this.$emit('isCheckedChanged', emitEvent); - this.$emit("update:modelValue", emitEvent); - } + handleCheckChange() { + const emitEvent = { + checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question + value: this.value.toString(), + buttonId: this.buttonID && this.buttonID.toString(), + }; + this.$emit("isCheckedChanged", emitEvent); + this.$emit("update:modelValue", emitEvent); }, }, components: { @@ -128,13 +146,11 @@ export default { } const { - checked, handleChange, errors, } = useField(props.groupName, props.validationRules, fieldOptions); return { - checked, handleChange, errors, fieldOptions, // only need to expose this for unit test purposes diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index a178895fb..ae563a952 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -6,8 +6,12 @@ isWide ? 'horizontal' : '', (errors.length > 0 || hasError) ? 'has-error' : '', ]" - @mouseup="handleChange(value)" - @keyup.space="handleChange(value)" + @mouseup="triggerButton()" + @keyup.space="triggerButton()" + @keyup.up="handleKeyupArrow()" + @keyup.down="handleKeyupArrow()" + @keyup.left="handleKeyupArrow()" + @keyup.right="handleKeyupArrow()" >