From 8c64b13c6d2158c252f9b112bb1c6e980f121478 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 24 Aug 2023 10:47:54 -0400 Subject: [PATCH 01/32] front end for endorsements page --- .../endorsements-page/endorsements-page.vue | 70 +++++++++++++++++++ src/router/router-constants/issPage-values.js | 1 + src/router/router-constants/routing-table.js | 16 ++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/layouts/endorsements-page/endorsements-page.vue diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue new file mode 100644 index 00000000..1e2513b4 --- /dev/null +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -0,0 +1,70 @@ + + diff --git a/src/router/router-constants/issPage-values.js b/src/router/router-constants/issPage-values.js index 9ddfab8c..4c98b188 100644 --- a/src/router/router-constants/issPage-values.js +++ b/src/router/router-constants/issPage-values.js @@ -8,6 +8,7 @@ const issPageValues = Object.freeze({ BAILOUT_PAGE: 'bailout-page', CAPABILITY_QUESTIONS: 'capability-questions', CONTACT_DETAILS: 'contact-details', + ENDORSEMENTS_PAGE: 'endorsements-page', ESTIMATE: 'estimate', COVERAGE_STATEMENT: 'coverage-statement', LICENSE_PLATE_LOOKUP: 'license-plate-lookup', diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index a4093eaf..b61db6d8 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -603,7 +603,21 @@ const routingTable = () => [ destinationIssPageValue: issPageValues.BAILOUT_CONFIRMATION } ] - } + }, + { + issPageValue: issPageValues.ENDORSEMENTS_PAGE, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationIssPageValue: issPageValues.POLICY_VEHICLES + }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationIssPageValue: issPageValues.VEHICLE_DAMAGE + } + ] + }, + ]; export { routingTable }; From b523e2c976beda9be6daaf2c259776d69fbc4464 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 24 Aug 2023 11:57:00 -0400 Subject: [PATCH 02/32] add subheader to page --- src/layouts/endorsements-page/endorsements-page.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 1e2513b4..dc92f80a 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -7,6 +7,7 @@
+
// Components import siteHeader from '@/iss-components/site-header/site-header.vue'; +import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue'; // Supporting files import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; @@ -33,6 +35,7 @@ export default { name: 'endorsements-page', components: { siteHeader, + siteSubHeader, siteFooter, // eslint-disable-next-line vue/no-reserved-component-names Form From 606b43ef8e316baa855cff0eb94e8221a317d60d Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 24 Aug 2023 11:57:23 -0400 Subject: [PATCH 03/32] navigation from policy-vehicles to endorsements --- src/layouts/policy-vehicles/policy-vehicles.vue | 10 ++++++++++ src/router/router-constants/navigation-scenarios.js | 1 + src/router/router-constants/routing-table.js | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index e10df300..dcd70af7 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -118,6 +118,10 @@ export default { ? vehicle?.coverages[0].deductible : 0; }, + endorsementsForSelectedVehicle() { + // hardcoded until endorsements service is ready + return true; + }, repairWaivedForSelectedVehicle() { const vehicle = this.policyVehicles.find((policyVehicle) => policyVehicle.vin === this.selectedVehicleVin); @@ -148,6 +152,7 @@ export default { // save selected vehicle to the store this.mainStore.updateVehicle(vehicle.data); this.displayGeneric = false; + console.log(this.endorsementsForSelectedVehicle); } } } @@ -194,6 +199,11 @@ export default { this.$route, {}, {}); + } else if (!!this.endorsementsForSelectedVehicle) { + this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, + this.$route, + {}, + {}); } else { this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE, this.$route, diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 934065c1..2d2d4be3 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -24,6 +24,7 @@ const navigationScenarios = { // Policy Vehicle CLICKED_FORWARD_LISTED_VEHICLE: 'CLICKED_FORWARD_LISTED_VEHICLE', CLICKED_FORWARD_NON_LISTED_VEHICLE: 'CLICKED_FORWARD_NON_LISTED_VEHICLE', + CLICKED_FORWARD_WITH_ENDORSEMENTS: 'CLICKED_FORWARD_WITH_ENDORSEMENTS', // Vehicle Damage CLICKED_FORWARD_WITH_REPAIR: 'CLICKED_FORWARD_WITH_REPAIR', diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index b61db6d8..a0622319 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -392,7 +392,12 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, destinationIssPageValue: issPageValues.BAILOUT_PAGE - } + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, + destinationIssPageValue: issPageValues.ENDORSEMENTS_PAGE + }, + ] }, { From ccda6519419b584e88593b8ad144ad818d73bf0c Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 24 Aug 2023 14:37:23 -0400 Subject: [PATCH 04/32] endorsements WIP --- .../endorsements-page/endorsements-page.vue | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index dc92f80a..720b86f9 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -7,7 +7,25 @@
- + + + + +
+ + From 25fa11629b3e66789d958f4dda4ddd4818af945a Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 24 Aug 2023 14:50:22 -0400 Subject: [PATCH 05/32] commit --- src/layouts/endorsements-page/endorsements-page.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 720b86f9..46dac883 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -8,6 +8,7 @@
+
-
Date: Mon, 28 Aug 2023 11:12:25 -0400 Subject: [PATCH 06/32] WIP --- .../endorsements-page/endorsements-page.vue | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 46dac883..17410a15 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -9,24 +9,39 @@
- + +
+ Date: Mon, 28 Aug 2023 16:07:24 -0400 Subject: [PATCH 07/32] button question functionality --- .../endorsements-page/endorsements-page.vue | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 17410a15..4277b73b 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -9,25 +9,14 @@
-
- -
- + Date: Mon, 11 Sep 2023 10:56:15 -0400 Subject: [PATCH 08/32] remove console log --- src/layouts/policy-vehicles/policy-vehicles.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 5bc511f3..54f19ce9 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -152,7 +152,6 @@ export default { // save selected vehicle to the store this.mainStore.updateVehicle(vehicle.data); this.displayGeneric = false; - console.log(this.endorsementsForSelectedVehicle); } } } From 0f3a9a18d923131cdb3fa45973cce83a5d45c4a2 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Mon, 11 Sep 2023 10:56:33 -0400 Subject: [PATCH 09/32] fix importing of settleAllPromises --- src/layouts/endorsements-page/endorsements-page.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 4277b73b..bbe57f4e 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -55,7 +55,7 @@ import questionChain from '@/digital-components/question-chain/question-chain.vu // Supporting files import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; -import { settleAllPromises } from '@/helpers/layout-helper'; +import settleAllPromises from '@/helpers/layout-helper'; import { Form } from 'vee-validate'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import globalRules from '@/constants/global-rules.js'; From 60b7fe5d53c78f37475b5c8a5352950ef67436b7 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Mon, 11 Sep 2023 11:16:09 -0400 Subject: [PATCH 10/32] save endorsements answers to store --- src/store/index.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index a2bfbcd7..f213b2a8 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -58,7 +58,8 @@ const getDefaultState = () => ({ deductible: { repair: null, // numerical value; how much customer owes on deductible in repair case replace: null // numerical value; how much customer owes on deductible in replace case, - } + }, + endorsementQuestionAnswers: null, }, customer: { address: { @@ -817,6 +818,21 @@ export const useMainStore = defineStore({ this.applicationUser.saveSessionPromise = null; }, + saveEndorsementQuestionAnswers(endorsementQuestionAnswersArray) { + // if endorsement question answers have changed, reset question answers + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.policy.endorsementQuestionAnswers, 'result'); + const sortedEndorsementQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(endorsementQuestionAnswersArray, 'result'); + const haveEndorsementQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedEndorsementQuestionAnswersArray.length + || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedEndorsementQuestionAnswersArray[i].result); + + if (haveEndorsementQuestionAnswersChanged) { + this.updateEndorsementQuestionAnswers(null); + } + + // Save new values + this.updateEndorsementQuestionAnswers(endorsementQuestionAnswersArray); + }, + saveVehicleDamage(isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount) { const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort(); const isGlassToReplaceTheSame = this.order.damage.glassToReplace?.length === selectedGlassToReplace.length @@ -1014,6 +1030,10 @@ export const useMainStore = defineStore({ } }, + updateEndorsementQuestionAnswers(answersArray) { + this.order.policy.endorsementQuestionAnswers = answersArray; + }, + updateIsRepair(isRepair) { this.order.damage.isRepair = isRepair; }, From 3af5a3a204032dc8d1b0ed96638ca440f0349e4b Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Mon, 11 Sep 2023 14:46:38 -0400 Subject: [PATCH 11/32] create answer array and call method to save to store --- .../endorsements-page/endorsements-page.vue | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index bbe57f4e..7b7f1977 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -59,6 +59,7 @@ import settleAllPromises from '@/helpers/layout-helper'; import { Form } from 'vee-validate'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import globalRules from '@/constants/global-rules.js'; +import { useMainStore } from '@/store'; export default { name: 'endorsements-page', @@ -117,7 +118,26 @@ export default { backButtonAction() { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, - forwardButtonAction() { + async forwardButtonAction() { + // manually creating the array for now, will revise once service returns questions + const questionAnswersArray = []; + + questionAnswersArray.push( + { + questionNum: 1, + questionText: this.schoolPropertyQuestionText, + selectedAnswer: this.schoolPropertyAnswer + }, + { + questionNum: 2, + questionText: this.parkingLotQuestionText, + selectedAnswer: this.parkingLotAnswer + } + ); + + // save answers to store as order.policy.endorsementQuestionAnswers + await this.mainStore.saveEndorsementQuestionAnswers(questionAnswersArray); + return this.navigateForward(); }, navigateForward() { From e1cf8e9d6317bd86707c937ca719d3de069d8952 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Mon, 11 Sep 2023 16:36:44 -0400 Subject: [PATCH 12/32] endorsements page styling WIP --- .../endorsements-page/endorsements-page.vue | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 7b7f1977..510fda8b 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -7,11 +7,11 @@
- -
+ +
- + @backClicked="backButtonAction" + class="pt-5" />
@@ -149,22 +150,29 @@ export default { From edd5d4fc4ee284dbf52e3cbbc241572893f8a186 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Tue, 12 Sep 2023 14:58:34 -0400 Subject: [PATCH 13/32] linting --- .../endorsements-page/endorsements-page.vue | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index 510fda8b..de2ee33b 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -7,7 +7,9 @@
- +
+ @backClicked="backButtonAction" />
@@ -51,8 +53,6 @@ import siteHeader from '@/iss-components/site-header/site-header.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue'; -import questionsPageLayout from '@/iss-components/questions-page-layout/questions-page-layout.vue'; -import questionChain from '@/digital-components/question-chain/question-chain.vue'; // Supporting files import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; @@ -69,8 +69,6 @@ export default { siteSubHeader, siteFooter, buttonQuestion, - questionsPageLayout, - questionChain, // eslint-disable-next-line vue/no-reserved-component-names Form }, @@ -98,7 +96,7 @@ export default { rules: { selectionRequired: globalRules.OPTION_REQUIRED } - } + }; }, computed: { schoolPropertyQuestionText() { @@ -112,7 +110,7 @@ export default { }, parkingLotAnswersFromCms() { return this.getCmsContent('ParkingLotQuestion', 'Answers'); - }, + } }, methods: { @@ -122,9 +120,9 @@ export default { async forwardButtonAction() { // manually creating the array for now, will revise once service returns questions const questionAnswersArray = []; - + questionAnswersArray.push( - { + { questionNum: 1, questionText: this.schoolPropertyQuestionText, selectedAnswer: this.schoolPropertyAnswer @@ -135,15 +133,17 @@ export default { selectedAnswer: this.parkingLotAnswer } ); - + // save answers to store as order.policy.endorsementQuestionAnswers - await this.mainStore.saveEndorsementQuestionAnswers(questionAnswersArray); + await useMainStore().saveEndorsementQuestionAnswers(questionAnswersArray); return this.navigateForward(); }, navigateForward() { - this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, - this.$route); + this.$router.navigate( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); } } }; @@ -174,5 +174,4 @@ export default { margin-top: 1rem; } - From fc8ec1745df61698285ab91e1c558228de04f13b Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Tue, 12 Sep 2023 16:29:25 -0400 Subject: [PATCH 14/32] endorsements page unit tests so far --- .../endorsements-page.spec.js | 111 ++++++++++++++++++ .../endorsements-page/endorsements-page.vue | 10 +- 2 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 src/layouts/endorsements-page/endorsements-page.spec.js diff --git a/src/layouts/endorsements-page/endorsements-page.spec.js b/src/layouts/endorsements-page/endorsements-page.spec.js new file mode 100644 index 00000000..119bba29 --- /dev/null +++ b/src/layouts/endorsements-page/endorsements-page.spec.js @@ -0,0 +1,111 @@ +// Components +import endorsementsPage from '@/layouts/endorsements-page/endorsements-page.vue'; + +// Supporting Files +import { shallowMount } from '@vue/test-utils'; +import { getMountOptions } from '@/helpers/unit-test-helper.js'; +import navigationScenarios from '@/router/router-constants/navigation-scenarios'; +import { createTestingPinia } from '@pinia/testing'; +import { getRandomString, getRandomInt } from '@/helpers/data-generation.js'; +import { useMainStore } from '@/store'; + +// import { useMainStore } from '@/store/index.js'; + +describe('endorsementsPage.vue', () => { + describe('Rendering', () => { + test('Should render site header', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions()); + + // Act + const siteHeader = wrapper.findComponent({ ref: 'siteHeader' }); + + // Assert + expect(siteHeader.exists()).toBe(true); + }); + test('Should render site subheader', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions()); + + // Act + const siteSubHeader = wrapper.findComponent({ ref: 'siteSubHeader' }); + + // Assert + expect(siteSubHeader.exists()).toBe(true); + }); + test('Should render buttonQuestion component', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions()); + + // Act + const buttonQuestion = wrapper.findComponent({ ref: 'endorsementQuestion' }); + + // Assert + expect(buttonQuestion.exists()).toBe(true); + }); + test('Should render site footer', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions()); + + // Act + const siteFooter = wrapper.findComponent({ ref: 'siteFooter' }); + + // Assert + expect(siteFooter.exists()).toBe(true); + }); + }); + describe('Navigation', () => { + test('Back button clicked triggers navigation', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions({ + router: { + navigate: jest.fn() + } + })); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, undefined); + }); + test('Forward button clicked triggers navigation', () => { + // Arrange + const wrapper = shallowMount(endorsementsPage, getMountOptions({ + router: { + navigate: jest.fn() + } + })); + + // Act + wrapper.vm.forwardButtonAction(); + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined); + }); + // *TO DO: once service is ready, revise this test to ensure data is saved to the store + test('Forward button clicked saves endorsement question answers', () => { + // Arrange + const mountOptions = getMountOptions({ + router: { + navigate: jest.fn() + }, + global: { + plugins: [createTestingPinia()] + } + }); + const wrapper = shallowMount(endorsementsPage, mountOptions); + + // Act + wrapper.vm.forwardButtonAction(); + + // Assert + expect(useMainStore().saveEndorsementQuestionAnswers).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/layouts/endorsements-page/endorsements-page.vue b/src/layouts/endorsements-page/endorsements-page.vue index de2ee33b..4b779dca 100644 --- a/src/layouts/endorsements-page/endorsements-page.vue +++ b/src/layouts/endorsements-page/endorsements-page.vue @@ -6,12 +6,16 @@ @invalidSubmit="onInvalidSubmit">
- +
@@ -135,7 +139,7 @@ export default { ); // save answers to store as order.policy.endorsementQuestionAnswers - await useMainStore().saveEndorsementQuestionAnswers(questionAnswersArray); + useMainStore().saveEndorsementQuestionAnswers(questionAnswersArray); return this.navigateForward(); }, From c90ef8b7c2b340da72e1a90c55c235c6c25cc153 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Tue, 12 Sep 2023 17:02:57 -0400 Subject: [PATCH 15/32] linting --- .../endorsements-page/endorsements-page.spec.js | 1 - src/layouts/policy-vehicles/policy-vehicles.vue | 11 +++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/layouts/endorsements-page/endorsements-page.spec.js b/src/layouts/endorsements-page/endorsements-page.spec.js index 119bba29..a7eaa593 100644 --- a/src/layouts/endorsements-page/endorsements-page.spec.js +++ b/src/layouts/endorsements-page/endorsements-page.spec.js @@ -6,7 +6,6 @@ import { shallowMount } from '@vue/test-utils'; import { getMountOptions } from '@/helpers/unit-test-helper.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios'; import { createTestingPinia } from '@pinia/testing'; -import { getRandomString, getRandomInt } from '@/helpers/data-generation.js'; import { useMainStore } from '@/store'; // import { useMainStore } from '@/store/index.js'; diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 54f19ce9..5287be82 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -200,12 +200,15 @@ export default { this.navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE, this.$route, {}, - {}); - } else if (!!this.endorsementsForSelectedVehicle) { - this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, + {} + ); + } else if (this.endorsementsForSelectedVehicle) { + this.$router.navigate( + this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, this.$route, {}, - {}); + {} + ); } else { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE, From 17ecf1ebec40ff374b13053b1757864fba8ff043 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 15:54:37 -0400 Subject: [PATCH 16/32] commit before stash --- .../service-location/service-location.vue | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 252741c1..b1fd6449 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -5,52 +5,45 @@ @submit="onSubmit" @invalidSubmit="onInvalidSubmit">
-
- - -
-
-
-
-
- - - -
- -
-
-
-
-
-
+ + +
+ + + + +
@@ -164,8 +157,18 @@ export default { } return this.isGlassServiceableMobile; }, + isServiceableInshop() { + if (this.isRecalibrationServiceableInshop !== null) { + return this.isGlassServiceableInshop && this.isRecalibrationServiceableInshop; + } + + return this.isGlassServiceableInshop; + }, displayMilitaryZipAlert() { return this.zipContainsMilitaryBase && this.isServiceableMobile; + }, + displayServiceableMobileOnly() { + return this.isServiceableMobile && !this.isServiceableInshop; } }, methods: { @@ -214,18 +217,16 @@ export default { diff --git a/src/helpers/cms-content-helper.js b/src/helpers/cms-content-helper.js index 861eacec..5120c4db 100644 --- a/src/helpers/cms-content-helper.js +++ b/src/helpers/cms-content-helper.js @@ -12,9 +12,11 @@ function processWidgetItemForReplacement(widgetModel, key) { // If we have a string, and it needs to be replaced. if (typeof widgetModel[key] === 'string') { if (widgetModel[key].includes('{if:')) { - widgetModel[key] = processIfStatements(widgetModel[key], + widgetModel[key] = processIfStatements( + widgetModel[key], dynamicStrings.GLOBAL_STATE, - getStoreValueFromString); + getStoreValueFromString + ); } if (widgetModel[key].includes(dynamicStrings.MODAL_LINK)) { @@ -158,14 +160,16 @@ export function fetchCmsContentForPage(issPage) { // Else get the client override page. const pageName = `${issPage}_${clientName.toLowerCase().replace(/ /g, '')}`; - return store.getPageData(pageName).then((clientResponse) => - // Process the client override if it exists. - processPageData(baseResponse, clientResponse), - (error) => { - console.error(error); - // Process the just the base if no client override exists. - return processPageData(baseResponse, null); - }); + return store.getPageData(pageName).then( + (clientResponse) => + // Process the client override if it exists. + processPageData(baseResponse, clientResponse), + (error) => { + console.error(error); + // Process the just the base if no client override exists. + return processPageData(baseResponse, null); + } + ); }) ); } @@ -179,8 +183,10 @@ function mapStringToModal(str) { let linkToReplace = str.substring(startIndex, str.length); linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf('}') + 1); - const params = linkToReplace.substring(dynamicStrings.MODAL_LINK.length + 2, - linkToReplace.length - 1); + const params = linkToReplace.substring( + dynamicStrings.MODAL_LINK.length + 2, + linkToReplace.length - 1 + ); const splitParams = params.split(','); const bodyText = `${splitParams[1]}`; @@ -202,8 +208,10 @@ function mapStringToLink(str) { let linkToReplace = str.substring(startIndex, str.length); linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf('}') + 1); - const params = linkToReplace.substring(dynamicStrings.EXTERNAL_LINK.length + 2, - linkToReplace.length - 1); + const params = linkToReplace.substring( + dynamicStrings.EXTERNAL_LINK.length + 2, + linkToReplace.length - 1 + ); const splitParams = params.split(','); const bodyText = `${splitParams[1]}`; @@ -291,13 +299,17 @@ export function processIfStatements(str, ifConditionKeyword, replacePlaceholderC } const ifStatementRegexExpression = getIfStatementRegexExpression(); const ifStatementRegexMatches = [...str.matchAll(ifStatementRegexExpression)]; - const completeIfStatementArray = getAndFlagFirstNonNestedIfStatementWithKeyword(ifStatementRegexMatches, - ifConditionKeyword); + const completeIfStatementArray = getAndFlagFirstNonNestedIfStatementWithKeyword( + ifStatementRegexMatches, + ifConditionKeyword + ); executeIfStatementAndSetProcessedStrings(completeIfStatementArray, replacePlaceholderCallback); const reconstructedPostProcessedString = joinProcessedRegexArray(ifStatementRegexMatches); - return processIfStatements(reconstructedPostProcessedString, + return processIfStatements( + reconstructedPostProcessedString, ifConditionKeyword, - replacePlaceholderCallback); + replacePlaceholderCallback + ); } /** @@ -419,26 +431,28 @@ function getIfStatementRegexExpression() { // {if:...} or {else} or {end} const anyLogicOperatorNonCapture = '(?:{(?:end|else|if:.*?)})'; // NOTE: ? syntax stores the captured match like so: match.groups.variableName - const matchStartOfString - = '(?^.+?)' // Match and Capture all characters (lazy), cannot be empty + const matchStartOfString = + '(?^.+?)' // Match and Capture all characters (lazy), cannot be empty + '(?=(?:{if))'; // Looks ahead but does not capture {if - const matchIfOperator - = '(?{if:)' // Match & Capture {if: + const matchIfOperator = + '(?{if:)' // Match & Capture {if: + '(?.*?):' // Match all chars up to and including next ':' - Capture all chars up to ':' + '(?.*?)}' // Match all chars up to and including next '}' - Capture all chars up to '}' + '(?.*?)' // Match and Capture all characters (lazy), can be empty + `(?=${anyLogicOperatorNonCapture})`; // Looks ahead but does not capture the next logic operator - const matchElseOperator - = '(?{else})' // Match & Capture {else} + const matchElseOperator = + '(?{else})' // Match & Capture {else} + '(?.*?)' // Match & Capture all characters (lazy), can be empty + `(?=${anyLogicOperatorNonCapture})`; // Looks ahead but does not capture the next logic operator - const matchEndOperator - = '(?{end})' // Match & Capture {end} + const matchEndOperator = + '(?{end})' // Match & Capture {end} + '(?.*?)' // Match & Capture all characters (lazy), can be empty + `(?=${anyLogicOperatorNonCapture}|$)`; // Looks ahead but does not capture the next logic operator // Combine all matching patterns, separated by 'or' pipes - return new RegExp(`${matchStartOfString}|${matchIfOperator}|${matchElseOperator}|${matchEndOperator}`, - 'g'); + return new RegExp( + `${matchStartOfString}|${matchIfOperator}|${matchElseOperator}|${matchEndOperator}`, + 'g' + ); } /// /////////////////////////////////////// @@ -501,6 +515,16 @@ export function splitCopyOnCMSPlaceHolder(copy) { return copy.split(/{(.*?)}/g); } +export function getExternalLink(copy) { + const url = copy.split(':')[1].split(',')[0]; + if (url.includes('https-')) { + const prefixAdded = url.replace('https-', 'https://'); + return prefixAdded; + } + + return '#!'; +} + /** * Returns string2 of input following this pattern: {string1:string2,string3} * @param copy diff --git a/src/helpers/object-helper.js b/src/helpers/object-helper.js new file mode 100644 index 00000000..5c1cafd6 --- /dev/null +++ b/src/helpers/object-helper.js @@ -0,0 +1,80 @@ +// For nested objects, spread operator only creates new references to the top level fields, +// the remaining nested fields actually reference the original object which can introduce problems. + +// The purpose of this method is to deep clone the data in an object recursively, this is useful +// for cloning modelValues to internal models when regular two-way binding is not an option. +// See: mobile-location-modal-questions.vue + +// Creates a deep clone of an object. Clones primitives, arrays and objects, excluding class instances. +// https://www.30secondsofcode.org/js/s/deep-clone +export function deepClone(object) { + if (object === null) { + return null; + } + + const clone = { ...object }; + // eslint-disable-next-line no-return-assign + Object.keys(clone).forEach((key) => + (clone[key] = typeof object[key] === 'object' ? deepClone(object[key]) : object[key])); + + if (Array.isArray(object)) { + clone.length = object.length; + return Array.from(clone); + } + + return clone; +} + +// The purpose of this method is to check for array or object equality recursively to determine if two complex objects are equal. +// This is only a comparison of data, not functions. +export function deepEqual(obj1, obj2) { + if (typeof obj1 !== typeof obj2) { + return false; + } + + if (obj1 === null || obj2 === null) { + return obj1 === obj2; + } + + if (Array.isArray(obj1) && Array.isArray(obj2)) { + if (obj1.length !== obj2.length) { + return false; + } + + const sorted1 = obj1.slice().sort(); + const sorted2 = obj2.slice().sort(); + + for (let i = 0; i < sorted1.length; i++) { + if (!deepEqual(sorted1[i], sorted2[i])) { + return false; + } + } + + return true; + } + + if (typeof obj1 === 'object' && typeof obj2 === 'object') { + const keys1 = Object.keys(obj1); + const keys2 = Object.keys(obj2); + + if (keys1.length !== keys2.length) { + return false; + } + + const sortedKeys1 = keys1.sort(); + const sortedKeys2 = keys2.sort(); + + for (let i = 0; i < sortedKeys1.length; i++) { + const key1 = sortedKeys1[i]; + const key2 = sortedKeys2[i]; + + if (key1 !== key2 || !deepEqual(obj1[key1], obj2[key2])) { + return false; + } + } + + return true; + } + + return obj1 === obj2; +} diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 242752d3..a8ac5503 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -1,16 +1,5 @@ import { useMainStore } from '@/store'; -export async function getServiceabilityDetails(serviceZipCode, lineItems) { - const serviceabilityDetails = await useMainStore().getServiceabilityDetails( - { - serviceZipCode, - lineItems - }, - false - ); - return Promise.resolve(serviceabilityDetails); -} - export async function getZipCodeData(zipCode) { const serviceZipValidationResponse = await useMainStore().validateZip({ zip: zipCode }); @@ -22,3 +11,57 @@ export async function getZipCodeData(zipCode) { zipCodeCtu: serviceZipValidationResponse.data.zipCodeCtu }; } + +export async function getPricedMobileFeePart(serviceZipCode) { + if (!serviceZipCode) { + return Promise.resolve(null); + } + const zipCodeData = await getZipCodeData(serviceZipCode); + + // Get the Mobile Fee Part + const mobileFeePart = await useMainStore().getMobileFeePart(); + + // Get the Mobile Fee Part Price + const pricingResults = await useMainStore() + .priceOrderItemsAndSaveServerData([mobileFeePart.data], serviceZipCode, zipCodeData.zipCodeCtu); + + return Promise.resolve(pricingResults[0]); +} + +export async function getServiceabilityDetails(serviceZipCode, lineItems) { + const serviceabilityDetails = await useMainStore().getServiceabilityDetails( + { + serviceZipCode, + lineItems + }, + false + ); + return Promise.resolve(serviceabilityDetails); +} + +export async function getAvailabilityRating( + startDate, + endDate, + shopAppointmentType, + providerNumber +) { + // For a given shop provider number and date range, get the appointment time slots available + const shopTimeSlots = await useMainStore().getShopTimeSlots( + { + providerNumber, + startDate, + endDate, + shopAppointmentType + }, + false + ); + + const numberOfDaysToEvaluate = 2; + const isGoodAvailability = + shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length + >= numberOfDaysToEvaluate; + + const shopStatus = isGoodAvailability ? 'high' : 'low'; + + return Promise.resolve(shopStatus); +} diff --git a/src/iss-components/site-footer/site-footer.vue b/src/iss-components/site-footer/site-footer.vue index f83d8372..2c4a4cb0 100644 --- a/src/iss-components/site-footer/site-footer.vue +++ b/src/iss-components/site-footer/site-footer.vue @@ -2,7 +2,7 @@