From f3336470d2548164d38d27c8d0c351bda2790543 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 12 Jan 2022 16:28:49 -0500 Subject: [PATCH 01/14] POC --- package-lock.json | 11 +++++++++ package.json | 1 + src/App.vue | 22 ++++++++++++++++- src/constants/store-mutations.js | 1 + src/layouts/not-found/not-found.vue | 3 --- src/main.js | 4 ++++ src/mixins/base-mixin.js | 4 ++++ src/router/index.js | 37 ++++++++++++++++------------- src/store/index.js | 15 +++++++----- 9 files changed, 72 insertions(+), 26 deletions(-) delete mode 100644 src/layouts/not-found/not-found.vue diff --git a/package-lock.json b/package-lock.json index f0cf0ac10..fcb7da487 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "core-js": "^3.6.5", "http-status-codes": "^2.1.4", "jest-junit": "^13.0.0", + "mitt": "^3.0.0", "vue": "^3.0.0", "vue-plugin-load-script": "^2.1.0", "vue-router": "^4.0.11", @@ -16874,6 +16875,11 @@ "node": ">=4.0.0" } }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" + }, "node_modules/mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -37798,6 +37804,11 @@ "through2": "^2.0.0" } }, + "mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" + }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", diff --git a/package.json b/package.json index 6033a0009..2c0d50df3 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "core-js": "^3.6.5", "http-status-codes": "^2.1.4", "jest-junit": "^13.0.0", + "mitt": "^3.0.0", "vue": "^3.0.0", "vue-plugin-load-script": "^2.1.0", "vue-router": "^4.0.11", diff --git a/src/App.vue b/src/App.vue index a44ab87b7..fd17c1309 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,3 +1,23 @@ + + diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 61882b691..ba5aae017 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -4,6 +4,7 @@ const storeMutations = { UPDATE_MODEL: "updateModel", UPDATE_STYLE: "updateStyle", UPDATE_VEHICLE: "updateVehicle", + UPDATE_LAST_PAGE: "updateLastPage", }; export { storeMutations }; diff --git a/src/layouts/not-found/not-found.vue b/src/layouts/not-found/not-found.vue deleted file mode 100644 index 6c4cc8e33..000000000 --- a/src/layouts/not-found/not-found.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/main.js b/src/main.js index c78696333..b6d4c4ce3 100644 --- a/src/main.js +++ b/src/main.js @@ -4,9 +4,11 @@ import App from "./App.vue"; import router from "./router"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; +import mitt from 'mitt'; import "../node_modules/bootstrap/dist/js/bootstrap.js"; // Vue App Setup +const emitter = mitt(); const vueApp = createApp(App); vueApp.use(router); @@ -14,4 +16,6 @@ vueApp.use(store); vueApp.use(LoadScript); vueApp.mixin(baseMixin); +vueApp.config.globalProperties.emitter = emitter; + vueApp.mount("#app"); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index a31a5368f..fcf63c7e1 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -7,6 +7,7 @@ import { widgetNames } from "@/constants/widget-names.js"; export default { data() { return { + routedToLastKnownPage: false, }; }, methods: { @@ -19,6 +20,9 @@ export default { return store.dispatch(type, payload); }, }, + mounted(){ + console.log(this.$route.params); + }, computed: { storeActions() { return storeActions; diff --git a/src/router/index.js b/src/router/index.js index b1aa88493..4ade682eb 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,18 +1,21 @@ +// Supporting files import { createWebHistory, createRouter } from "vue-router"; -import { storeActions } from "@/constants/store-actions.js"; +import { storeActions } from "@/constants/store-actions"; +import { storeMutations } from "@/constants/store-mutations"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; -import ComponentTest from "@/layouts/component-test/component-test.vue"; +import store from "@/store"; +import mitt from 'mitt' +// Components +import ComponentTest from "@/layouts/component-test/component-test.vue"; import AddressPOC from "@/layouts/address-poc/address-poc.vue"; -import NotFound from "@/layouts/not-found/not-found.vue"; -import store from "@/store"; + const routes = [ { path: "/:pathMatch(.*)*", - component: NotFound, name: "NotFound", }, { @@ -30,7 +33,7 @@ const routes = [ beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { - RetainStructureAndGoTo404(to, next); + GoToLastPageFor404(next, store.getters.navigation.lastPage); } else { // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { @@ -50,6 +53,9 @@ const routes = [ component: routeData[0].component, }); + // Assign last route information + store.commit(storeMutations.UPDATE_LAST_PAGE, from.query.fmgPage); + // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, @@ -57,11 +63,10 @@ const routes = [ }); }) .catch((error) => { - // If we can't find the route, go to the 404 page. - RetainStructureAndGoTo404(to, next); + // If we can't find the route, go to the last known page. + GoToLastPageFor404(next, store.getters.navigation.lastPage); - console.log("error:"); - console.log(error); + console.log("Cannot find route, navigating to last page:", error); }); } }, @@ -153,13 +158,13 @@ function GetRouteInfoFromPageName(pageName) { }); } -// Go to our 404 page but retain our structure when we go there (path, queryString, hash). -function RetainStructureAndGoTo404(to, next) { +// Go to our last known page the user was on for a 404. +function GoToLastPageFor404(next, lastPageName) { + + next({ - name: "NotFound", - params: { pathMatch: to.path.split("/").slice(1) }, - query: to.query, - hash: to.hash, + path: '/', + query: { fmgPage: lastPageName }, }); } diff --git a/src/store/index.js b/src/store/index.js index 742e4be25..ff6faf05d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,11 +5,7 @@ import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; export default createStore({ - plugins: [ - createPersistedState({ - storage: window.sessionStorage, - }), - ], + plugins: [createPersistedState()], // IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons: // * The CMS can reference the fields by name @@ -58,6 +54,9 @@ export default createStore({ }, applicationUser: { experiments: null, + navigation: { + lastPage: 'vehicle-year' // our default value is the start page. + } }, }, // See IMPORTANT note at top of "state" declaration. @@ -78,10 +77,14 @@ export default createStore({ updateVehicle(state, data) { state.order.vehicle.carId = data.carId; state.order.vehicle.category = data.category; + }, + updateLastPage(state, page) { + state.applicationUser.navigation.lastPage = page; } }, getters: { - vehicle: state => state.order.vehicle + vehicle: state => state.order.vehicle, + navigation: state => state.applicationUser.navigation }, actions: { // Vehicle API Actions From a7002f47d55d7ff3ee48d88213cc9a911e6e3af3 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Fri, 14 Jan 2022 12:43:17 -0500 Subject: [PATCH 02/14] 404 page to use EventBus --- src/App.vue | 61 +++++++++++++++++++++++------- src/constants/events.js | 12 ++++++ src/helpers/event-bus/event-bus.js | 3 ++ src/main.js | 3 -- src/mixins/base-mixin.js | 17 +++++++-- src/router/index.js | 25 ++++++------ src/store/index.js | 6 +-- 7 files changed, 91 insertions(+), 36 deletions(-) create mode 100644 src/constants/events.js create mode 100644 src/helpers/event-bus/event-bus.js diff --git a/src/App.vue b/src/App.vue index fd17c1309..ec7cecf46 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,23 +1,58 @@ diff --git a/src/constants/events.js b/src/constants/events.js new file mode 100644 index 000000000..58002c389 --- /dev/null +++ b/src/constants/events.js @@ -0,0 +1,12 @@ +const globalEvents = { + GLOBAL_ALERT: "GLOBAL_ALERT", +} + +const globalEventTypes = { + Success: "alert-success", + Warning: "alert-warning", + Info: "alert-info", + Danger: "alert-danger", +} + +export {globalEvents, globalEventTypes} \ No newline at end of file diff --git a/src/helpers/event-bus/event-bus.js b/src/helpers/event-bus/event-bus.js new file mode 100644 index 000000000..d92fdfd56 --- /dev/null +++ b/src/helpers/event-bus/event-bus.js @@ -0,0 +1,3 @@ +import mitt from 'mitt'; + +export const emitter = mitt(); \ No newline at end of file diff --git a/src/main.js b/src/main.js index b6d4c4ce3..322374cfd 100644 --- a/src/main.js +++ b/src/main.js @@ -4,11 +4,9 @@ import App from "./App.vue"; import router from "./router"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; -import mitt from 'mitt'; import "../node_modules/bootstrap/dist/js/bootstrap.js"; // Vue App Setup -const emitter = mitt(); const vueApp = createApp(App); vueApp.use(router); @@ -16,6 +14,5 @@ vueApp.use(store); vueApp.use(LoadScript); vueApp.mixin(baseMixin); -vueApp.config.globalProperties.emitter = emitter; vueApp.mount("#app"); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index fcf63c7e1..4d3363a84 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -1,8 +1,10 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; -import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { widgetNames } from "@/constants/widget-names.js"; +import { emitter } from "@/helpers/event-bus/event-bus"; +import { globalEvents } from "@/constants/events"; export default { data() { @@ -19,9 +21,16 @@ export default { return store.dispatch(type, payload); }, - }, - mounted(){ - console.log(this.$route.params); + emitGlobalMessage(headline, copy, isDismissible, type) { + emitter.emit(globalEvents.GLOBAL_ALERT, { + globalAlertMessage: { + messageHeadline: headline, + messageCopy: copy, + isDismissible: isDismissible, + type: type + } + }); + } }, computed: { storeActions() { diff --git a/src/router/index.js b/src/router/index.js index 4ade682eb..0530fc50e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,15 +4,15 @@ import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "@/constants/store-mutations"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; +import { globalEventTypes } from "@/constants/events"; +import baseMixin from "@/mixins/base-mixin"; import store from "@/store"; -import mitt from 'mitt' // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; import AddressPOC from "@/layouts/address-poc/address-poc.vue"; - - +const FUNNEL_START_PAGE = 'vehicle-year'; const routes = [ { path: "/:pathMatch(.*)*", @@ -33,8 +33,9 @@ const routes = [ beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { - GoToLastPageFor404(next, store.getters.navigation.lastPage); + GoToFunnelStartOn404(next); } else { + // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { return next({ @@ -53,9 +54,6 @@ const routes = [ component: routeData[0].component, }); - // Assign last route information - store.commit(storeMutations.UPDATE_LAST_PAGE, from.query.fmgPage); - // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, @@ -64,7 +62,7 @@ const routes = [ }) .catch((error) => { // If we can't find the route, go to the last known page. - GoToLastPageFor404(next, store.getters.navigation.lastPage); + GoToFunnelStartOn404(next); console.log("Cannot find route, navigating to last page:", error); }); @@ -158,13 +156,18 @@ function GetRouteInfoFromPageName(pageName) { }); } -// Go to our last known page the user was on for a 404. -function GoToLastPageFor404(next, lastPageName) { +// Go to our start page on a 404. +function GoToFunnelStartOn404(next) { + // Emit a global message + baseMixin.methods.emitGlobalMessage('We\'re sorry, something went wrong.', + 'You can get a quote by starting on this page.', + true, + globalEventTypes.Danger); next({ path: '/', - query: { fmgPage: lastPageName }, + query: { fmgPage: FUNNEL_START_PAGE }, }); } diff --git a/src/store/index.js b/src/store/index.js index ff6faf05d..d7ba3f985 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -54,9 +54,6 @@ export default createStore({ }, applicationUser: { experiments: null, - navigation: { - lastPage: 'vehicle-year' // our default value is the start page. - } }, }, // See IMPORTANT note at top of "state" declaration. @@ -83,8 +80,7 @@ export default createStore({ } }, getters: { - vehicle: state => state.order.vehicle, - navigation: state => state.applicationUser.navigation + vehicle: state => state.order.vehicle }, actions: { // Vehicle API Actions From 5f8108e4b8dd748df922137f993eb91c07487bdf Mon Sep 17 00:00:00 2001 From: FrankRua Date: Fri, 14 Jan 2022 16:22:35 -0500 Subject: [PATCH 03/14] Switched to using await, ditched emitter --- package.json | 1 - src/App.vue | 55 ------------ .../funnel-header/funnel-header.vue | 26 +++++- src/helpers/event-bus/event-bus.js | 3 - src/layouts/vehicle-damage/vehicle-damage.vue | 85 ++++++++++--------- src/layouts/vehicle-make/vehicle-make.vue | 53 +++++++----- src/layouts/vehicle-model/vehicle-model.vue | 43 ++++++---- src/layouts/vehicle-style/vehicle-style.vue | 48 +++++++---- src/layouts/vehicle-year/vehicle-year.vue | 44 ++++++---- src/router/index.js | 17 +--- 10 files changed, 191 insertions(+), 184 deletions(-) delete mode 100644 src/helpers/event-bus/event-bus.js diff --git a/package.json b/package.json index 2c0d50df3..6033a0009 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "core-js": "^3.6.5", "http-status-codes": "^2.1.4", "jest-junit": "^13.0.0", - "mitt": "^3.0.0", "vue": "^3.0.0", "vue-plugin-load-script": "^2.1.0", "vue-router": "^4.0.11", diff --git a/src/App.vue b/src/App.vue index ec7cecf46..a44ab87b7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,58 +1,3 @@ - - diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index f2934cb37..a5313c91c 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -4,21 +4,41 @@ v-if="imageSrc" > Safelite logo + + diff --git a/src/helpers/event-bus/event-bus.js b/src/helpers/event-bus/event-bus.js deleted file mode 100644 index d92fdfd56..000000000 --- a/src/helpers/event-bus/event-bus.js +++ /dev/null @@ -1,3 +0,0 @@ -import mitt from 'mitt'; - -export const emitter = mitt(); \ No newline at end of file diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index abf24e998..edcfedaa3 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -1,12 +1,9 @@ diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index e641c4c73..c9b5afe81 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -4,12 +4,12 @@
-
@@ -35,11 +35,11 @@ export default { }, computed: {}, - beforeRouteEnter(to, from, next) { - + async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); - const makeQuestionInitialDataPromise = makeQuestion.methods.loadInitialData(); + const makeQuestionInitialDataPromise = + makeQuestion.methods.loadInitialData(); // Settle promises and get results const promiseResultMap = [ @@ -52,14 +52,24 @@ export default { promise: makeQuestionInitialDataPromise, }, ]; - settleAllPromises(promiseResultMap).then((resultMap) => { - // Call the "next" function to complete the transition to this page. - next((vm) => { - vm.$refs.funnelSubHeader.initializeComponent(resultMap.cmsContent.FunnelSubHeaderWidget); - vm.$refs.funnelHeader.initializeComponent(resultMap.cmsContent.FunnelHeaderWidget); - vm.$refs.vehicleBanner.initializeComponent(resultMap.cmsContent.VehicleBannerWidget); - vm.$refs.makeQuestion.initializeComponent(resultMap.cmsContent.VehicleMakeQuestion, resultMap.makeQuestionInitialData); - }); + + const resultMap = await settleAllPromises(promiseResultMap); + + // Call the "next" function to complete the transition to this page. + next((vm) => { + vm.$refs.funnelSubHeader.initializeComponent( + resultMap.cmsContent.FunnelSubHeaderWidget + ); + vm.$refs.funnelHeader.initializeComponent( + resultMap.cmsContent.FunnelHeaderWidget + ); + vm.$refs.vehicleBanner.initializeComponent( + resultMap.cmsContent.VehicleBannerWidget + ); + vm.$refs.makeQuestion.initializeComponent( + resultMap.cmsContent.VehicleMakeQuestion, + resultMap.makeQuestionInitialData + ); }); }, @@ -67,14 +77,17 @@ export default { backButtonAction() { // route to move backwards this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); - } + }, }, watch: { selectedMake(make) { this.$store.commit(this.storeMutations.UPDATE_MAKE, make); - this.$router.navigate(this.navigationScenarios.SELECTED_MAKE, this.$route); - } + this.$router.navigate( + this.navigationScenarios.SELECTED_MAKE, + this.$route + ); + }, }, components: { diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue index c682e9e24..92e979af4 100644 --- a/src/layouts/vehicle-model/vehicle-model.vue +++ b/src/layouts/vehicle-model/vehicle-model.vue @@ -4,7 +4,7 @@
- { - // Call the "next" function to complete the transition to this page. - next((vm) => { - vm.$refs.funnelSubHeader.initializeComponent(resultMap.cmsContent.FunnelSubHeaderWidget); - vm.$refs.funnelHeader.initializeComponent(resultMap.cmsContent.FunnelHeaderWidget); - vm.$refs.vehicleBanner.initializeComponent(resultMap.cmsContent.VehicleBannerWidget); - vm.$refs.modelQuestion.initializeComponent(resultMap.cmsContent.VehicleModelQuestion, resultMap.modelQuestionInitialData); - }); + + const resultMap = await settleAllPromises(promiseResultMap); + + // Call the "next" function to complete the transition to this page. + next((vm) => { + vm.$refs.funnelSubHeader.initializeComponent( + resultMap.cmsContent.FunnelSubHeaderWidget + ); + vm.$refs.funnelHeader.initializeComponent( + resultMap.cmsContent.FunnelHeaderWidget + ); + vm.$refs.vehicleBanner.initializeComponent( + resultMap.cmsContent.VehicleBannerWidget + ); + vm.$refs.modelQuestion.initializeComponent( + resultMap.cmsContent.VehicleModelQuestion, + resultMap.modelQuestionInitialData + ); }); }, @@ -67,14 +77,17 @@ export default { backButtonAction() { // route to move backwards this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); - } + }, }, watch: { selectedModel(model) { this.$store.commit(this.storeMutations.UPDATE_MODEL, model); - this.$router.navigate(this.navigationScenarios.SELECTED_MODEL, this.$route); - } + this.$router.navigate( + this.navigationScenarios.SELECTED_MODEL, + this.$route + ); + }, }, components: { diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index ff9fb86d3..3ae0a593b 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -4,7 +4,7 @@
- { - // Call the "next" function to complete the transition to this page. - next((vm) => { - vm.$refs.funnelSubHeader.initializeComponent(resultMap.cmsContent.FunnelSubHeaderWidget); - vm.$refs.funnelHeader.initializeComponent(resultMap.cmsContent.FunnelHeaderWidget); - vm.$refs.vehicleBanner.initializeComponent(resultMap.cmsContent.VehicleBannerWidget); - vm.$refs.styleQuestion.initializeComponent(resultMap.cmsContent.VehicleStyleQuestion, resultMap.styleQuestionInitialData); - }); + + const resultMap = await settleAllPromises(promiseResultMap); + + // Call the "next" function to complete the transition to this page. + next((vm) => { + vm.$refs.funnelSubHeader.initializeComponent( + resultMap.cmsContent.FunnelSubHeaderWidget + ); + vm.$refs.funnelHeader.initializeComponent( + resultMap.cmsContent.FunnelHeaderWidget + ); + vm.$refs.vehicleBanner.initializeComponent( + resultMap.cmsContent.VehicleBannerWidget + ); + vm.$refs.styleQuestion.initializeComponent( + resultMap.cmsContent.VehicleStyleQuestion, + resultMap.styleQuestionInitialData + ); }); }, @@ -69,16 +79,24 @@ export default { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, selectVehicle() { - this.dispatchNonBlockingStoreAction(this.storeActions.GET_VEHICLE, {year: this.$store.getters.vehicle.year, make: this.$store.getters.vehicle.make, model: this.$store.getters.vehicle.model, style: this.$store.getters.vehicle.style}); - } + this.dispatchNonBlockingStoreAction(this.storeActions.GET_VEHICLE, { + year: this.$store.getters.vehicle.year, + make: this.$store.getters.vehicle.make, + model: this.$store.getters.vehicle.model, + style: this.$store.getters.vehicle.style, + }); + }, }, watch: { selectedStyle(style) { this.$store.commit(this.storeMutations.UPDATE_STYLE, style); this.selectVehicle(); - this.$router.navigate(this.navigationScenarios.SELECTED_STYLE, this.$route); - } + this.$router.navigate( + this.navigationScenarios.SELECTED_STYLE, + this.$route + ); + }, }, components: { diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue index c5c85675e..bf19cb08d 100644 --- a/src/layouts/vehicle-year/vehicle-year.vue +++ b/src/layouts/vehicle-year/vehicle-year.vue @@ -4,10 +4,7 @@
- +
@@ -33,11 +30,11 @@ export default { }, computed: {}, - beforeRouteEnter(to, from, next) { - + async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); - const yearQuestionInitialDataPromise = yearQuestion.methods.loadInitialData(); + const yearQuestionInitialDataPromise = + yearQuestion.methods.loadInitialData(); // Settle promises and get results const promiseResultMap = [ @@ -50,22 +47,35 @@ export default { promise: yearQuestionInitialDataPromise, }, ]; - settleAllPromises(promiseResultMap).then((resultMap) => { - // Call the "next" function to complete the transition to this page. - next((vm) => { - vm.$refs.funnelSubHeader.initializeComponent(resultMap.cmsContent.FunnelSubHeaderWidget); - vm.$refs.funnelHeader.initializeComponent(resultMap.cmsContent.FunnelHeaderWidget); - vm.$refs.vehicleBanner.initializeComponent(resultMap.cmsContent.VehicleBannerWidget); - vm.$refs.yearQuestion.initializeComponent(resultMap.cmsContent.VehicleYearQuestion, resultMap.yearQuestionInitialData); - }); + + let resultMap = await settleAllPromises(promiseResultMap); + + // Call the "next" function to complete the transition to this page. + next((vm) => { + vm.$refs.funnelSubHeader.initializeComponent( + resultMap.cmsContent.FunnelSubHeaderWidget + ); + vm.$refs.funnelHeader.initializeComponent( + resultMap.cmsContent.FunnelHeaderWidget + ); + vm.$refs.vehicleBanner.initializeComponent( + resultMap.cmsContent.VehicleBannerWidget + ); + vm.$refs.yearQuestion.initializeComponent( + resultMap.cmsContent.VehicleYearQuestion, + resultMap.yearQuestionInitialData + ); }); }, watch: { selectedYear(year) { this.$store.commit(this.storeMutations.UPDATE_YEAR, year); - this.$router.navigate(this.navigationScenarios.SELECTED_YEAR, this.$route); - } + this.$router.navigate( + this.navigationScenarios.SELECTED_YEAR, + this.$route + ); + }, }, components: { diff --git a/src/router/index.js b/src/router/index.js index 0530fc50e..2ffec3359 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -38,10 +38,7 @@ const routes = [ // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { - return next({ - name: to.query.fmgPage, - query: to.query, - }); + return next({name: to.query.fmgPage,query: to.query}); } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. @@ -55,10 +52,7 @@ const routes = [ }); // Assign current query string parameters, as well as our fmgPage one. - next({ - name: routeData[0].name, - query: Object.assign(to.query, { fmgPage: routeData[0].name }), - }); + next({name: routeData[0].name, query: Object.assign(to.query, { fmgPage: routeData[0].name })}); }) .catch((error) => { // If we can't find the route, go to the last known page. @@ -158,13 +152,6 @@ function GetRouteInfoFromPageName(pageName) { // Go to our start page on a 404. function GoToFunnelStartOn404(next) { - - // Emit a global message - baseMixin.methods.emitGlobalMessage('We\'re sorry, something went wrong.', - 'You can get a quote by starting on this page.', - true, - globalEventTypes.Danger); - next({ path: '/', query: { fmgPage: FUNNEL_START_PAGE }, From 3df24f131cf64c685437fa909535bc3ae84c50b0 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Fri, 14 Jan 2022 16:36:30 -0500 Subject: [PATCH 04/14] Cleanup, switched router over to use aysnc/await --- src/layouts/vehicle-style/vehicle-style.vue | 2 +- src/mixins/base-mixin.js | 12 ---- src/router/index.js | 71 ++++++++------------- 3 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index 3ae0a593b..13ad52a7c 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -35,7 +35,7 @@ export default { }, computed: {}, - beforeRouteEnter(to, from, next) { + async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const styleQuestionInitialDataPromise = diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 4d3363a84..c283894c2 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -3,8 +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 { widgetNames } from "@/constants/widget-names.js"; -import { emitter } from "@/helpers/event-bus/event-bus"; -import { globalEvents } from "@/constants/events"; export default { data() { @@ -21,16 +19,6 @@ export default { return store.dispatch(type, payload); }, - emitGlobalMessage(headline, copy, isDismissible, type) { - emitter.emit(globalEvents.GLOBAL_ALERT, { - globalAlertMessage: { - messageHeadline: headline, - messageCopy: copy, - isDismissible: isDismissible, - type: type - } - }); - } }, computed: { storeActions() { diff --git a/src/router/index.js b/src/router/index.js index 2ffec3359..ce7b76bcd 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,11 +1,8 @@ // Supporting files import { createWebHistory, createRouter } from "vue-router"; import { storeActions } from "@/constants/store-actions"; -import { storeMutations } from "@/constants/store-mutations"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; -import { globalEventTypes } from "@/constants/events"; -import baseMixin from "@/mixins/base-mixin"; import store from "@/store"; // Components @@ -14,10 +11,6 @@ import AddressPOC from "@/layouts/address-poc/address-poc.vue"; const FUNNEL_START_PAGE = 'vehicle-year'; const routes = [ - { - path: "/:pathMatch(.*)*", - name: "NotFound", - }, { path: "/component-test", // This is a temporary route for testing. name: "ComponentTest", @@ -30,7 +23,7 @@ const routes = [ }, { path: "/", - beforeEnter(to, from, next) { + async beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { GoToFunnelStartOn404(next); @@ -38,28 +31,21 @@ const routes = [ // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { - return next({name: to.query.fmgPage,query: to.query}); + return next({ name: to.query.fmgPage, query: to.query }); } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. - GetRouteInfoFromPageName(to.query.fmgPage) - .then((routeData) => { - // Add our dynamic route. - router.addRoute({ - path: routeData[0].path, // Always the same path, because we control it with query strings. - name: routeData[0].name, - component: routeData[0].component, - }); + const routeData = await GetRouteInfoFromPageName(to.query.fmgPage); - // Assign current query string parameters, as well as our fmgPage one. - next({name: routeData[0].name, query: Object.assign(to.query, { fmgPage: routeData[0].name })}); - }) - .catch((error) => { - // If we can't find the route, go to the last known page. - GoToFunnelStartOn404(next); + // Add our dynamic route. + router.addRoute({ + path: routeData[0].path, // Always the same path, because we control it with query strings. + name: routeData[0].name, + component: routeData[0].component, + }); - console.log("Cannot find route, navigating to last page:", error); - }); + // Assign current query string parameters, as well as our fmgPage one. + next({ name: routeData[0].name, query: Object.assign(to.query, { fmgPage: routeData[0].name }) }); } }, }, @@ -101,7 +87,7 @@ router.navigate = ( } }; -// Get navigation map depeding on the scenario and the current 'page' you're on. +// Get navigation map depending on the scenario and the current 'page' you're on. router.getNavigationMap = (scenario, currentRoute) => { const fmgPageValue = currentRoute.query.fmgPage; const matchedQueryValue = routingTable @@ -125,29 +111,22 @@ function navigateToUrl(url) { // Get route information by page name. // This will reach out to the Cms and there is a 1:1 relationship between page names and route names. -function GetRouteInfoFromPageName(pageName) { - return new Promise((resolve, reject) => { - store - .dispatch(storeActions.GET_ROUTE_INFO_ACTION, { pageName: pageName }) - .then((response) => { - // Add our route data and return our array. - let jsonFromResponse = JSON.parse(response.data.Result); - let routeData = []; +async function GetRouteInfoFromPageName(pageName) { + const response = await store.dispatch(storeActions.GET_ROUTE_INFO_ACTION, { pageName: pageName }); - Object.keys(jsonFromResponse).forEach((key) => { - routeData.push({ - path: "/", - name: `${key}`, - component: lazyLoadComponent(jsonFromResponse[key].LayoutName), - }); - }); + // Add our route data and return our array. + const jsonFromResponse = JSON.parse(response.data.Result); + let routeData = []; - resolve(routeData); - }) - .catch((error) => { - reject(error); - }); + Object.keys(jsonFromResponse).forEach((key) => { + routeData.push({ + path: "/", + name: `${key}`, + component: lazyLoadComponent(jsonFromResponse[key].LayoutName), + }); }); + + return routeData; } // Go to our start page on a 404. From 7abbf7c3cb0da38269aea4cf21172cba71982802 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Fri, 14 Jan 2022 16:40:08 -0500 Subject: [PATCH 05/14] Comments --- src/router/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index ce7b76bcd..6b4e703fc 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -113,11 +113,10 @@ function navigateToUrl(url) { // This will reach out to the Cms and there is a 1:1 relationship between page names and route names. async function GetRouteInfoFromPageName(pageName) { const response = await store.dispatch(storeActions.GET_ROUTE_INFO_ACTION, { pageName: pageName }); - - // Add our route data and return our array. const jsonFromResponse = JSON.parse(response.data.Result); let routeData = []; + // Add our route data and return our array. Object.keys(jsonFromResponse).forEach((key) => { routeData.push({ path: "/", From ab947a4d1516725bce076955dfe201f1bf26e55d Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 17 Jan 2022 16:53:10 -0500 Subject: [PATCH 06/14] Created event bus, created homepage endpoint --- .../funnel-header/funnel-header.vue | 26 +++++--- src/constants/endpoints.js | 4 ++ src/constants/events.js | 7 +- src/constants/store-actions.js | 1 + src/helpers/event-bus/event-bus.js | 40 ++++++++++++ src/layouts/vehicle-year/vehicle-year.vue | 4 +- src/mixins/base-mixin.js | 1 - src/router/index.js | 64 +++++++++++++------ src/store/index.js | 10 ++- 9 files changed, 124 insertions(+), 33 deletions(-) create mode 100644 src/helpers/event-bus/event-bus.js diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index a5313c91c..13cebd61b 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -4,19 +4,21 @@ v-if="imageSrc" > Safelite logo - - + />
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index ae0755963..590cf1080 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -11,6 +11,9 @@ const storeActions = { GET_EVOX_IMAGE: "getEvoxImage", LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms", LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin", + // EVENT BUS + ADD_EVENT_TO_BUS: "addEventToBus", + REMOVE_EVENT_FROM_BUS: "removeEventFromBus", }; export { storeActions }; diff --git a/src/helpers/event-bus/event-bus.js b/src/helpers/event-bus/event-bus.js index 6ca248d19..8ac156776 100644 --- a/src/helpers/event-bus/event-bus.js +++ b/src/helpers/event-bus/event-bus.js @@ -1,42 +1,25 @@ import store from "@/store"; +import { storeActions } from "@/constants/store-actions.js"; export default { - // Adds event to the bus given its category, subcategory, and eventValue; addEventToBus(category, subCategory, eventValue) { - store.state.applicationUser.eventBus.push({ - category: category, - subCategory: subCategory, - eventValue: eventValue, - }); + store.commit(storeActions.ADD_EVENT_TO_BUS, { category: category, subCategory: subCategory, eventValue: eventValue }); }, // Finds event on the bus, removes the item, and returns its value to the caller. readAndPopEventFromBus(category, subCategory) { - // Match our item and find the index - const matchedEvent = store.state.applicationUser.eventBus.find(({ category, subCategory }) => category === category && subCategory === subCategory); + const event = store.getters.eventBusItem(category, subCategory); - const itemIndex = store.state.applicationUser.eventBus.indexOf(matchedEvent); + store.commit(storeActions.REMOVE_EVENT_FROM_BUS, { category: category, subCategory: subCategory }); - // If the item exists, remove it. - if (itemIndex > -1) { - store.state.applicationUser.eventBus.splice(itemIndex, 1); - } - - return matchedEvent === undefined ? undefined : matchedEvent.eventValue; + return event; }, // Finds the event on the bus and returns its value to the caller, does not remove it. readEventFromBus(category, subCategory) { - const matchedEvent = store.state.applicationUser.eventBus.find(({ category, subCategory }) => category === category && subCategory === subCategory); - - return matchedEvent === undefined ? undefined : matchedEvent.eventValue; + const event = store.getters.eventBusItem(category, subCategory); + + return event; }, - - // Checks if an item is on the bus or not, useful when you don't care about the value. - isItemOnBus(category, subCategory) { - const matchedEvent = store.state.applicationUser.eventBus.find(({ category, subCategory }) => category === category && subCategory === subCategory); - - return matchedEvent !== undefined; - } } \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index cb2e4a3dc..818fd3bd5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -76,13 +76,27 @@ export default createStore({ state.order.vehicle.carId = data.carId; state.order.vehicle.category = data.category; }, - updateLastPage(state, page) { - state.applicationUser.navigation.lastPage = page; + addEventToBus(state, event) { + state.applicationUser.eventBus.push(event); + }, + removeEventFromBus(state, eventData) { + const matchedEvent = state.applicationUser.eventBus.find(({ category, subCategory }) => category === eventData.category && subCategory === eventData.subCategory); + const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); + + // If the item exists, remove it. + if (itemIndex > -1) { + state.applicationUser.eventBus.splice(itemIndex, 1); + } } }, getters: { vehicle: state => state.order.vehicle, - eventBus: state => state.applicationUser.eventBus, + eventBusItem: (state) => (eventCategory, eventSubCategory) => { + const matchedEvent = state.applicationUser.eventBus.find(({ category, subCategory }) => category === eventCategory && subCategory === eventSubCategory); + + return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; + }, + eventBus: state => state.applicationUser.eventBus }, actions: { // Vehicle API Actions From 48171bb8c0ca62202f022f9c52e0ab2977c6640f Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 18 Jan 2022 16:33:39 -0500 Subject: [PATCH 10/14] unneeded import --- src/common-components/funnel-header/funnel-header.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index 7b46f226a..7d5be69b0 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -10,7 +10,6 @@ import alert from "@/ux-components/alert/alert"; import eventBus from "@/helpers/event-bus/event-bus"; import { globalEvents, - globalEventTypes } from "@/constants/events"; export default { From a0b5d1ff61628122e6e7434a47b71174903dc254 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 19 Jan 2022 13:48:55 -0500 Subject: [PATCH 11/14] Added dynamic calc for height --- .../button-question/button-question.vue | 9 +++++++-- src/common-components/funnel-header/funnel-header.vue | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index 849f5a353..3d2f75893 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -47,6 +47,13 @@ export default { components: { listButton, }, + updated() { + + // Dynamically account for the header height. + var element = document.getElementsByClassName('overflow-scroll')[0]; + + element.style.height = 'calc(100% - ' + element.offsetTop + 'px)'; + } }; @@ -55,8 +62,6 @@ export default { height: calc(100vh - 280px); .overflow-scroll { - // Height will be determined by overall height of content above list - height: calc(100% - 320px); -webkit-overflow-scrolling: touch; } } diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index 7d5be69b0..0a3fd5219 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -1,5 +1,5 @@