From f6ca73d2c076c37fa1bf0dd8b18290eae00493d2 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 12 Jul 2022 15:22:24 -0400 Subject: [PATCH 01/44] change event constant to match gtm trigger --- src/constants/analytics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/analytics.js b/src/constants/analytics.js index a3f057150..d4ac3d2ea 100644 --- a/src/constants/analytics.js +++ b/src/constants/analytics.js @@ -5,7 +5,7 @@ const analyticsPageEvents = { // GA Constants const GaEvents = { - GENERIC_EVENT: 'ga_Event', + GENERIC_EVENT: 'event', PAGE_VIEW_EVENT : 'logPageview' }; From 453d086a1dffd0f983bb56d3dcf4c7c797d08563 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 15 Jul 2022 12:14:39 -0400 Subject: [PATCH 02/44] CSR-666 Add experiment-mixin --- src/mixins/experiment-mixin.js | 13 +++++++++++++ src/mixins/experiment-mixin.spec.js | 0 2 files changed, 13 insertions(+) create mode 100644 src/mixins/experiment-mixin.js create mode 100644 src/mixins/experiment-mixin.spec.js diff --git a/src/mixins/experiment-mixin.js b/src/mixins/experiment-mixin.js new file mode 100644 index 000000000..de6edd79c --- /dev/null +++ b/src/mixins/experiment-mixin.js @@ -0,0 +1,13 @@ +export default { + methods: { + hasSettingEqualTo(settingName, settingValue) { + + }, + hasSetting(settingName) { + + }, + getSettingValue(settingName) { + + } + }, +} \ No newline at end of file diff --git a/src/mixins/experiment-mixin.spec.js b/src/mixins/experiment-mixin.spec.js new file mode 100644 index 000000000..e69de29bb From 3f29cc1a89627eae895aeb991134764f640a85ea Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 15 Jul 2022 12:52:44 -0400 Subject: [PATCH 03/44] CSR-734 Fix validation rule --- .../windshield-damage-type-question.vue | 1 - .../windshield-options/windshield-options.vue | 2 +- src/ux-components/list-card/list-card.vue | 10 +++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue b/src/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue index ce162617d..e76536103 100644 --- a/src/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue +++ b/src/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue @@ -17,7 +17,6 @@ From cefd25399e9fe635e4fdfbfcc6b8eb4ac5adca36 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 19 Jul 2022 15:20:02 -0400 Subject: [PATCH 10/44] CSR-530 Add routing for experiment-integration --- src/layouts/test-one.vue | 15 + src/layouts/test-two.vue | 15 + src/router/index.js | 25 +- src/router/router-constants/routing-table.js | 480 ++++++++++--------- 4 files changed, 300 insertions(+), 235 deletions(-) create mode 100644 src/layouts/test-one.vue create mode 100644 src/layouts/test-two.vue diff --git a/src/layouts/test-one.vue b/src/layouts/test-one.vue new file mode 100644 index 000000000..5ba269f2a --- /dev/null +++ b/src/layouts/test-one.vue @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/src/layouts/test-two.vue b/src/layouts/test-two.vue new file mode 100644 index 000000000..2ea5fd624 --- /dev/null +++ b/src/layouts/test-two.vue @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index b09f734a2..f01fb4ff6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -19,7 +19,24 @@ import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; import analyticsMixin from "@/mixins/analytics-mixin"; +import TestOne from "@/layouts/test-one"; +import TestTwo from "@/layouts/test-two"; + const routes = [ + { + path: "/test1", + name: "test1", + components: { + default: TestOne + } + }, + { + path: "/test2", + name: "test2", + components: { + default: TestTwo + } + }, { path: "/", name: "root", @@ -53,7 +70,6 @@ const routes = [ return next(false); } - // Assign our fmgPage so it will load normally like the other pages. to.query.fmgPage = pageToRedirectTo; } @@ -180,15 +196,16 @@ async function navigate(scenario, currentRoute, optionalQuery = {}, optionalPara // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap(scenario, currentRoute) { const fmgPageValue = currentRoute.query.fmgPage; - const matchedQueryValue = routingTable + let matchedQueryValue = routingTable(store) .filter( (item) => item.fmgPageValue === fmgPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0 ) - .map((m) => m.maps.filter((map) => map.scenario === scenario)); + .map((m) => m.maps.filter((map) => map.scenario === scenario))[0] + .filter(x => x.filter === true || x.filter === undefined); - return matchedQueryValue[0][0]; + return matchedQueryValue[0]; } //---------------------------------------------------------- Private Functions ---------------------------------------------------------- diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3f81e99ad..5d89daab9 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -1,236 +1,254 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; -const routingTable = [ - { - fmgPageValue: fmgPageValues.VEHICLE_YEAR, - maps: [ - { - scenario: navigationScenarios.SELECTED_YEAR, - destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VEHICLE_MAKE, - maps: [ - { - scenario: navigationScenarios.SELECTED_MAKE, - destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL, - }, - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_YEAR, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VEHICLE_MODEL, - maps: [ - { - scenario: navigationScenarios.SELECTED_MODEL, - destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, - }, - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VEHICLE_STYLE, - maps: [ - { - scenario: navigationScenarios.SELECTED_STYLE, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, - destinationFmgPageValue: fmgPageValues.ESTIMATE, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VEHICLE_PARTS, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, - { - scenario: navigationScenarios.SELECTED_PARTS, - destinationFmgPageValue: fmgPageValues.QUOTE, - }, - { - scenario: navigationScenarios.CLICKED_FORWARD, - destinationFmgPageValue: fmgPageValues.REVEAL, - }, - ], - }, - { - fmgPageValue: fmgPageValues.REVEAL, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_PARTS, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, - ], - }, - { - fmgPageValue: fmgPageValues.VIN_LOOKUP, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.ESTIMATE, - }, - { - scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.CLICKED_BACK_WITH_VIN, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS - } - ], - }, - { - fmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.ESTIMATE, - }, - { - scenario: navigationScenarios.CLICKED_FORWARD, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS - } - ], - }, - { - fmgPageValue: fmgPageValues.ADDRESS_LOOKUP, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.ESTIMATE, - }, - { - scenario: navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, - destinationFmgPageValue: fmgPageValues.ADDRESS_VEHICLES, - }, - { - scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS - } - ], - }, - { - fmgPageValue: fmgPageValues.ADDRESS_VEHICLES, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, - }, - { - scenario: navigationScenarios.CLICKED_FORWARD, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS - }, - { - scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS - }, - { - scenario: navigationScenarios.SELECTED_PROVIDE_VIN_DIFFERENT_WAY, - destinationFmgPageValue: fmgPageValues.ESTIMATE - } - ], - }, - { - fmgPageValue: fmgPageValues.ESTIMATE, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, - }, - { - scenario: navigationScenarios.SELECTED_MANUAL_VIN, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, - { - scenario: navigationScenarios.SELECTED_LICENSE_PLATE, - destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, - }, - { - scenario: navigationScenarios.SELECTED_HOME_ADDRESS, - destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, - }, - ], - }, - { - fmgPageValue: fmgPageValues.PART_QUESTIONS, - maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP - }, - { - scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS - }, - { - scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, - destinationFmgPageValue: fmgPageValues.QUOTE, - }, - ] - }, -]; +// Get store from router/index.js instead of importing it here to get updated values +const routingTable = function(store) { + return [ + { + fmgPageValue: fmgPageValues.VEHICLE_YEAR, + maps: [ + { + scenario: navigationScenarios.SELECTED_YEAR, + destinationFmgPageValue: "test1", + filter: store.getters.vehicle.year > 2010 + }, + { + scenario: navigationScenarios.SELECTED_YEAR, + destinationFmgPageValue: "test2", + filter: store.getters.vehicle.year <= 2010 + }, + { + scenario: navigationScenarios.SELECTED_YEAR, + destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, + }, + + { + scenario: navigationScenarios.SELECTED_YEAR, + destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VEHICLE_MAKE, + maps: [ + { + scenario: navigationScenarios.SELECTED_MAKE, + destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL, + }, + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_YEAR, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VEHICLE_MODEL, + maps: [ + { + scenario: navigationScenarios.SELECTED_MODEL, + destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, + }, + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VEHICLE_STYLE, + maps: [ + { + scenario: navigationScenarios.SELECTED_STYLE, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, + destinationFmgPageValue: fmgPageValues.ESTIMATE, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VEHICLE_PARTS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.SELECTED_PARTS, + destinationFmgPageValue: fmgPageValues.QUOTE, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationFmgPageValue: fmgPageValues.REVEAL, + }, + ], + }, + { + fmgPageValue: fmgPageValues.REVEAL, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_PARTS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + ], + }, + { + fmgPageValue: fmgPageValues.VIN_LOOKUP, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + } + ], + }, + { + fmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + } + ], + }, + { + fmgPageValue: fmgPageValues.ADDRESS_LOOKUP, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, + destinationFmgPageValue: fmgPageValues.ADDRESS_VEHICLES, + }, + { + scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + } + ], + }, + { + fmgPageValue: fmgPageValues.ADDRESS_VEHICLES, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_PROVIDE_VIN_DIFFERENT_WAY, + destinationFmgPageValue: fmgPageValues.ESTIMATE + } + ], + }, + { + fmgPageValue: fmgPageValues.ESTIMATE, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_MANUAL_VIN, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.SELECTED_LICENSE_PLATE, + destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, + }, + { + scenario: navigationScenarios.SELECTED_HOME_ADDRESS, + destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, + }, + ], + }, + { + fmgPageValue: fmgPageValues.PART_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP + }, + { + scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, + destinationFmgPageValue: fmgPageValues.QUOTE, + }, + ] + }, + ]; +} export { routingTable }; From f9fa9d154f1d4e828ded9964f10995f3b6080a09 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 19 Jul 2022 15:44:14 -0400 Subject: [PATCH 11/44] CSR-530 Add test cases in --- src/router/router-constants/routing-table.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 5d89daab9..25463bd8b 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -10,22 +10,17 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_YEAR, destinationFmgPageValue: "test1", - filter: store.getters.vehicle.year > 2010 + filter: store.getters.vehicle.year === 2010 }, { scenario: navigationScenarios.SELECTED_YEAR, destinationFmgPageValue: "test2", - filter: store.getters.vehicle.year <= 2010 + filter: store.getters.vehicle.year < 1954 }, { scenario: navigationScenarios.SELECTED_YEAR, destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, }, - - { - scenario: navigationScenarios.SELECTED_YEAR, - destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE, - }, ], }, { From f3120ef80dde21ad766d67d20f1708dd5426c199 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 19 Jul 2022 15:46:48 -0400 Subject: [PATCH 12/44] CSR-530 Cleanup --- src/router/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/index.js b/src/router/index.js index f01fb4ff6..d2a5ee154 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -196,7 +196,7 @@ async function navigate(scenario, currentRoute, optionalQuery = {}, optionalPara // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap(scenario, currentRoute) { const fmgPageValue = currentRoute.query.fmgPage; - let matchedQueryValue = routingTable(store) + const matchedQueryValue = routingTable(store) .filter( (item) => item.fmgPageValue === fmgPageValue && From c7b775863bc6a0907bd897faca299981dd31ebee Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 20 Jul 2022 09:27:55 -0400 Subject: [PATCH 13/44] CSR-110: navigation/store changes for molding-questions page --- jest.config.js | 1 + .../license-plate-lookup.spec.js | 6 +- .../molding-questions/molding-questions.vue | 288 ++++++++++++++ src/layouts/part-questions/part-questions.vue | 27 +- src/layouts/vehicle-parts/vehicle-parts.vue | 355 +++++++++--------- src/mixins/vin-pages-mixin.js | 9 +- src/router/router-constants/fmgPage-values.js | 1 + .../router-constants/navigation-scenarios.js | 2 + src/router/router-constants/routing-table.js | 29 +- 9 files changed, 523 insertions(+), 195 deletions(-) create mode 100644 src/layouts/molding-questions/molding-questions.vue diff --git a/jest.config.js b/jest.config.js index 0a063507d..f4c60e4f7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,6 +12,7 @@ module.exports = { "!src/router/**/*.js", "!src/helpers/unit-test-helper.js", "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", + "!src/layouts/molding-questions/**/*.vue", "!src/layouts/part-questions/**/*.vue", "!src/layouts/reveal/**/*.vue", "!src/ux-components/text-link/**/*.vue", diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 2e83c3103..7bfc02eba 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -235,7 +235,7 @@ describe("license-plate-lookup.vue", () => { expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); }); - test("navigateToHeritageFunnel should be called if isCarIdDifferent is false or isSelectedGlassAvailableForVehicle is true when navigateForward is called", async () => { + test("navigateForwardWithSingleCarMatch should be called if isCarIdDifferent is false or isSelectedGlassAvailableForVehicle is true when navigateForward is called", async () => { // Arrange const { wrapper } = setupMocks({}); @@ -247,11 +247,11 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { return ''; }); - navigateToHeritage.navigateToHeritageFunnel = jest.fn(); + wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); await wrapper.vm.navigateForward(); //Assert - expect(navigateToHeritage.navigateToHeritageFunnel).toHaveBeenCalled(); + expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalled(); }); test("carId matches returned vehicle => navigateForwardWithSingleCarMatch", async () => { diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue new file mode 100644 index 000000000..04259a3c3 --- /dev/null +++ b/src/layouts/molding-questions/molding-questions.vue @@ -0,0 +1,288 @@ + + + + + diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index f5ec4841d..856b8a099 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -142,14 +142,14 @@ export default { if (!partsLookup) { return } - const glassNameAndParts = partsLookup.data.glassNameAndParts; + const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; // test response data for multiple parts - const hasMultipleParts = glassNameAndParts.some((glass) => glass.parts?.length > 1); + const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); // loop through all glass items const collectedGlassParts = []; - glassNameAndParts.forEach((glass) => { + glassNameAndPartsForStore.forEach((glass) => { if (Array.isArray(glass.parts) && glass.parts.length === 1) { const singlePart = glass.parts[0]; collectedGlassParts.push({ @@ -159,24 +159,37 @@ export default { "requiresRecalibration": singlePart.requiresRecalibration, "childParts": singlePart.childParts, "price": singlePart.price, - }) + }); + // check for and collect any molding questions + if (Array.isArray(singlePart.childPartQuestions) && singlePart.childPartQuestions.length > 0) { + this.moldingQuestionsForStore.push({ + "glassName": glass.glassName, + "glassLocation": glass.glassLocation, + "childPartQuestions": singlePart.childPartQuestions, + }); + } } }); if (!hasMultipleParts) { store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); } - this.navigateForward(hasMultipleParts, glassNameAndParts); + this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); }, - async navigateForward(hasMultipleParts, glassNameAndParts) { + async navigateForward(hasMultipleParts, glassNameAndPartsForStore) { if (hasMultipleParts) { // if multiple parts on any glass // go to vehicle-parts page and pass the partsData - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndParts}); + this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); } else { // if single parts only // go to quote page this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); } + + // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS + + + }, arePagePrerequisitesValid() { return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length > 0; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index ce5727ce3..d0af557b0 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -49,217 +49,208 @@ diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index fce96c980..196a21e63 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -7,10 +7,14 @@ export default { methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); - const partsOrQuestions = result.data.partsOrQuestions; const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); + const hasChildPartQuestions = partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.childPartQuestions?.length > 0); + }); + + // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS if (hasPartsQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data); @@ -18,6 +22,9 @@ export default { else if (hasGlassLocationWithMultipleParts) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, this.$route, {}, {}, result.data); } + else if (hasChildPartQuestions) { + this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, this.$route, {}, {}, result.data); + } else { store.commit(storeMutations.UPDATE_GLASS_PARTS, result.data); this.$refs.loadingModal.showModal(); diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index d067895ee..7a38c6b40 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -8,6 +8,7 @@ const fmgPageValues = { VIN_LOOKUP: "vin-lookup", VEHICLE_PARTS: "vehicle-parts", PART_QUESTIONS: "part-questions", + MOLDING_QUESTIONS: "molding-questions", LICENSE_PLATE_LOOKUP: "license-plate-lookup", REVEAL: "reveal", ESTIMATE: "estimate", diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5768c55de..ab1772de3 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -10,6 +10,7 @@ const navigationScenarios = { SELECTED_PARTS: "SELECTED_PARTS", SELECTED_VIN_WITH_PART_QUESTIONS: "SELECTED_VIN_WITH_PART_QUESTIONS", SELECTED_VIN_WITH_MULTIPLE_PARTS: "SELECTED_VIN_WITH_MULTIPLE_PARTS", + SELECTED_VIN_WITH_MOLDING_QUESTIONS: "SELECTED_VIN_WITH_MOLDING_QUESTIONS", CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART", CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES", SELECTED_VIN_HAS_MISMATCHED_GLASS: "SELECTED_VIN_HAS_MISMATCHED_GLASS", @@ -19,6 +20,7 @@ const navigationScenarios = { SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", + HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS", SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3f81e99ad..82bb59ff6 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -79,8 +79,8 @@ const routingTable = [ destinationFmgPageValue: fmgPageValues.QUOTE, }, { - scenario: navigationScenarios.CLICKED_FORWARD, - destinationFmgPageValue: fmgPageValues.REVEAL, + scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS }, ], }, @@ -119,6 +119,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -140,6 +144,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -165,6 +173,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -225,12 +237,25 @@ const routingTable = [ scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS }, + { + scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + }, { scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, destinationFmgPageValue: fmgPageValues.QUOTE, }, ] }, + { + fmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + ] + }, ]; export { routingTable }; From b21c6171e9d4574f4597a1d9e773074357e9b055 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Mon, 25 Jul 2022 09:30:00 -0400 Subject: [PATCH 14/44] CSR-706 | Remove state resetting on loadOrder As well as making loadOrder await the latest saveOrderPromise Also clearing saveOrderPromise if entering the funnel fresh to avoid a broken promise object --- src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 1 + src/helpers/heritage-integration/order-helper.js | 2 ++ src/router/index.js | 3 +++ src/store/index.js | 8 ++++++-- 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 87331daea..6fa81d45f 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -31,6 +31,7 @@ const storeActions = { INITIALIZE_SESSION: "initializeSession", GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser", CLEAR_VIN: "clearVin", + RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise", // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleAndDependencies", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 80697cc46..66b9ded0e 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -58,6 +58,7 @@ const storeMutations = { UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation", UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise", UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited", + RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise", }; export { storeMutations }; diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index 9722744f0..2e6fcade0 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -60,6 +60,8 @@ export async function saveOrder() { and returns the response. */ async function loadOrder(referralNumber, referralDate, referralCorrelationId, accountNumber) { + // await the saveOrderPromise in the store to make sure we're loading up to date information + await store.getters.applicationUser.saveOrderPromise; const response = await baseMixin.methods.dispatchStoreAction(storeActions.LOAD_ORDER, { referralNumber: referralNumber.toString(), diff --git a/src/router/index.js b/src/router/index.js index d2a5ee154..98b26483b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -60,6 +60,9 @@ const routes = [ // On entering the funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { + // clear the saveOrderPromise - if it exists in the vuex store but a new instance was created + // the saveOrderPromise will no longer point to a valid promise + baseMixin.methods.dispatchStoreAction(storeActions.RESET_SAVE_ORDER_PROMISE); const loadOrderResponse = await loadOrderIfPresent(); const pageToRedirectTo = await getPageToRouteExistingOrderTo(to, loadOrderResponse); diff --git a/src/store/index.js b/src/store/index.js index 90932c8bb..82d3323d1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -269,7 +269,9 @@ export const mutations = { resetState(state) { Object.assign(state, getDefaultState()); }, - + resetSaveOrderPromise(state) { + state.applicationUser.saveOrderPromise = null; + }, // Misc Mutations updateStateWithOrderInformation(state, orderInformation) { state.order.referralNumber = orderInformation.referralNumber; @@ -457,6 +459,9 @@ export const actions = { resetState(context) { context.commit(storeMutations.RESET_STATE); }, + resetSaveOrderPromise(context) { + context.commit(storeMutations.RESET_SAVE_ORDER_PROMISE); + }, // Content API Actions getRouteInfo(context, { pageName }) { @@ -701,7 +706,6 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { - context.commit(storeMutations.RESET_STATE); context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); return response; }); From 62b72163d6127a8a09989bc4182e2ce221893b6f Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Mon, 25 Jul 2022 15:29:44 -0400 Subject: [PATCH 15/44] CSR-706 | Only clear state if referral does not match --- src/store/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/store/index.js b/src/store/index.js index 82d3323d1..64ba356e6 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -706,6 +706,10 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { + // clear the state if the existing referral number does not equal what is returned from loadOrder + if (context.state.order.referralNumber != response.data.referralNumber) { + context.commit(storeMutations.RESET_STATE); + } context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); return response; }); From e31f415aa4cb5fe06c89ec7579d1d956a1a0943b Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Jul 2022 10:38:10 -0400 Subject: [PATCH 16/44] CSR-110: refactoring per PR review --- src/layouts/molding-questions/molding-questions.vue | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 04259a3c3..0ffaae411 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -141,11 +141,9 @@ export default { // call API parts method const partsLookup = await this.dispatchStoreAction(storeActions.GET_PARTS) .catch(() => { - this.$refs.funnelFooter.removeLoader(); + return this.$refs.funnelFooter.removeLoader(); }); - if (!partsLookup) { return } - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; console.log("glassNameAndPartsForStore: ", glassNameAndPartsForStore); @@ -236,11 +234,11 @@ export default { } }); if (!hasMultipleParts) { - store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); } this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); }, - async navigateForward(hasMultipleParts, glassNameAndPartsForStore) { + navigateForward(hasMultipleParts, glassNameAndPartsForStore) { if (hasMultipleParts) { // if multiple parts on any glass // go to vehicle-parts page and pass the partsData From bb1fa9aede61cd8b894aad40369e468ace6e05af Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 26 Jul 2022 12:02:03 -0400 Subject: [PATCH 17/44] CSR-706 | Refactoring to use SavedSession instead of SaveQuote --- src/helpers/heritage-integration/navigation-helper.spec.js | 2 +- src/store/store.spec.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index 1b33c0a6f..7337bf98e 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -309,7 +309,7 @@ describe("navigateToHeritageFunnel", () => { const mockCorrelationId = "55"; const mockReferralDate = "2022"; const mockAccountNumber = "167132"; - const mockSaveQuoteId = "xxx-xxx-xxx"; + const mockavedSessionId = "xxx-xxx-xxx"; const mockCrmCustomerId = "xxx-xxx-xxx" const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSaveQuoteId, mockCrmCustomerId); diff --git a/src/store/store.spec.js b/src/store/store.spec.js index a9e37dea7..29f8a88ed 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -574,7 +574,7 @@ describe("Actions", () => { applicationUser: { lastPageVisited: "test-page", crmCustomerId: "xxx-xxx-xxx", - saveQuoteId: "xxx-xxx-xxx" + savedSessionId: "xxx-xxx-xxx" } }; context.state = { @@ -630,7 +630,7 @@ describe("Actions", () => { referralDate: new Date().toUTCString(), referralCorrelationId: "xxx-xxx-xxx", accountNumber: "167132", - saveQuoteId: "xxx-xxx-xxx", + savedSessionId: "xxx-xxx-xxx", crmCustomerId: "xxx-xxx-xxx", }); @@ -639,7 +639,7 @@ describe("Actions", () => { expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_DATE, new Date().toUTCString()); expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, "xxx-xxx-xxx"); expect(commit).toBeCalledWith(storeMutations.UPDATE_PARENT_ACCT_NUMBER, "167132"); - expect(commit).toBeCalledWith(storeMutations.UPDATE_SAVE_QUOTE_ID, "xxx-xxx-xxx"); + expect(commit).toBeCalledWith(storeMutations.UPDATE_SAVED_SESSION_ID, "xxx-xxx-xxx"); expect(commit).toBeCalledWith(storeMutations.UPDATE_CRM_CUSTOMER_ID, "xxx-xxx-xxx"); }); From c18af60165c0ef85c396287c57c7dc942e085f39 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 26 Jul 2022 12:07:03 -0400 Subject: [PATCH 18/44] CSR-706 | Refactoring savedQuote -> SavedSession --- src/constants/store-mutations.js | 2 +- src/helpers/heritage-integration/cookie-helper.js | 2 +- .../heritage-integration/navigation-helper.spec.js | 8 ++++---- src/helpers/heritage-integration/order-helper.js | 2 +- .../heritage-integration/order-helper.spec.js | 10 +++++----- src/helpers/heritage-integration/session-helper.js | 2 +- .../heritage-integration/session-helper.spec.js | 4 ++-- src/helpers/unit-test-helper.js | 4 ++-- src/store/index.js | 12 ++++++------ 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 66b9ded0e..508f59bf7 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -39,7 +39,7 @@ const storeMutations = { UPDATE_REFERRAL_DATE: "updateReferralDate", UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId", UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber", - UPDATE_SAVE_QUOTE_ID: "updateSaveQuoteId", + UPDATE_SAVED_SESSION_ID: "updateSavedSessionId", UPDATE_CRM_CUSTOMER_ID: "updateCrmCustomerId", // EVENT BUS MUTATIONS diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 3a8614661..775a64fec 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -15,7 +15,7 @@ export function updateOrCreateFunnelCookie() { // Set up cookie with all the props. setFunnelCookieProperties({ LastTouched: new Date().toUTCString(), - SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, + SavedSessionTimeoutDate: store.getters.applicationUser.savedSessionTimeout, DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.getters.order.referralNumber, diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index 7337bf98e..0e615aef5 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -309,10 +309,10 @@ describe("navigateToHeritageFunnel", () => { const mockCorrelationId = "55"; const mockReferralDate = "2022"; const mockAccountNumber = "167132"; - const mockavedSessionId = "xxx-xxx-xxx"; + const mockSavedSessionId = "xxx-xxx-xxx"; const mockCrmCustomerId = "xxx-xxx-xxx" - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSaveQuoteId, mockCrmCustomerId); + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSavedSessionId, mockCrmCustomerId); const mockData = { actionList: [{ @@ -344,10 +344,10 @@ describe("navigateToHeritageFunnel", () => { const mockCorrelationId = "55"; const mockReferralDate = "2022"; const mockAccountNumber = "167132"; - const mockSaveQuoteId = "xxx-xxx-xxx"; + const mockSavedSessionId = "xxx-xxx-xxx"; const mockCrmCustomerId = "xxx-xxx-xxx" - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSaveQuoteId, mockCrmCustomerId); + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSavedSessionId, mockCrmCustomerId); const mockData = { actionList: [{ diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index 2e6fcade0..870ee190b 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -84,7 +84,7 @@ async function saveOrderHelper() { referralCorrelationId: savedOrderInfo.data.referralCorrelationId, referralDate: savedOrderInfo.data.referralDate, accountNumber: savedOrderInfo.data.accountNumber.toString(), - saveQuoteId: savedOrderInfo.data.saveQuoteId, + savedSessionId: savedOrderInfo.data.savedSessionId, crmCustomerId: savedOrderInfo.data.crmCustomerId.toString(), }, false); diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index c3a581e41..400ab46e4 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -112,10 +112,10 @@ describe("saveOrder", () => { const mockCorrelationId = "55"; const mockReferralDate = "2022"; const mockAccountNumber = "167132"; - const mockSaveQuoteId = "xxx-xxx-xxx"; + const mockSavedSessionId = "xxx-xxx-xxx"; const mockCrmCustomerId = "xxx-xxx-xxx" - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSaveQuoteId, mockCrmCustomerId); + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, mockAccountNumber, mockSavedSessionId, mockCrmCustomerId); const mockData = { actionList: [ @@ -141,7 +141,7 @@ describe("saveOrder", () => { referralDate: mockReferralDate, referralCorrelationId: mockCorrelationId, accountNumber: mockAccountNumber, - saveQuoteId: mockSaveQuoteId, + savedSessionId: mockSavedSessionId, crmCustomerId: mockCrmCustomerId, }, false); }); @@ -152,10 +152,10 @@ describe("saveOrder", () => { const mockReferralDate = "2022-03-15T10:56:24.597"; const mockReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; const mockAccountNumber = "167132"; - const mockSaveQuoteId = "xxx-xxx-xxx"; + const mockSavedSessionId = "xxx-xxx-xxx"; const mockCrmCustomerId = "xxx-xxx-xxx" - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockReferralCorrelationId, mockReferralDate, mockAccountNumber, mockSaveQuoteId, mockCrmCustomerId); + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockReferralCorrelationId, mockReferralDate, mockAccountNumber, mockSavedSessionId, mockCrmCustomerId); const mockData = { actionList: [{ diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index ba816cdb1..ca50a4e7b 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -28,7 +28,7 @@ export function isAnalyticsSessionStillActive() { */ export function isSavedSessionStillActive() { if (getFunnelCookie() !== null) { - const savedSessionTimeStamp = new Date(getFunnelCookie().SavedQuoteTimeoutDate); + const savedSessionTimeStamp = new Date(getFunnelCookie().SavedSessionTimeoutDate); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); if (isSavedSessionTimedOut) { diff --git a/src/helpers/heritage-integration/session-helper.spec.js b/src/helpers/heritage-integration/session-helper.spec.js index 8a17743d1..b41827bf7 100644 --- a/src/helpers/heritage-integration/session-helper.spec.js +++ b/src/helpers/heritage-integration/session-helper.spec.js @@ -41,7 +41,7 @@ describe("isSavedSessionStillActive", () => { mockDate.setDate(mockDate.getDate() + 1); cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") - .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); + .mockReturnValue({ SavedSessionTimeoutDate: mockDate }); // Act const result = isSavedSessionStillActive(); @@ -56,7 +56,7 @@ describe("isSavedSessionStillActive", () => { mockDate.setDate(mockDate.getDate() - 1) cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") - .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); + .mockReturnValue({ SavedSessionTimeoutDate: mockDate }); // Act const result = isSavedSessionStillActive(); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 36745d28a..13436be78 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -90,13 +90,13 @@ export function removeAllTestCookies() { }); } -export function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, accountNumber = "0", saveQuoteId, crmCustomerId) { +export function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate, accountNumber = "0", savedSessionId, crmCustomerId) { return { referralNumber: mockReferralNumber, referralCorrelationId: mockCorrelationId, referralDate: mockReferralDate, accountNumber: accountNumber, - saveQuoteId: saveQuoteId, + savedSessionId: savedSessionId, crmCustomerId: crmCustomerId, } } diff --git a/src/store/index.js b/src/store/index.js index 64ba356e6..2c507a123 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -66,7 +66,7 @@ const getDefaultState = () => { pageData: {}, savedSessionTimeout: getDateForSavedSessionTimeout(), saveOrderPromise: null, - saveQuoteId: null, + savedSessionId: null, crmCustomerId: null, lastPageVisited: null, experiments: [] @@ -209,8 +209,8 @@ export const mutations = { updateSaveOrderPromise(state, saveOrderPromise){ state.applicationUser.saveOrderPromise = saveOrderPromise; }, - updateSaveQuoteId(state, saveQuoteId) { - state.applicationUser.saveQuoteId = saveQuoteId; + updateSavedSessionId(state, savedSessionId) { + state.applicationUser.savedSessionId = savedSessionId; }, updateCrmCustomerId(state, crmCustomerId) { state.applicationUser.crmCustomerId = crmCustomerId; @@ -502,12 +502,12 @@ export const actions = { }, // Misc Actions - updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, accountNumber, saveQuoteId, crmCustomerId }) { + updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, accountNumber, savedSessionId, crmCustomerId }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, accountNumber); - context.commit(storeMutations.UPDATE_SAVE_QUOTE_ID, saveQuoteId); + context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId); context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId); }, @@ -690,7 +690,7 @@ export const actions = { existingPromoCode: null, lastPage: applicationUser.lastPageVisited, crmCustomerId: applicationUser.crmCustomerId, - saveQuoteId: applicationUser.saveQuoteId, + savedSessionId: applicationUser.savedSessionId, }, }); From b41eae1797733e32ec8fc336420d2c7466a9a92b Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Jul 2022 14:39:07 -0400 Subject: [PATCH 19/44] CSR-111: set up prerequisite data and navigation for capability questions --- .../capability-questions.vue | 162 ++++++++++++++++++ .../molding-questions/molding-questions.vue | 111 ++---------- src/layouts/part-questions/part-questions.vue | 61 +++---- src/layouts/vehicle-parts/vehicle-parts.vue | 54 +++--- src/mixins/vehicle-questions-mixin.js | 43 +++++ src/mixins/vin-pages-mixin.js | 25 ++- src/mixins/vin-pages-mixin.spec.js | 12 +- src/router/router-constants/fmgPage-values.js | 1 + .../router-constants/navigation-scenarios.js | 2 + src/router/router-constants/routing-table.js | 39 ++++- 10 files changed, 335 insertions(+), 175 deletions(-) create mode 100644 src/layouts/capability-questions/capability-questions.vue create mode 100644 src/mixins/vehicle-questions-mixin.js diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue new file mode 100644 index 000000000..025e5aa20 --- /dev/null +++ b/src/layouts/capability-questions/capability-questions.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 0ffaae411..a0fa5e96d 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -60,6 +60,7 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,9 +109,10 @@ export default { return this.getCmsContent("AlertPartsQuestions", "BodyText"); }, }, + mixins: [vehicleQuestionsMixin], methods: { arePagePrerequisitesValid() { - return true; + return true; // TODO - DO TRUE TEST OF PAGEDATA // return Object.keys(store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)).length > 0; }, showThisPartQuestionChain(part, i) { @@ -146,111 +148,20 @@ export default { const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; - console.log("glassNameAndPartsForStore: ", glassNameAndPartsForStore); + const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore); - // HARD CODE RESPONSE FOR NOW... - - this.glassNameAndPartsForStore = [ - { - "glassName": "Single", - "glassLocation": "Windshield", - "parts": [ - { - "partNumber": "FW03861GTYN", - "description": "rain sensor, heated glass, auto dimming mirror, solar, 3rd visor band, condensation sensor", - "color": "Green Tint", - "requiresRecalibration": false, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [ - { - "questionSequence": 1, - "questionText": "Does the rubber seal around your windshield have a chrome strip running through it?", - "answers": [ - { - "answerResult": "WKT D1106 C", - "answerText": "Yes", - "nextQuestionSequence": null - }, - { - "answerResult": "WKT D1106 B", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } - ] - }, - { - "glassName": "Stationary", - "glassLocation": "Rear", - "parts": [ - { - "partNumber": "FB25992GTNN", - "description": "heated glass, solar", - "color": "Green Tint", - "requiresRecalibration": false, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ] - } - ]; - - - - - - - // test response data for multiple parts - const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); - - // loop through all glass items - const collectedGlassParts = []; - glassNameAndPartsForStore.forEach((glass) => { - if (Array.isArray(glass.parts) && glass.parts.length === 1) { - const singlePart = glass.parts[0]; - collectedGlassParts.push({ - "partNumber": singlePart.partNumber, - "description": singlePart.description, - "color": singlePart.color, - "requiresRecalibration": singlePart.requiresRecalibration, - "childParts": singlePart.childParts, - "price": singlePart.price, - }); - // check for and collect any molding questions - if (Array.isArray(singlePart.childPartQuestions) && singlePart.childPartQuestions.length > 0) { - this.moldingQuestionsForStore.push({ - "glassName": glass.glassName, - "glassLocation": glass.glassLocation, - "childPartQuestions": singlePart.childPartQuestions, - }); - } - } - }); - if (!hasMultipleParts) { - this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - } - this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); - }, - navigateForward(hasMultipleParts, glassNameAndPartsForStore) { - if (hasMultipleParts) { - // if multiple parts on any glass - // go to vehicle-parts page and pass the partsData - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + if (hasCapabilityQuestions) { + // if has capability questions + // go to capability-questions page + this.$router.navigate(this.navigationScenarios.HAS_CAPABILITY_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); } else { // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); // go to quote page this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - }, }, watch: { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 856b8a099..b22c30ba6 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -60,6 +60,7 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,6 +109,7 @@ export default { return this.getCmsContent("AlertPartsQuestions", "BodyText"); }, }, + mixins: [vehicleQuestionsMixin], methods: { showThisPartQuestionChain(part, i) { if (part.partQuestions?.length < 1) { return false; } // return false if only one partQuestion @@ -137,59 +139,36 @@ export default { // call API parts method const partsLookup = await this.dispatchStoreAction(storeActions.GET_PARTS) .catch(() => { - this.$refs.funnelFooter.removeLoader(); + return this.$refs.funnelFooter.removeLoader(); }); - if (!partsLookup) { return } + const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(glassNameAndPartsForStore); + const hasChildPartQuestions = this.hasChildPartQuestions(glassNameAndPartsForStore); + const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore); - // test response data for multiple parts - const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); - - // loop through all glass items - const collectedGlassParts = []; - glassNameAndPartsForStore.forEach((glass) => { - if (Array.isArray(glass.parts) && glass.parts.length === 1) { - const singlePart = glass.parts[0]; - collectedGlassParts.push({ - "partNumber": singlePart.partNumber, - "description": singlePart.description, - "color": singlePart.color, - "requiresRecalibration": singlePart.requiresRecalibration, - "childParts": singlePart.childParts, - "price": singlePart.price, - }); - // check for and collect any molding questions - if (Array.isArray(singlePart.childPartQuestions) && singlePart.childPartQuestions.length > 0) { - this.moldingQuestionsForStore.push({ - "glassName": glass.glassName, - "glassLocation": glass.glassLocation, - "childPartQuestions": singlePart.childPartQuestions, - }); - } - } - }); - if (!hasMultipleParts) { - store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - } - this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); - }, - async navigateForward(hasMultipleParts, glassNameAndPartsForStore) { - if (hasMultipleParts) { + // NAVIGATE FORWARD + if (hasGlassLocationWithMultipleParts) { // if multiple parts on any glass // go to vehicle-parts page and pass the partsData this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + } else if (hasChildPartQuestions) { + // if any childpart questions + // go to molding-questions page and pass the partsData + this.$router.navigate(this.navigationScenarios.HAS_MOLDING_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + } else if (hasCapabilityQuestions) { + // if has capability questions + // go to capability-questions page and pass the partsData + this.$router.navigate(this.navigationScenarios.HAS_CAPABILITY_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); } else { // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); // go to quote page this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - - - }, arePagePrerequisitesValid() { return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length > 0; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index d0af557b0..3cbc07e6f 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -60,9 +60,10 @@ import alert from "@/ux-components/alert/alert"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import store from "@/store"; import { Form } from "vee-validate"; -import { storeActions } from "@/constants/store-actions"; +import store from "@/store"; +import { storeMutations } from "@/constants/store-mutations.js"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { name: "vehicle-parts", @@ -95,7 +96,6 @@ export default { data() { return { glassParts: {}, - matchedParts: [], alertWidgetData: Object, alreadyPopulatedPartsData: {}, }; @@ -141,13 +141,14 @@ export default { }, PartsFromApi() { - return store.getters.pageData(fmgPageValues.VEHICLE_PARTS); + return this.$store.getters.pageData(fmgPageValues.VEHICLE_PARTS); }, RefPrefix() { return "partQuestion"; }, }, + mixins: [vehicleQuestionsMixin], methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) @@ -160,7 +161,7 @@ export default { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - let isMoldingQuestions = false; + const matchedParts = []; // Match them to the parts from the API. for (let [key, value] of Object.entries( @@ -175,47 +176,54 @@ export default { ); if (isMatched) { - this.matchedParts.push(currentPart); - // check if there are childPartQuestions (for molding-questions) - if (Array.isArray(currentPart.childPartQuestions) && currentPart.childPartQuestions.length > 0) { - isMoldingQuestions = true - } + matchedParts.push({ + "glassLocation": value.glassLocation, + "glassName": value.glassName, + "parts": [currentPart] + }); } } } - // If no parts could be matched, throw an error (isForwardActionDisabled is based off of this.matchedParts) + const hasChildPartQuestions = this.hasChildPartQuestions(matchedParts); + const hasCapabilityQuestions = this.hasCapabilityQuestions(matchedParts); + + // If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts) if (this.isForwardActionDisabled) { this.$refs.funnelFooter.removeLoader(); throw new Error("Could not match any parts to the selected parts"); } // Navigate to the next page - if (isMoldingQuestions) { + if (hasChildPartQuestions) { this.$router.navigate( this.navigationScenarios.HAS_MOLDING_QUESTIONS, this.$route, {}, {}, - this.moldingQuestionsForStore + {partsOrQuestions: matchedParts} ); - } - else { - // Save parts to the store - await this.dispatchStoreAction( - storeActions.SAVE_GLASS_PARTS, - this.matchedParts, - false + } else if (hasCapabilityQuestions) { + this.$router.navigate( + this.navigationScenarios.HAS_CAPABILITY_QUESTIONS, + this.$route, + {}, + {}, + {partsOrQuestions: matchedParts} ); + + } else { + // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(matchedParts); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + // Navigate to the quote page this.$router.navigate( this.navigationScenarios.SELECTED_PARTS, this.$route ); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - }, LoadInitialPartsData() { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js new file mode 100644 index 000000000..5490ea7bf --- /dev/null +++ b/src/mixins/vehicle-questions-mixin.js @@ -0,0 +1,43 @@ +export default { + + methods: { + hasPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + }, + hasGlassLocationWithMultipleParts(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.parts?.length > 1); + }, + hasChildPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.childPartQuestions?.length > 0); + }); + }, + hasCapabilityQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.requiresCapabilityQuestions === true); + }); + }, + // method to only include keys listed for lineItems.glassParts in + // https://safelite.atlassian.net/wiki/spaces/DC/pages/17137665/Catalog+Front-End+State#glassParts + reduceGlassPartsArray(glassParts) { + const reducedGlassParts = []; + glassParts.forEach((glass) => { + if (Array.isArray(glass.parts) && glass.parts.length === 1) { + const singlePart = glass.parts[0]; + reducedGlassParts.push({ + "partNumber": singlePart.partNumber, + "description": singlePart.description, + "color": singlePart.color, + "requiresRecalibration": singlePart.requiresRecalibration, + "requiresCapabilityQuestions": singlePart.requiresCapabilityQuestions, + "recalibrationType": singlePart.recalibrationType, + "childParts": singlePart.childParts, + "price": singlePart.price, + }); + } + }); + return reducedGlassParts; + } + } + +} \ No newline at end of file diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index 196a21e63..b9d652223 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -1,18 +1,20 @@ -import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { + mixins: [vehicleQuestionsMixin], methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); + const partsOrQuestions = result.data.partsOrQuestions; - const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); - const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); - const hasChildPartQuestions = partsOrQuestions.some(pq => { - return pq.parts?.some(part => part.childPartQuestions?.length > 0); - }); + + const hasPartsQuestions = this.hasPartQuestions(partsOrQuestions); + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); + const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions); + const hasCapabilityQuestions = this.hasCapabilityQuestions(partsOrQuestions); // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS @@ -25,8 +27,17 @@ export default { else if (hasChildPartQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, this.$route, {}, {}, result.data); } + else if (hasCapabilityQuestions) { + this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, this.$route, {}, {}, result.data); + } else { - store.commit(storeMutations.UPDATE_GLASS_PARTS, result.data); + // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(result.data.partsOrQuestions); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + + // go to quote page + this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); this.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); } diff --git a/src/mixins/vin-pages-mixin.spec.js b/src/mixins/vin-pages-mixin.spec.js index 0ef66226f..49503d9dc 100644 --- a/src/mixins/vin-pages-mixin.spec.js +++ b/src/mixins/vin-pages-mixin.spec.js @@ -864,14 +864,17 @@ describe("vin-pages-mixin", () => { partsOrQuestions: partsOrQuestions }); - store.commit = jest.fn(); + wrapper.vm.$store.commit = jest.fn(); + + const collectedGlassParts = wrapper.vm.reduceGlassPartsArray(partsOrQuestions); // Act await wrapper.vm.navigateForwardWithSingleCarMatch(); + // Assert - expect(store.commit).toHaveBeenCalledTimes(1); - expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_GLASS_PARTS, { partsOrQuestions }) + expect(wrapper.vm.$store.commit).toHaveBeenCalledTimes(1); + expect(wrapper.vm.$store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts) expect(wrapper.vm.$refs.loadingModal.showModal).toHaveBeenCalledTimes(1); expect(navigateToHeritageFunnel).toHaveBeenCalledTimes(1); }); @@ -895,6 +898,9 @@ function setupMocks({ partsOrQuestions = [] }) { router: { navigate: jest.fn() }, + store: { + commit: jest.fn() + } }); const mockVinComponent = { diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 7a38c6b40..404a89de9 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -9,6 +9,7 @@ const fmgPageValues = { VEHICLE_PARTS: "vehicle-parts", PART_QUESTIONS: "part-questions", MOLDING_QUESTIONS: "molding-questions", + CAPABILITY_QUESTIONS: "capability-questions", LICENSE_PLATE_LOOKUP: "license-plate-lookup", REVEAL: "reveal", ESTIMATE: "estimate", diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index ab1772de3..c252a3d0f 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -11,6 +11,7 @@ const navigationScenarios = { SELECTED_VIN_WITH_PART_QUESTIONS: "SELECTED_VIN_WITH_PART_QUESTIONS", SELECTED_VIN_WITH_MULTIPLE_PARTS: "SELECTED_VIN_WITH_MULTIPLE_PARTS", SELECTED_VIN_WITH_MOLDING_QUESTIONS: "SELECTED_VIN_WITH_MOLDING_QUESTIONS", + SELECTED_VIN_WITH_CAPABILITY_QUESTIONS: "SELECTED_VIN_WITH_CAPABILITY_QUESTIONS", CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART", CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES", SELECTED_VIN_HAS_MISMATCHED_GLASS: "SELECTED_VIN_HAS_MISMATCHED_GLASS", @@ -21,6 +22,7 @@ const navigationScenarios = { ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS", + HAS_CAPABILITY_QUESTIONS: "HAS_CAPABILITY_QUESTIONS", SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 51ac52efa..73b501493 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -135,6 +135,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -160,6 +164,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -189,6 +197,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -211,10 +223,18 @@ const routingTable = function(store) { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS + }, { scenario: navigationScenarios.SELECTED_PROVIDE_VIN_DIFFERENT_WAY, destinationFmgPageValue: fmgPageValues.ESTIMATE - } + } ], }, { @@ -253,6 +273,10 @@ const routingTable = function(store) { scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS, }, + { + scenario: navigationScenarios.HAS_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, + }, { scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, destinationFmgPageValue: fmgPageValues.QUOTE, @@ -261,6 +285,19 @@ const routingTable = function(store) { }, { fmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.HAS_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, + }, + ] + }, + { + fmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, maps: [ { scenario: navigationScenarios.CLICKED_BACK, From 6a8409cd345863d01037856714a6e72d1d52952b Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:03:40 -0400 Subject: [PATCH 20/44] CSR-702 Add basic routing for part-questions --- .../button-question/button-question.vue | 2 +- src/layouts/part-questions/part-questions.vue | 2 +- .../side-door-options/side-door-options.vue | 2 +- .../glass-part-question.vue | 3 ++- src/layouts/vehicle-parts/vehicle-parts.vue | 19 +++++++++---------- src/mixins/vehicle-questions-mixin.js | 10 ++++++++++ src/mixins/vehicle-questions-mixin.spec.js | 0 src/mixins/vin-pages-mixin.js | 8 +++++--- src/router/index.js | 7 +++++-- .../router-constants/navigation-scenarios.js | 4 +++- src/router/router-constants/routing-table.js | 12 ++++++++---- src/store/index.js | 7 ++++++- .../list-button-horizontal.vue | 8 ++++---- src/ux-components/list-button/list-button.vue | 8 ++++---- src/ux-components/list-card/list-card.vue | 6 +----- 15 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 src/mixins/vehicle-questions-mixin.js create mode 100644 src/mixins/vehicle-questions-mixin.spec.js diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index ee9ecdbad..6848285b8 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -89,7 +89,7 @@ export default { modelValue: [Array, String], validationRules: String, suppressError: Boolean, - useTextForValue: Boolean + useTextForValue: Boolean, }, computed: { formattedGroupName() { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index f5ec4841d..ee1d81c09 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions.filter((p) => { + partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue index b4df1121e..284c3eee6 100644 --- a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue @@ -112,7 +112,7 @@ export default ({ this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides, this.selectedValues.selectedDriverSideReplaceOptions, newValue); } }, - answersToDisplay(){ + answersToDisplay(){ const filteredAnswers = Array.isArray(this.answersFromCms) ? this.answersFromCms.filter(ans => { diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index 608cf55cb..b46a2f9bc 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,6 +48,7 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import store from "@/store"; export default { name: "glass-part-question", @@ -152,7 +153,7 @@ export default { }, PartDataFromApi() { - return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index ce5727ce3..c35699c4e 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -63,9 +63,11 @@ import store from "@/store"; import { Form } from "vee-validate"; import { storeActions } from "@/constants/store-actions"; + import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { name: "vehicle-parts", + mixins: [vehicleQuestionsMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); @@ -173,19 +175,16 @@ methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) - if ( - store.getters.damage.isRepair != null && - Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) - .length !== 0 - ) { - return true; - } - - return false; + return store.getters.damage.isRepair != null && + Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { + console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) + const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); + const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; + this.$router.navigate( - this.navigationScenarios.CLICKED_BACK, + backNavigationScenario, this.$route ); }, diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js new file mode 100644 index 000000000..7a8f3832f --- /dev/null +++ b/src/mixins/vehicle-questions-mixin.js @@ -0,0 +1,10 @@ +export default { + methods: { + hasPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + }, + hasGlassLocationWithMultipleParts(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.parts?.length > 1); + } + } +} \ No newline at end of file diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index fce96c980..31fa44cf7 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -2,15 +2,17 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { + mixins: [vehicleQuestionsMixin], methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); const partsOrQuestions = result.data.partsOrQuestions; - const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); - const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); + const hasPartsQuestions = this.hasPartQuestions(partsOrQuestions); + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); if (hasPartsQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data); @@ -23,6 +25,6 @@ export default { this.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); } - } + }, } } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d2a5ee154..d086cc89a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -173,8 +173,11 @@ async function navigate(scenario, currentRoute, optionalQuery = {}, optionalPara if (destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. - // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. - baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + // Update page data to the store for next page if provided. Otherwise, use existing page data or override with empty object + const existingPageData = store.getters.pageData(destinationFmgPageValue) ?? {}; + if (Object.keys(optionalPageData).length > 0 && Object.keys(existingPageData).length === 0) { + baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + } // if cookie and referralNumber/Date exists OR an emailAddress has been saved if ((getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) || store.getters.order.customer?.emailAddress) { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5768c55de..61de8147f 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -19,7 +19,9 @@ const navigationScenarios = { SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", - SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" + SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY", + CLICKED_BACK_WITH_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITH_PART_QUESTION_ANSWERS", + CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS" }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 25463bd8b..0c729607f 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -82,10 +82,6 @@ const routingTable = function(store) { { fmgPageValue: fmgPageValues.VEHICLE_PARTS, maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, { scenario: navigationScenarios.SELECTED_PARTS, destinationFmgPageValue: fmgPageValues.QUOTE, @@ -94,6 +90,14 @@ const routingTable = function(store) { scenario: navigationScenarios.CLICKED_FORWARD, destinationFmgPageValue: fmgPageValues.REVEAL, }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, ], }, { diff --git a/src/store/index.js b/src/store/index.js index 90932c8bb..200389734 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,7 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/se import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "../constants/store-actions"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Export State const getDefaultState = () => { @@ -264,7 +265,10 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { + console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; + state.order.damage.partQuestionAnswers = null; + state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; }, resetState(state) { Object.assign(state, getDefaultState()); @@ -701,7 +705,7 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { - context.commit(storeMutations.RESET_STATE); + // context.commit(storeMutations.RESET_STATE); context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); return response; }); @@ -854,6 +858,7 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values + // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, 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 2fef5119f..5bcfcc706 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index 34b6f92e0..cef450bb6 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index a4ef7eac8..002fb14ac 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -110,10 +110,6 @@ export default { this.checkValue = this.selectedValues == this.value || this.modelValue == this.value; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, computed: { getLabelClasses() { if (this.isWide) { @@ -185,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - checkedValue: props.value, // EX: "Single" or "Passenger" + // checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 7e5fb4c906903f2c657553327b50e091e10add72 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:31:20 -0400 Subject: [PATCH 21/44] CSR-702 Cleanup --- src/layouts/part-questions/part-questions.vue | 2 +- src/layouts/vehicle-parts/vehicle-parts.vue | 3 --- src/store/index.js | 2 -- .../list-button-horizontal/list-button-horizontal.vue | 4 ---- src/ux-components/list-button/list-button.vue | 4 ---- src/ux-components/list-card/list-card.vue | 2 +- 6 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 3f779ace8..ff5f494c1 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -142,7 +142,7 @@ export default { if (!partsLookup) { return } - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; + const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; // test response data for multiple parts const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 75ba3df7f..80cdf8a97 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -157,7 +157,6 @@ export default { Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { - console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; @@ -167,8 +166,6 @@ export default { ); }, async forwardButtonAction() { - const selectedGlassPartNumbers = []; - const matchedParts = []; let isMoldingQuestions = false; // Match them to the parts from the API. diff --git a/src/store/index.js b/src/store/index.js index d6c09b22c..f3e3cf96a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -265,7 +265,6 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { - console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; state.order.damage.partQuestionAnswers = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; @@ -866,7 +865,6 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values - // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, 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 5bcfcc706..4c9670097 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index cef450bb6..aabb06ae5 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index 002fb14ac..a1c95157f 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -181,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - // checkedValue: props.value, // EX: "Single" or "Passenger" + checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 18524de9a6fe74b3f2bc4a142861a2db1173c4d4 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 16:02:53 -0400 Subject: [PATCH 22/44] CSR-702 Add vehicle-questions-mixin tests --- src/layouts/part-questions/part-questions.vue | 2 +- .../glass-part-question.vue | 3 +- src/mixins/vehicle-questions-mixin.spec.js | 161 ++++++++++++++++++ 3 files changed, 163 insertions(+), 3 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index ff5f494c1..6f18408b7 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { + partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index b46a2f9bc..608cf55cb 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,7 +48,6 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; -import store from "@/store"; export default { name: "glass-part-question", @@ -153,7 +152,7 @@ export default { }, PartDataFromApi() { - return store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index e69de29bb..01d41b9c8 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -0,0 +1,161 @@ +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import { shallowMount } from "@vue/test-utils"; +import { setupMocksForJsFiles, getMountOptions } from "@/helpers/unit-test-helper.js"; + +describe("vehicle-questions-mixin", () => { + describe("hasPartQuestions", () => { + test("has no part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has undefined part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has part questions => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [{ + testProperty: "some value" + }] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(true); + }); + }); + + describe("hasGlassLocationWithMultipleParts", () => { + test("has one part for one glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has one part for every glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [{ + partNumber: "1234569" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has multiple parts for one glass location => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [ + { + partNumber: "1234569" + }, + { + partNumber: "1234560" + } + ] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(true); + }); + }); +}); + +function setupMocks({}) { + const baseMixin = setupMocksForJsFiles({}); + + const mocks = getMountOptions({ + router: { + navigate: jest.fn() + }, + }); + + const mockVehicleQuestionComponent = { + template: '
', + mixins: [vehicleQuestionsMixin, baseMixin.baseMixin] + }; + + const wrapper = shallowMount(mockVehicleQuestionComponent, mocks); + + return { wrapper }; +} \ No newline at end of file From 149adc97929bd7b1f83c464c99f18aed876818bd Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Jul 2022 16:21:13 -0400 Subject: [PATCH 23/44] CSR-110: restored navigation to go back to heritage funnel --- .../capability-questions/capability-questions.vue | 3 +++ src/layouts/molding-questions/molding-questions.vue | 8 ++++++-- src/layouts/part-questions/part-questions.vue | 9 +++++++-- src/layouts/vehicle-parts/vehicle-parts.vue | 11 ++++++----- src/mixins/vin-pages-mixin.js | 3 +-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 025e5aa20..69fc8aad5 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -145,6 +147,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index a0fa5e96d..c489dc500 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -159,8 +161,9 @@ export default { const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); // save to store lineItems.glassParts this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - // go to quote page - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); + // go to heritage quote page + this.$refs.loadingModal.showModal(); + navigateToHeritageFunnel(); } }, }, @@ -180,6 +183,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index b22c30ba6..dcefad7c0 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -61,6 +63,7 @@ import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -166,8 +169,9 @@ export default { const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); // save to store lineItems.glassParts this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - // go to quote page - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); + // go to heritage quote page + this.$refs.loadingModal.showModal(); + navigateToHeritageFunnel(); } }, arePagePrerequisitesValid() { @@ -190,6 +194,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 3cbc07e6f..832d4bb94 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -1,6 +1,7 @@