From c821fc7d83a9738c1e326256a4524bb841c2fc90 Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Mon, 16 Feb 2026 17:11:56 -0500 Subject: [PATCH 01/48] INSR-7759: Some payment-method parity updates - Payment method question button now matches Heritage - Recalibration is now its own line item - Some other general updates to structure and formatting of page --- .../icons/chevron-circle_review_dropdown.png | Bin 0 -> 1973 bytes src/constants/progress-bar-mapper.js | 5 +- src/helpers/cart-helper.js | 15 +++ .../cart-dropdown/cart-dropdown.vue | 109 ++++++++++-------- .../payment-method-list-button.vue | 82 +++++-------- .../payment-method-question.vue | 3 +- src/layouts/payment-method/payment-method.vue | 74 +++++++++--- .../review-dropdown/review-dropdown.vue | 23 ++-- 8 files changed, 174 insertions(+), 137 deletions(-) create mode 100644 src/assets/img/icons/chevron-circle_review_dropdown.png diff --git a/src/assets/img/icons/chevron-circle_review_dropdown.png b/src/assets/img/icons/chevron-circle_review_dropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..c2360997b00dfc6b1964e4222e666b6b215a7418 GIT binary patch literal 1973 zcmV;m2TJ&fP)Px+Z%IT!RA>d|TU%@tRTw_!>~blw5J+gt#XyLGC^0-}Vl=ftOi%~}>4LFJg24yE zgTCM;5n3l(AO=OFi7|Lds1G&*+lo*wAy`3_kf<-j5E5Q|0Je*$<+c=N=Jo8JSQFKH`oRU$MVrO|q=tBx7+B?`Wo3_l?y8ym(x=j@JT z>d{Z+19FsEc}m$k&n(01|_ z%L3fcmRf9@EXkN`EH{u~_4z3g7p-Y+)sMmS-CCgl&)Sxnb~`I~(y(iBo2)#Cg6B5)WZ*ba%kMO%&lEycwH&R@1t(V#JUL^F1)^Mz|W^I;D+sorpjz~zm)Px zKV#LDbIwomnwpjAca~i#7Dv$`jh-C|U;z*vf>;rAXuuf8!@Xzi;1Fy6)w8o5(hhTSh67-L~$~_NX|^bW6QlhSuVg>RAjUA93dDEpPq6W zvcIN=KddfJTs?>t)F=RphMJVe;%GES4>xGti%i|?Q3sG51YE#KEm<2 z!dEdB05`ODExdob9#>oyWXQ%Gww#LsV9CrkD(JPUrtR3QcNm!pX~>I_Z{Dj4)8-sW zgczTJ%t@|?DJ?Tm~R#IBkcLT20^`l`Ew&6q7^@>H+vD3gRXl&23 zGyTfaGVhAr5HZPf;1Fs1pq$}dI(tDqJv4KR}rngi^I z8Cq(lYCN4x^hnNMWb_$OWhK*O1GZpOtqb3Xfo5M<463f323BDmf7rPJ%Cym*bJt+U zXKOtTs(L1w=%$`oOMF9>l|UP?0b6Pv_=Io7pvrt{I_eSDS&y%#hk}%Ivqttfa$c&m zFPZpOaIu~m(^O@?w6&KN>tRFHg)jJ|o}H`80?~A?MLnE9*a}p`sYEm1BW5;xY^HW( zic`WEO)_885Zb`VfhrrC<`Q*KSJiZVTZ(ch*U+Z-(KGMnNPpOyv zHzu5I%IP|Tflb(k52qvqMOZOul?@oKkukiY|J{>27j_1d*_zl%OTx`g?mY^!O#A8& z?{RV^*n&;iR%M}R!iq^N9jdZtCD}yF)bD3&z2j9e4b|;5WL*gcn%t6*srs-1Thx?I zsw^~3Sh4UpAKHLNMVeHexn*4Kny>xgIt-_8Y8!o{cND5onI@=r3v|AKy08ITs;nFu zSh4Vk6tESLWJ~`t&h1&G^|}tnGwq4Dxey=Y4`meq>Yy%-yrrtFTpCzux758v*Nvm) z8uO}8@8;g7N1I#rzQ6-5Le}h&v6E-JI_aHV<7KaGo)AmuvlKrS<@(ni6aqhaHnm&R zr0?esI?$~YSYX6u8G+j}H07VM2O4FW-ov$@8L2M_2<`H`AINe#){@j)sZ1^~0;|>X zG`73Sv{$q`fnHzV+C|@E?*}sIcuS+<4r0s=HM$xU$quJzY;t3LYw9CaCC8H+Req#2 zc5lE)PhptVx9&SYt-L%^M;^wgrN0^*kGDZ|N7s||sd&{xEm9V}zX$u;SFeE4!eoMb zP?35W!WaM!=yxyT?|y)_K-#bsdKdyaSN&=9oj&kWw6raxr3yW4wS-{SP(yjNJh;ea z$Kn7?OTS*~@=m+LNG=15{p1i>9Du>V4LADNkManA`tw*EFkFCfVvZYbq0%!B(^Vvp zCL#>#=|3WJ0S42$8zK2yD38d8V)we=0W6MLS_N0PW#4Y%tyB5KobJeMUH!^XF?#m! zpfaxW(T?ZzAU)jwBUZ#*EY6~Uad#2d`9=b0#E4k^?pqcGjF!UP#oDPgi>cUAtmUdK z>p+Zt_bd@((RWw{Vcl@!atCE2d>cxwTM-(Gewv_=Bn)c5B)~BGzq%j}z?klF!;M<1 zYAZ7MMhruJdJyMOPsu%OH item.requiresRecalibration); + const recalibrationLineItems = itemsWithRecalibration.map((item) => { + return item.childParts?.find((child) => child.partType === partTypeStrings.RECALIBRATION || child.partType === partTypeStrings.ADAS_RECALIBRATION) ?? {}; + }); + + return getPriceOfLineItems(recalibrationLineItems); +} diff --git a/src/iss-components/cart-dropdown/cart-dropdown.vue b/src/iss-components/cart-dropdown/cart-dropdown.vue index fa106ffe..fe3183b9 100644 --- a/src/iss-components/cart-dropdown/cart-dropdown.vue +++ b/src/iss-components/cart-dropdown/cart-dropdown.vue @@ -1,20 +1,30 @@ @@ -128,6 +128,7 @@ import { getCartTotal, getDeductible, getLineItems, getMobileFeeLineItem, + getRecalibrationTotal, getRecycleFeeLineItem, getSalesTax, getServiceLineItems, getSubtotal, isOrderITAC, isOrderNoComp, isOrderUnverified @@ -136,7 +137,6 @@ import { getPriceOfLineItems, getTaxOfLineItems } from '@/helpers/price-calculat import { processIfStatements } from '@/helpers/cms-content-helper'; const VERIFYING_COVERAGE = 'Verifying coverage'; -const RECYCLING_MODAL_REF_NAME = 'RecycleModal'; export default { name: 'confirmation-cart', @@ -148,7 +148,6 @@ export default { props: { readOnly: Boolean, showAsPaid: Boolean, - recyclingModalCmsWidgetName: String, submittedOrder: Object }, data() { @@ -158,6 +157,7 @@ export default { amountPaid: 'AmountPaidTextWidget', deductible: 'DeductibleWidget', basePrice: 'BasePriceWidget', + recalibration: 'RecalibrationWidget', subtotal: 'SubtotalWidget', salesTax: 'SalesTaxWidget', recycleFee: 'RecycleFeeWidget', @@ -167,8 +167,7 @@ export default { warrantyText: 'WarrantyCartItemTextWidget', guaranteeText: 'GuaranteeCartItemTextWidget' }, - cartItemType, - RECYCLING_MODAL_REF_NAME + cartItemType }; }, computed: { @@ -181,9 +180,18 @@ export default { deductible() { return getDeductible(this.cartOrder); }, + isDeductibleOnly() { + return this.deductible > 0 && this.subTotal === this.deductible; + }, showDeductibleCartItem() { return this.isUnverified || (!this.isNoComp && !this.isITAC); }, + showRecalibrationCartItem() { + return this.recalibrationPrice > 0; + }, + recalibrationPrice() { + return getRecalibrationTotal(this.cartOrder); + }, lineItems() { return getLineItems(this.cartOrder); }, @@ -191,7 +199,8 @@ export default { return getRecycleFeeLineItem(this.cartOrder); }, servicePrice() { - return getPriceOfLineItems(getServiceLineItems(this.cartOrder)) ?? 0; + const price = getPriceOfLineItems(getServiceLineItems(this.cartOrder)) ?? 0; + return price - this.recalibrationPrice; }, isUnverified() { return isOrderUnverified(this.cartOrder); @@ -327,6 +336,9 @@ export default { this.getCustomValueFromString ); }, + recalibrationLabel() { + return this.getCmsContent(this.widget.recalibration, widgetFields.TEXT_BLOCK_WIDGET.TEXT); + }, subtotalLabel() { return this.getCmsContent(this.widget.subtotal, widgetFields.TEXT_BLOCK_WIDGET.TEXT); }, @@ -452,8 +464,6 @@ export default { diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue index 0f834cbc..c3601cbf 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue @@ -2,32 +2,30 @@ -
+ buttonWrapperClasses="list-group base-input-button list-button d-flex flex-column w-100 no-hover"> +
+
+ + + + {{ getInlineAltText(token) }} + + + {{ token }} + + +
-
-

- - - - {{ getInlineAltText(token) }} - - - {{ token }} - - -

-
@@ -78,48 +76,26 @@ export default { outline: none; input[type="radio"], input[type="checkbox"] { - position: static; //override bootstrap - - &:focus-visible + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } - &:focus + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } &:checked + .list-button-content { + background: $background-color-selected; + border-color: $heritage-blue-primary; + font-weight: 600; color: $black; - font-weight: 500; - background: $blue-100; - box-shadow: 0 0 0 1px $blue; - } - &:checked:focus + .list-button-content { - box-shadow: 0 0 0 2.5px $blue; - } - &:checked + .list-button-content p, - &:checked + .list-button-content span { - font-weight: 500; - } - &:checked + .list-button-content span:nth-child(2) { - font-weight: 400; - color: $gray-600; } } } .list-button-content { - color: $gray-600; + color: $darker-gray; + font-weight: 400; position: relative; background: $white; transition: all 150ms linear; - border-radius: $border-radius-lg; - border: 1px solid $gray-500; + border-radius: 3.75rem; + border: 1px solid #CACBCC; width: 100%; outline: none; - - span { - &.small { - font-size: $font-size-xsm; - color: $gray-550; - } - } + padding: .625rem 2rem; + height: 2.875rem; + margin-bottom: .75rem; } diff --git a/src/layouts/payment-method/payment-method-question/payment-method-question.vue b/src/layouts/payment-method/payment-method-question/payment-method-question.vue index d8376879..33d82adf 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-question.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-question.vue @@ -19,6 +19,7 @@ import buttonQuestion from '@/digital-components/button-question/button-question.vue'; import widgetFields from '@/constants/cms-widget-fields.js'; import paymentMethodListButton from './payment-method-list-button/payment-method-list-button.vue'; +import { markRaw } from 'vue'; export default { name: 'payment-method-question', @@ -33,7 +34,7 @@ export default { emits: ['update:modelValue'], data() { return { - paymentMethodListButton + paymentMethodListButton: markRaw(paymentMethodListButton) }; }, computed: { diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index ba1f761b..8b675e33 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -12,21 +12,24 @@
+ + class="subheader" + cmsWidgetName="SiteSubHeaderWidget" />
-
+
-
+
+ -
+
$page-side-padding: 1.5rem; -.iss-heritage-container-width { +#app .iss-heritage-container-width { + .iss-heritage-content-container-width { + @include media-breakpoint-up(md) { + width: 58.33333333%; + } + } .payment-method-container { position: relative; min-height: 1px; padding-left: .9375rem; padding-right: .9375rem; + + .alert-warning { + margin-top: 1.25rem; + margin-bottom: 0rem; + } + + .subheader { + margin-top: 1.25rem; + + :deep(strong) { + color: $black; + font-weight: 600; + } + + :deep(.subheader-secondary) { + margin-top: .625rem; + + p { + margin-bottom: 0; + } + } + } + + .section-divider { + margin-top: 1.5rem; + margin-bottom: 1.875rem; + } + + .pia-divider { + margin-top: .5rem; + margin-bottom: .75rem; + } } } - -.main-content-container { - padding: 0; -} - -.page-container-grouped-styles { - overflow: auto; -} diff --git a/src/layouts/payment-method/review-dropdown/review-dropdown.vue b/src/layouts/payment-method/review-dropdown/review-dropdown.vue index d1504da4..d48b55f3 100644 --- a/src/layouts/payment-method/review-dropdown/review-dropdown.vue +++ b/src/layouts/payment-method/review-dropdown/review-dropdown.vue @@ -1,7 +1,7 @@ + + \ No newline at end of file diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index c1c7abbd..1d46973c 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -69,6 +69,10 @@ class="d-flex justify-content-center cost mb-0 cost-underline"> {{ formatAmountInDollars(totalServicePrice) }}
+ 0; } }, watch: { From c7b9137975eaf3b5b09134c6223ead76c7e4a948 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Wed, 18 Feb 2026 14:50:35 -0600 Subject: [PATCH 16/48] Initial work on moving components to the new bailout system. --- src/global-methods.spec.js | 24 ++- src/helpers/order-helper.js | 13 +- .../capability-questions.vue | 3 +- .../coverage-statement.spec.js | 19 +- .../coverage-statement/coverage-statement.vue | 17 +- .../duplicate-check/duplicate-check.spec.js | 8 +- .../duplicate-check/duplicate-check.vue | 16 +- src/layouts/entry-page/entry-page.vue | 54 +++--- .../molding-questions/molding-questions.vue | 3 +- src/layouts/part-questions/part-questions.vue | 3 +- src/layouts/payment-method/payment-method.vue | 23 +-- src/layouts/payment-return/payment-return.vue | 8 +- .../policy-vehicles/policy-vehicles.spec.js | 23 +-- .../policy-vehicles/policy-vehicles.vue | 51 ++--- .../provider-preference.spec.js | 7 +- .../provider-preference.vue | 4 +- src/layouts/tpa-search/tpa-search.spec.js | 11 +- src/layouts/tpa-search/tpa-search.vue | 6 +- src/layouts/tpa-submit/tpa-submit.vue | 16 +- .../vehicle-damage/vehicle-damage.spec.js | 20 +- src/layouts/vehicle-damage/vehicle-damage.vue | 22 +-- src/layouts/vehicle-lookup/vehicle-lookup.vue | 19 +- src/layouts/vehicle-parts/vehicle-parts.vue | 4 +- .../vehicle-selection/vehicle-selection.vue | 62 +----- src/layouts/vin-lookup/vin-lookup.spec.js | 42 +---- src/layouts/vin-lookup/vin-lookup.vue | 88 ++++----- src/layouts/welcome-page/welcome-page.spec.js | 13 +- src/layouts/welcome-page/welcome-page.vue | 72 +++---- src/mixins/vehicle-questions-mixin.js | 11 +- src/router/index.js | 176 +++++++++--------- .../router-constants/navigation-scenarios.js | 7 - src/router/router-constants/routing-table.js | 68 ------- src/router/router.spec.js | 13 +- src/store/index.js | 148 ++++++--------- 34 files changed, 374 insertions(+), 700 deletions(-) diff --git a/src/global-methods.spec.js b/src/global-methods.spec.js index fbb084ff..e5e82e45 100644 --- a/src/global-methods.spec.js +++ b/src/global-methods.spec.js @@ -21,7 +21,8 @@ global.$logger = { function setupMocksForHttpClient({ endpoint = null, isError = false, - additionalData = null + additionalData = null, + bailoutOnError = false }) { // Clear node module axios.mockClear(); @@ -57,7 +58,8 @@ function setupMocksForHttpClient({ return { endpoint, - logApiCall: true + logApiCall: true, + bailoutOnError }; } @@ -92,3 +94,21 @@ it('Global Methods - Call Http Client - Should Reject Promise', () => { expect(err.status).toEqual(500); }); }); + +it('Global Methods - Call Http Client - Rejected Promised - bailoutOnError: true - Calls global.bailoutOnAxiosError', () => { + // Arrange + const endpoint = 'https://mock.safelite.com'; + const httpArgs = setupMocksForHttpClient({ + endpoint, + isError: true, + bailoutOnError: true + }); + analyticsMixIn.methods.pushEventToGA = jest.fn(); + global.bailoutOnAxiosError = jest.fn(); + + // Act + globalMethods.callHttpClient(httpArgs).catch((err) => { + // Assert + expect(global.bailoutOnAxiosError).toHaveBeenCalledTimes(1); + }); +}); \ No newline at end of file diff --git a/src/helpers/order-helper.js b/src/helpers/order-helper.js index f1ab7c72..cbc5c890 100644 --- a/src/helpers/order-helper.js +++ b/src/helpers/order-helper.js @@ -4,8 +4,8 @@ import submitType from '@/constants/submit-type'; /* Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing */ -async function saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA }) { - const savedSessionInfo = await store.saveSession({ submitAfterSave, createWorkOrderNumberForPIA }); +async function saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError }) { + const savedSessionInfo = await store.saveSession({ submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError }); if (savedSessionInfo) { store.setSaveSessionInfo(savedSessionInfo.data); } @@ -16,11 +16,11 @@ async function saveSessionHelper(store, { submitAfterSave, createWorkOrderNumber This will also set Referral information in the store after saving, and then update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue */ -export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitAfterSave = false, createWorkOrderNumberForPIA = false }) { +export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitAfterSave = false, createWorkOrderNumberForPIA = false, bailoutOnError = false }) { const store = useMainStore(); const saveSessionPromise = store.applicationUser.saveSessionPromise - ? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA })) - : saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA }); + ? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError })) + : saveSessionHelper(store, { submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError }); store.setSaveSessionPromise(saveSessionPromise); @@ -38,7 +38,8 @@ export async function submitWorkOrder({ submitType }) { store.resetSubmittedOrder(); await saveSession({ shouldAwaitSaveSessionQueue: true, - submitAfterSave: true + submitAfterSave: true, + bailoutOnError: true }); await store.createSubmittedOrder(submitType); } diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index c322a54b..e6dfd7bf 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -157,8 +157,7 @@ export default { this.navigateForward(this.partsOrQuestionsData, null); }, requestCallbackBailout() { - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.$router.navigate(navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, this.$route); + this.$router.navigateBailout(bailoutMessage.RequestCallback()); } } }; diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index aa9c3058..9711a10b 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -63,7 +63,8 @@ const loadingModalStub = { function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) { const mountOptions = getMountOptions({ router: { - navigate: jest.fn() + navigate: jest.fn(), + navigateBailout: jest.fn() } }); @@ -578,7 +579,7 @@ describe('coverageStatement.vue', () => { undefined ); }); - test('If Verified ITAC, selected Cancel, navigate forward w/ CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP', () => { + test('If Verified ITAC, selected Cancel, navigateBailout', () => { // Arrange const deductible = servicePrice + 1; const mainInitialState = { @@ -604,11 +605,7 @@ describe('coverageStatement.vue', () => { wrapper.vm.cancelClaim(); // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - undefined - ); + expect(wrapper.vm.$router.navigateBailout).toHaveBeenCalled() }); test('If No Comp and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => { // Arrange @@ -641,7 +638,7 @@ describe('coverageStatement.vue', () => { undefined ); }); - test('If No comp and selected other shop, navigate forward with CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP ', () => { + test('If No comp and selected other shop, navigateBailout ', () => { // Arrange const mainInitialState = { order: { @@ -666,11 +663,7 @@ describe('coverageStatement.vue', () => { wrapper.vm.cancelClaim(); // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - undefined - ); + expect(wrapper.vm.$router.navigateBailout).toHaveBeenCalled() }); }); describe('openCancelClaimModal', () => { diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index c1c7abbd..5a42a997 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -381,17 +381,6 @@ export default { // We only call the ITAC pricing endpoint if we are not repair or we are NoComp if (!this.isRepair || this.mainStore.isNoComp) { const pricingResults = await useMainStore().getITACPriceOrderItems(availableLineItems) - .catch((err) => { - useMainStore().setBailout(bailoutMessage.pricingResponseError( - availableLineItems.map((li) => li.partNumber), - { - code: err.code, - message: err.message, - data: err.data - } - )); - this.navigateWithScenario(navigationScenarios.PRICING_LOOKUP_ERROR); - }); this.setBaseServiceLineItems(pricingResults); } }, @@ -402,8 +391,7 @@ export default { this.mainStore.updateIsSafeliteProvider(true); this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE); } else { - this.mainStore.setBailout(bailoutMessage.coverageStatementInvalidState()); - this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE); + this.$router.navigateBailout(bailoutMessage.coverageStatementInvalidState()) } }, navigateWithScenario(scenario) { @@ -457,8 +445,7 @@ export default { }, cancelClaim() { this.mainStore.updateIsSafeliteProvider(false); - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP); + this.$router.navigateBailout(bailoutMessage.RequestCallback()) } } }; diff --git a/src/layouts/duplicate-check/duplicate-check.spec.js b/src/layouts/duplicate-check/duplicate-check.spec.js index 10be35e2..95346c26 100644 --- a/src/layouts/duplicate-check/duplicate-check.spec.js +++ b/src/layouts/duplicate-check/duplicate-check.spec.js @@ -357,11 +357,15 @@ describe('duplicateCheck.vue', () => { useMainStore().loadSession = jest.fn().mockImplementation(() => Promise.reject(error)); // Act - await wrapper.vm.forwardButtonAction(); // Assert + expect.assertions(2); + try { + await wrapper.vm.forwardButtonAction(); + } catch (e) { + expect(e).toMatch(error); + } expect(wrapper.vm.mainStore.loadSession).toHaveBeenCalledTimes(1); - expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1); }); test('coverageType deductible and policy vehicles returned => CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES', async () => { // Arrange diff --git a/src/layouts/duplicate-check/duplicate-check.vue b/src/layouts/duplicate-check/duplicate-check.vue index 1cac5a1e..3c4ead5f 100644 --- a/src/layouts/duplicate-check/duplicate-check.vue +++ b/src/layouts/duplicate-check/duplicate-check.vue @@ -140,18 +140,14 @@ export default { return; } - try { - const selectedReferral = - this.mainStore.applicationUser.duplicateOrders.find((o) => o.correlationId === this.selectedAnswer); + const selectedReferral = + this.mainStore.applicationUser.duplicateOrders.find((o) => o.correlationId === this.selectedAnswer); - if (selectedReferral) { - await this.mainStore.loadSession(selectedReferral); - } - } catch (err) { - console.error(`Error on loading session from duplicate check ${err}`); - } finally { - this.navigateForward(); + if (selectedReferral) { + await this.mainStore.loadSession(selectedReferral); } + + this.navigateForward(); }, navigateForward() { this.mainStore.updateDuplicateCheckVisited(true); diff --git a/src/layouts/entry-page/entry-page.vue b/src/layouts/entry-page/entry-page.vue index e9880117..9893f024 100644 --- a/src/layouts/entry-page/entry-page.vue +++ b/src/layouts/entry-page/entry-page.vue @@ -151,37 +151,33 @@ export default { this.mainStore.issConfig.isCoverageEnabled = data.coverageEnabled; this.mainStore.issConfig.siteType = data.siteType; - try { - if (data.clientFlags) { - const clientFlags = JSON.parse(data.clientFlags); + if (data.clientFlags) { + const clientFlags = JSON.parse(data.clientFlags); - if (clientFlags.TPAEnabled) { - this.mainStore.issConfig.enableTPAFlow = true; - } - - if (clientFlags.ClientFullName != null) { - this.mainStore.issConfig.clientFullName = clientFlags.ClientFullName; - } - - if (clientFlags.ClientDisplayName != null) { - this.mainStore.issConfig.clientDisplayName = clientFlags.ClientDisplayName; - this.mainStore.issConfig.clientPossessiveName = toPossessive(clientFlags.ClientDisplayName); - } - - if (clientFlags.ClientPossessiveName != null) { - this.mainStore.issConfig.clientPossessiveName = clientFlags.ClientPossessiveName; - } - - if (clientFlags.ClaimRegistrationRequired) { - this.mainStore.issConfig.isClaimRegistrationRequired = true; - } - - if (clientFlags.EnableNoCompQuote) { - this.mainStore.issConfig.enableNoCompQuote = true; - } + if (clientFlags.TPAEnabled) { + this.mainStore.issConfig.enableTPAFlow = true; + } + + if (clientFlags.ClientFullName != null) { + this.mainStore.issConfig.clientFullName = clientFlags.ClientFullName; + } + + if (clientFlags.ClientDisplayName != null) { + this.mainStore.issConfig.clientDisplayName = clientFlags.ClientDisplayName; + this.mainStore.issConfig.clientPossessiveName = toPossessive(clientFlags.ClientDisplayName); + } + + if (clientFlags.ClientPossessiveName != null) { + this.mainStore.issConfig.clientPossessiveName = clientFlags.ClientPossessiveName; + } + + if (clientFlags.ClaimRegistrationRequired) { + this.mainStore.issConfig.isClaimRegistrationRequired = true; + } + + if (clientFlags.EnableNoCompQuote) { + this.mainStore.issConfig.enableNoCompQuote = true; } - } catch (e) { - console.error(`Error parsing client flags: ${e}`); } }, combineClientParameters(configParams, queryStringParams) { diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index cb0f4f04..44d6af81 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -148,8 +148,7 @@ export default { this.navigateForward(partsOrQuestions, null); }, requestCallbackBailout() { - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.$router.navigate(navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, this.$route); + this.$router.navigateBailout(bailoutMessage.RequestCallback()); } } }; diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 1230016a..9bed6345 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -148,8 +148,7 @@ export default { this.navigateForward(glassPartsForStore, null); }, requestCallbackBailout() { - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.$router.navigate(navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, this.$route); + this.$router.navigateBailout(bailoutMessage.RequestCallback()); } }, }; diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index ba1f761b..676af3ef 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -260,25 +260,16 @@ export default { async forwardButtonAction() { useMainStore().savePaymentMethodChoice(this.paymentMethod); if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) { - try { - await submitWorkOrder({ submitType: submitType.SAFELITE }); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD, - this.$route - ); - } catch (error) { - useMainStore().setBailout(bailoutMessage.saveSessionError(error.data)); - this.$router.navigate( - this.navigationScenarios.SAVE_SESSION_FAILED, - this.$route, - { issPage: issPageValues.PAYMENT_METHOD } - ); - console.error(`error: response from submit work order:${error.message}`); - } + await submitWorkOrder({ submitType: submitType.SAFELITE }); + this.$router.navigate( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); } else { await saveSession({ createWorkOrderNumberForPIA: true, - shouldAwaitSaveSessionQueue: true + shouldAwaitSaveSessionQueue: true, + bailoutOnError: true }); this.$router.navigate( diff --git a/src/layouts/payment-return/payment-return.vue b/src/layouts/payment-return/payment-return.vue index 09860d17..d4ba19a4 100644 --- a/src/layouts/payment-return/payment-return.vue +++ b/src/layouts/payment-return/payment-return.vue @@ -124,13 +124,7 @@ export default { }, async saveAndSubmitWorkOrder() { // Final work order submit after returning from pay in advance. - try { - await submitWorkOrder({ submitType: submitType.SAFELITE }); - } catch (error) { - console.error(`error: response from submit work order:${error.message}`); - this.navigateOnPayInAdvanceError(); - return; - } + await submitWorkOrder({ submitType: submitType.SAFELITE }); this.$router.navigate( this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS, diff --git a/src/layouts/policy-vehicles/policy-vehicles.spec.js b/src/layouts/policy-vehicles/policy-vehicles.spec.js index a4670b55..55f2c676 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.spec.js +++ b/src/layouts/policy-vehicles/policy-vehicles.spec.js @@ -252,12 +252,12 @@ describe('policy-vehicles.vue', () => { ); test( - 'Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', + 'Error in lookupVehicleByVin call => error thrown in forwardButtonAction.', async () => { // Arrange const { wrapper } = setupMocks({}); const lookupReturnValue = { error: true, status: 500, data: 'error' }; - wrapper.vm.lookupVehicleByVin = jest.fn().mockReturnValue(lookupReturnValue); + wrapper.vm.lookupVehicleByVin = jest.fn().mockReturnValue(Promise.reject(lookupReturnValue)); const vin = getRandomString(17, 17); await wrapper.setData({ @@ -270,21 +270,14 @@ describe('policy-vehicles.vue', () => { }); // Act - wrapper.vm.mainStore.applicationUser.pageData[issPageValues.BAILOUT_PAGE] = { - 'bailout-page': { - bailoutCode: bailoutCode.VehicleVinLookupError - } - }; - await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalledWith(bailoutMessage.vehicleVinLookupError(vin, lookupReturnValue.data)); - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - undefined, - {}, - {} - ); + expect.assertions(1); + try { + await wrapper.vm.forwardButtonAction(); + } catch (e) { + expect(e).toBe(lookupReturnValue); + } } ); diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index c459cefd..bd00493d 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -59,7 +59,6 @@ import vehicleSelectionOptions from '@/constants/vehicle-selection-options.js'; import endorsementOptions from '@/constants/endorsement-options.js'; import globalRules from '@/constants/global-rules.js'; import { useMainStore } from '@/store/index.js'; -import bailoutMessage from '@/constants/bailoutMessage'; import { deductibleForSelectedVehicle, endorsementsForSelectedVehicle, @@ -144,10 +143,6 @@ export default { }, repairWaivedForSelectedVehicle() { return repairWaivedForSelectedVehicle(this.selectedPolicyVehicle); - }, - selectedVehicle() { - const vehicle = this.mainStore.lookupVehicleByVin(this.selectedVehicleVin); - return vehicle; } }, watch: { @@ -158,24 +153,23 @@ export default { this.mainStore.resetVehicleState(); } else { // get vehicle details from selected VIN - const vehicle = await this.lookupVehicleByVin(value); + try { + const vehicle = await this.lookupVehicleByVin(value); - // handle error in case vehicle info doesn't come back for selected VIN - if (vehicle?.error === true) { + if (!vehicle?.data.canSafeliteService) { + this.displayNoServiceAlert = true; + return; + } + if (vehicle) { + // save selected vehicle to the store + useMainStore().updateVehicle({ + ...vehicle.data, + policyVehicleId: this.selectedPolicyVehicle?.id, + vin: value + }); + } + } catch (e) { this.mainStore.resetVehicleState(); - return; - } - if (!vehicle?.data.canSafeliteService) { - this.displayNoServiceAlert = true; - return; - } - if (vehicle) { - // save selected vehicle to the store - useMainStore().updateVehicle({ - ...vehicle.data, - policyVehicleId: this.selectedPolicyVehicle?.id, - vin: value - }); } } } @@ -217,11 +211,7 @@ export default { return this.navigateForward(); } - this.mainStore.setBailout(bailoutMessage.vehicleVinLookupError( - vehicle.vin, - vehicleLookupResponse.data - )); - return this.navigateForward(); + return; } useMainStore().updateVehicle({ @@ -242,14 +232,7 @@ export default { return this.navigateForward(); }, navigateForward() { - if (this.mainStore.isBailout) { - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route, - {}, - {} - ); - } else if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) { + if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE, this.$route, diff --git a/src/layouts/provider-preference/provider-preference.spec.js b/src/layouts/provider-preference/provider-preference.spec.js index 3fdcb495..0d93ed3a 100644 --- a/src/layouts/provider-preference/provider-preference.spec.js +++ b/src/layouts/provider-preference/provider-preference.spec.js @@ -20,7 +20,8 @@ jest.mock('@/helpers/cms-content-helper', () => ({ function setupMocks(mockApiResponses) { const mountOptions = getMountOptions({ router: { - navigate: jest.fn() + navigate: jest.fn(), + navigateBailout: jest.fn() }, route: 'provider-preference' }); @@ -43,7 +44,7 @@ function setupMocks(mockApiResponses) { } describe('provider-preference.vue', () => { - test('Should navigate to tpa disabled route page when TPAOption selected and TPA Flow disabled', () => { + test('Should navigateBailout when TPAOption selected and TPA Flow disabled', () => { // Arrange const { wrapper } = setupMocks(); @@ -52,7 +53,7 @@ describe('provider-preference.vue', () => { wrapper.vm.findAnotherShopClicked(); // Test - expect(wrapper.vm.$router.navigate).toBeCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, 'provider-preference'); + expect(wrapper.vm.$router.navigateBailout).toBeCalled(); }); test('Should navigate to safelite flow when navigateWithTPARecalAnswer is called with SafeliteOption', () => { diff --git a/src/layouts/provider-preference/provider-preference.vue b/src/layouts/provider-preference/provider-preference.vue index 4400174e..27e38ff8 100644 --- a/src/layouts/provider-preference/provider-preference.vue +++ b/src/layouts/provider-preference/provider-preference.vue @@ -186,9 +186,7 @@ export default { this.scheduleWithTPA(); } } else { - this.mainStore.setBailout(bailoutMessage.TPANotEnabled()); - const scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED; - this.navigateForward(scenario); + this.$router.navigateBailout(bailoutMessage.TPANotEnabled()); } }, openStateSteeringModal() { diff --git a/src/layouts/tpa-search/tpa-search.spec.js b/src/layouts/tpa-search/tpa-search.spec.js index a888e60f..20a22153 100644 --- a/src/layouts/tpa-search/tpa-search.spec.js +++ b/src/layouts/tpa-search/tpa-search.spec.js @@ -53,7 +53,8 @@ const loaderStub = { function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) { const mountOptions = getMountOptions({ router: { - navigate: jest.fn() + navigate: jest.fn(), + navigateBailout: jest.fn() }, route: { query: { issPage: 'tpa-search' } @@ -787,7 +788,7 @@ describe('tpa-search.vue', () => { }); describe('needHelpLinkClick', () => { - test('sets bailout and navigates', () => { + test('navigatesBailout', () => { // Arrange const { wrapper } = getMountedComponent(); @@ -795,11 +796,7 @@ describe('tpa-search.vue', () => { wrapper.vm.needHelpLinkClick(); // Assert - expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalled(); - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_NEED_HELP, - expect.anything() - ); + expect(wrapper.vm.$router.navigateBailout).toBeCalled(); }); }); diff --git a/src/layouts/tpa-search/tpa-search.vue b/src/layouts/tpa-search/tpa-search.vue index 99241b1f..fd726728 100644 --- a/src/layouts/tpa-search/tpa-search.vue +++ b/src/layouts/tpa-search/tpa-search.vue @@ -358,11 +358,7 @@ export default { return getTpaProvidersResult?.data ?? []; }, needHelpLinkClick() { - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.$router.navigate( - this.navigationScenarios.CLICKED_NEED_HELP, - this.$route - ); + this.$router.navigateBailout(bailoutMessage.RequestCallback()); }, async searchClick() { if (isNaN(this.tpaSearchValue)) { diff --git a/src/layouts/tpa-submit/tpa-submit.vue b/src/layouts/tpa-submit/tpa-submit.vue index d1a1e1ed..bd113db7 100644 --- a/src/layouts/tpa-submit/tpa-submit.vue +++ b/src/layouts/tpa-submit/tpa-submit.vue @@ -315,20 +315,8 @@ export default { }; }, async forwardButtonAction() { - try { - await submitWorkOrder({ submitType: submitType.TPA }).then(() => { - this.navigate(this.navigationScenarios.CLICKED_FORWARD); - }).catch((submitError) => { - this.mainStore.setBailout(bailoutMessage.saveSessionError(submitError.data)); - this.navigate( - this.navigationScenarios.SAVE_SESSION_FAILED, - this.$route, - { issPage: this.issPageValues.TPA_SUBMIT } - ); - }); - } catch (error) { - console.error(`error: response from submit work order:${error.message}`); - } + await submitWorkOrder({ submitType: submitType.TPA }) + this.navigate(this.navigationScenarios.CLICKED_FORWARD); }, navigate(scenario) { this.$router.navigate(scenario, this.$route); diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index db8ae50d..8bc26edb 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -139,7 +139,7 @@ describe('vehicle-damage.vue', () => { expect(vehicleQuestionsMixin.methods.getPartsOrQuestions).toHaveBeenCalledTimes(1); expect(vehicleQuestionsMixin.methods.navigateForward).toHaveBeenCalledTimes(1); }); - test('Error in getPartsOrQuestions call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario', async () => { + test('Error in getPartsOrQuestions call => error thrown in forwardButtonAction', async () => { mountOptions.global.plugins = [createTestingPinia({ initialState: { main: { @@ -154,23 +154,21 @@ describe('vehicle-damage.vue', () => { } } })]; - mountOptions.data = () => ({ - hasBailedOut: true - }); + mountOptions.data = () => ({}); const wrapper = mount(VehicleDamageComponent, mountOptions); - const siteFooterWrapper = wrapper.getComponent({ ref: 'siteFooter' }); const partsQuestionsErrorResponse = { error: 'Error getting parts' }; vehicleQuestionsMixin.methods.getPartsOrQuestions.mockImplementation(() => ( - partsQuestionsErrorResponse + Promise.reject(partsQuestionsErrorResponse) )); - siteFooterWrapper.vm.$emit('forwardClicked'); - await flushPromises(); - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate) - .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, mockRoute); + expect.assertions(1); + try { + await wrapper.vm.forwardButtonAction(); + } catch (e) { + expect(e).toBe(partsQuestionsErrorResponse); + } }); }); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index b486f90e..a27e3655 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -189,8 +189,7 @@ export default { this.getPassengerSideReplaceOptionsFromStore() }, selectedWindshieldOptions: this.getWindshieldOptionsFromStore(), - selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore(), - hasBailedOut: false + selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore() }; }, computed: { @@ -429,23 +428,12 @@ export default { // If vin already exists or not replacing windshield, get parts/questions and navigate forward const partsOrQuestionsResponse = await this.getPartsOrQuestions(); - if (partsOrQuestionsResponse.error) { - this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data)); - window.console.error('Error on retrieving PartsOrQuestions'); - this.hasBailedOut = true; - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } // Comes from vehicleQuestionsMixin.navigateForward() - if (!this.hasBailedOut) { - await this.navigateForward( - partsOrQuestionsResponse.data.partsOrQuestions, - this - ); - } + await this.navigateForward( + partsOrQuestionsResponse.data.partsOrQuestions, + this + ); } else { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, diff --git a/src/layouts/vehicle-lookup/vehicle-lookup.vue b/src/layouts/vehicle-lookup/vehicle-lookup.vue index b322b7c8..acbf58a0 100644 --- a/src/layouts/vehicle-lookup/vehicle-lookup.vue +++ b/src/layouts/vehicle-lookup/vehicle-lookup.vue @@ -113,21 +113,10 @@ export default { break; case vinLookupMethodSelections.NOVIN: const partsOrQuestionsResponse = await this.getPartsOrQuestions(); - if (partsOrQuestionsResponse.error) { - this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data)); - window.console.error('Error on retrieving PartsOrQuestions'); - this.hasBailedOut = true; - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } - else { - await this.navigateForward( - partsOrQuestionsResponse.data.partsOrQuestions, - this - ); - } + await this.navigateForward( + partsOrQuestionsResponse.data.partsOrQuestions, + this + ); break; default: break; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index b951f777..a49e8be4 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -64,6 +64,7 @@ import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import { useMainStore } from '@/store'; import widgetFields from '@/constants/cms-widget-fields'; +import bailoutMessage from '@/constants/bailoutMessage'; export default { name: 'vehicle-parts', @@ -213,8 +214,7 @@ export default { }); }, requestCallbackBailout() { - this.mainStore.setBailout(bailoutMessage.RequestCallback()); - this.$router.navigate(navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, this.$route); + this.$router.navigateBailout(bailoutMessage.RequestCallback()); } } }; diff --git a/src/layouts/vehicle-selection/vehicle-selection.vue b/src/layouts/vehicle-selection/vehicle-selection.vue index 1f56fec3..1cfb7f4d 100644 --- a/src/layouts/vehicle-selection/vehicle-selection.vue +++ b/src/layouts/vehicle-selection/vehicle-selection.vue @@ -206,77 +206,25 @@ export default { }, navigateForward() { - this.mainStore.setVehicle().then( - () => { - if (this.mainStore.isBailout) { - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - return; - } - + this.mainStore.setVehicle().then(() => { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD, this.$route ); - }, - (error) => { - this.mainStore.setBailout(bailoutMessage.vehicleYMMSLookupError(this.mainStore.vehicle.year, this.mainStore.vehicle.make, this.mainStore.vehicle.model, this.mainStore.vehicle.style, error)); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); } ); }, async updateYearValues() { - return this.mainStore.getVehicleYears().then( - (response) => response, - (error) => { - this.mainStore.setBailout(bailoutMessage.vehicleYMMSLookupError(null, null, null, null, error)); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } - ); + return this.mainStore.getVehicleYears(); }, async updateMakeValues() { - return this.mainStore.getVehicleMakes().then( - (response) => response, - (error) => { - this.mainStore.setBailout(bailoutMessage.vehicleYMMSLookupError(this.mainStore.vehicle.year, null, null, null, error)); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } - ); + return this.mainStore.getVehicleMakes(); }, async updateModelValues() { - return this.mainStore.getVehicleModels().then( - (response) => response, - (error) => { - this.mainStore.setBailout(bailoutMessage.vehicleYMMSLookupError(this.mainStore.vehicle.year, this.mainStore.vehicle.make, null, null, error)); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } - ); + return this.mainStore.getVehicleModels(); }, async updateStyleValues() { - return this.mainStore.getVehicleStyles().then( - (response) => response, - (error) => { - this.mainStore.setBailout(bailoutMessage.vehicleYMMSLookupError(this.mainStore.vehicle.year, this.mainStore.vehicle.make, this.mainStore.vehicle.model, null, error)); - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } - ); + return this.mainStore.getVehicleStyles(); }, resetAlert() { this.displayNoServiceAlert = false; diff --git a/src/layouts/vin-lookup/vin-lookup.spec.js b/src/layouts/vin-lookup/vin-lookup.spec.js index 0376eaa3..b5808d77 100644 --- a/src/layouts/vin-lookup/vin-lookup.spec.js +++ b/src/layouts/vin-lookup/vin-lookup.spec.js @@ -148,7 +148,8 @@ const mockRoute = { }; const mockRouter = { navigate: jest.fn(), - navigateWithSpinner: jest.fn() + navigateWithSpinner: jest.fn(), + navigateBailout: jest.fn() }; const maska = jest.fn(); jest.mock('@/helpers/damage-helper', () => ({ @@ -553,45 +554,6 @@ describe('vin-lookup.vue', () => { ); }); }); - test( - 'Error in getPartsOrQuestions call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario', - async () => { - const user = userEvent.setup(); - mountOptions.global.stubs.vinQuestion = false; - - mountOptions.data = () => ({ - vinWithNonMatchingCarId: false, - isCarIdDifferentFromTheStore: false, - vin: mockValidVin, - hasBailedOut: true - }); - - getPartsOrQuestions.mockResponse = partsOrQuestionsErrorMockResponse; - - jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName) - .mockResolvedValue(lookupVehicleByVin.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) - .mockResolvedValue(getPartsOrQuestions.mockResponse); - - const { container } = render(VinLookupComponent, mountOptions); - - const vinInput = container.querySelector(vinInputSelector); - await user.type(vinInput, mockValidVin); - - const continueButton = container.querySelector(continueButtonQuerySelector); - await user.click(continueButton); - - await flushPromises(); - await waitFor(() => { - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - mockRoute - ); - }); - } - ); }); }); }); diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 3bb0d637..05582873 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -112,8 +112,7 @@ export default { vinWithNonMatchingCarId: vin?.length > 0 && !this.hasValidCarId(), vin, forwardButtonCarStyle: '', - vinPopulatedOnPageLoad: vin?.length > 0 && this.hasValidCarId(), - hasBailedOut: false + vinPopulatedOnPageLoad: vin?.length > 0 && this.hasValidCarId() }; }, computed: { @@ -176,35 +175,37 @@ export default { showIssLoadingModal(true); if (this.needToLookupVehicle) { - const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin); + try { + const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin); - if (vehicleLookupResponse.error) { - this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND; - this.mainStore.setBailout(bailoutMessage.vehicleNotFound(this.vin)); - this.resetVehicleFromLookup(); - // Temp solution to turn on 'disabled' style on the Continue button - // because the form itself actually passes its client-side validation. - // SSR-189 Scenario #4. - this.$refs.siteFooter.enableForwardAction(); - showIssLoadingModal(false); - return; - } - - if (!vehicleLookupResponse.data.canSafeliteService) { - this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE; - this.resetVehicleFromLookup(); - this.$refs.siteFooter.disableForwardButton(); - showIssLoadingModal(false); - return; - } - - // Add vin bcs the response from the service doesn't contain vin - this.vehicleFromLookup = Object.assign( - vehicleLookupResponse.data, - { - vin: this.vin + if (!vehicleLookupResponse.data.canSafeliteService) { + this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE; + this.resetVehicleFromLookup(); + this.$refs.siteFooter.disableForwardButton(); + showIssLoadingModal(false); + return; } - ); + + // Add vin bcs the response from the service doesn't contain vin + this.vehicleFromLookup = Object.assign( + vehicleLookupResponse.data, + { + vin: this.vin + } + ); + } catch (e) { + if (e.status === 404) { + this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND; + this.resetVehicleFromLookup(); + // Temp solution to turn on 'disabled' style on the Continue button + // because the form itself actually passes its client-side validation. + // SSR-189 Scenario #4. + this.$refs.siteFooter.enableForwardAction(); + showIssLoadingModal(false); + return; + } + throw e; + } } if (this.needToLookupVehicle && this.isCarIdDifferentFromTheStore) { @@ -259,34 +260,15 @@ export default { } const partsOrQuestionsResponse = await this.getPartsOrQuestions(); - if (partsOrQuestionsResponse.error) { - this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data)); - window.console.error('Error on retrieving PartsOrQuestions'); - this.hasBailedOut = true; - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); - } // Comes from vehicleQuestionsMixin.navigateForward() - if (!this.hasBailedOut) { - await this.navigateForward( - partsOrQuestionsResponse.data.partsOrQuestions, - this - ); - } + await this.navigateForward( + partsOrQuestionsResponse.data.partsOrQuestions, + this + ); }, async lookupVehicleByVin(vin) { - try { - return await this.mainStore.lookupVehicleByVin(vin); - } catch (responseError) { - return { - error: { - status: responseError.status - } - }; - } + return this.mainStore.lookupVehicleByVin(vin); }, resetActiveAlert() { this.activeVehicleLookupAlertType = null; diff --git a/src/layouts/welcome-page/welcome-page.spec.js b/src/layouts/welcome-page/welcome-page.spec.js index 4748a9b0..39fd8284 100644 --- a/src/layouts/welcome-page/welcome-page.spec.js +++ b/src/layouts/welcome-page/welcome-page.spec.js @@ -72,7 +72,8 @@ function setupMocks({ const mockDataMountOptions = { ...mountOptionsMockData, router: { - navigate: jest.fn() + navigate: jest.fn(), + navigateBailout: jest.fn() } }; @@ -166,7 +167,7 @@ describe('navigation', () => { const { wrapper } = setupMocks({}); wrapper.vm.mainStore.getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); wrapper.vm.mainStore.applicationUser.duplicateOrders = [{ test: 'a' }]; - wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.reject()); + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.reject({ isAxiosError: false })); // Act await wrapper.vm.forwardButtonAction(); @@ -316,10 +317,14 @@ describe('navigation', () => { })); // Act - await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect.assertions(1); + try { + await wrapper.vm.forwardButtonAction(); + } catch (e) { + expect(e).toMatch(error); + } }); }); }); diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 6520a930..235f510b 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -303,54 +303,47 @@ export default { }, methods: { async forwardButtonAction() { - try { - this.mainStore.updatePolicyData(this.welcomePageModel); - const promises = []; - promises.push(this.configureZip().then(async () => await this.mainStore.getBillToInfo())); + this.mainStore.updatePolicyData(this.welcomePageModel); - // Clear duplicate orders if navigating away from the welcome page after visiting duplicate check page. - if (this.mainStore.order.visitedDuplicateCheckPage) { - this.mainStore.clearDuplicateOrders(); - } - - // Skip duplicate check if loaded from cookie or already visited duplicate check page. - if (!this.mainStore.order.loadedFromCookie && !this.mainStore.order.visitedDuplicateCheckPage) { - promises.push(this.mainStore.getDuplicateReferrals()); - } - promises.push(this.mainStore.getCoveragePolicyInfo()); - await Promise.allSettled(promises); - } catch (e) { - console.error(e); - // TODO: Bailout? - } finally { - if (!this.displayInvalidZipAlert) { - await saveSession({ shouldAwaitSaveSessionQueue: true }) - .catch((error) => { - this.mainStore.setBailout(bailoutMessage.saveSessionError(error.data)); - }) - .finally(() => this.navigateForward()); - } + // We want to await this separately. It's quick and if this has an invalid zip we don't want to be waiting on the slower API calls + await this.configureZip(); + if (this.displayInvalidZipAlert) { + showIssLoadingModal(false); + return; } + + // Clear duplicate orders if navigating away from the welcome page after visiting duplicate check page. + if (this.mainStore.order.visitedDuplicateCheckPage) { + this.mainStore.clearDuplicateOrders(); + } + + const promises = [ + // Suppress error from API call we can try again later in the flow + this.mainStore.getBillToInfo() + ]; + // Skip duplicate check if loaded from cookie or already visited duplicate check page. + if (!this.mainStore.order.loadedFromCookie && !this.mainStore.order.visitedDuplicateCheckPage) { + promises.push(this.mainStore.getDuplicateReferrals()); + } + promises.push(this.mainStore.getCoveragePolicyInfo()); + await Promise.all(promises); + await saveSession({shouldAwaitSaveSessionQueue: true}) + .catch((error) => this.mainStore.setBailout(bailoutMessage.saveSessionError(error))); + this.navigateForward(); }, async configureZip() { try { this.displayInvalidZipAlert = false; await this.mainStore.validateZip({ zip: this.welcomePageModel.policyZipCode }); - return Promise.resolve(); } catch (e) { + if (e.isAxiosError) { + throw e; + } this.displayInvalidZipAlert = true; - return Promise.reject(e); } }, navigateForward() { - if (this.mainStore.isBailout) { - this.$router.navigate( - this.navigationScenarios.SAVE_SESSION_FAILED, - this.$route, - {}, - { [routerParams.SKIP_SAVE_SESSION]: true } - ); - } else if ((this.mainStore.applicationUser.duplicateOrders?.length > 0 ?? false) + if ((this.mainStore.applicationUser.duplicateOrders?.length > 0 ?? false) && !this.answeredContinueModal) { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, @@ -445,12 +438,7 @@ export default { .then((response) => { this.answeredContinueModal = true; if (response && !response.provider?.isSafeliteProvider) { - this.mainStore.setBailout(bailoutMessage.SafeliteNotTheProvider()); - this.hasBailedOut = true; - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - this.$route - ); + this.$router.navigateBailout(bailoutMessage.SafeliteNotTheProvider()); } else { this.updateWelcomePageModel(response); } diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index d5c492d8..6efed9ee 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -353,16 +353,7 @@ export default { }, async getPartsOrQuestions() { - try { - return await useMainStore().getPartsOrQuestions(); - } catch (responseError) { - return { - error: { - status: responseError.status, - data: responseError.data - } - }; - } + return useMainStore().getPartsOrQuestions(); }, // Can't use `this` because navigateForward is also called from vin-pages-mixin diff --git a/src/router/index.js b/src/router/index.js index cd77544f..c6a18493 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -25,100 +25,95 @@ const routes = [ path: '/', name: 'root', async beforeEnter(to, from, next) { - try { - const issPageToUse = !to.query.issPage ? issPageValues.WELCOME_PAGE : to.query.issPage; - const fromQueryPage = from.query?.issPage; + const issPageToUse = !to.query.issPage ? issPageValues.WELCOME_PAGE : to.query.issPage; + const fromQueryPage = from.query?.issPage; - if ((issPageToUse === issPageValues.ACCESS_DENIED + if ((issPageToUse === issPageValues.ACCESS_DENIED || (issPageToUse !== issPageValues.ENTRY_PAGE && !useMainStore().issConfig.parentAccountNumber)) - && process.env.VUE_APP_CURRENT_ENVIRONMENT !== 'Localhost' - ) { - return await GoToAccessIsDenied(next); + && process.env.VUE_APP_CURRENT_ENVIRONMENT !== 'Localhost' + ) { + return await GoToAccessIsDenied(next); + } + + // Do not run these for the main entry page - as it is not part of the user flow. + if (issPageToUse !== issPageValues.ENTRY_PAGE) { + if (analyticsMixin.methods.noSession()) { + await analyticsMixin.methods.initSession(); + } else { + updateSessionIdCookie(); } - // Do not run these for the main entry page - as it is not part of the user flow. - if (issPageToUse !== issPageValues.ENTRY_PAGE) { - if (analyticsMixin.methods.noSession()) { - await analyticsMixin.methods.initSession(); - } else { - updateSessionIdCookie(); - } + await runExperiments(issPageToUse); // fmg has this further down + } - await runExperiments(issPageToUse); // fmg has this further down + // Intercept all navigation if a submitted order exists in storage + if (useMainStore().hasSubmittedOrder()) { + if (to.query.issPage !== issPageValues.ENTRY_PAGE) { + return await GoToConfirmationPage(next, useMainStore().getSubmittedOrder()); + } + } + + // If the saved session has timed out, clear the session, execute 404 logic. + if (getISSCookie() !== null && !isSavedSessionStillActive()) { + // await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); + await GoToStartOn404(next); + } + + // Process ISS cookie. + // Skip if Entry Page or Refreshing Welcome page + if (issPageToUse !== issPageValues.ENTRY_PAGE + && !(issPageToUse === issPageValues.WELCOME_PAGE && fromQueryPage === undefined)) { + updateOrCreateISSCookie(); + } + + if (router.hasRoute(issPageToUse)) { + // Since our route is already in scope, we can grab the component and call the arePagePrerequisitesValid function. + let component = router.getRoutes().filter((x) => x.name === issPageToUse)[0].components; + + // If the component hasn't been loaded fully, load it before we check prerequisites. + if (component.default.methods === undefined) { + component = await component.default(); } - // Intercept all navigation if a submitted order exists in storage - if (useMainStore().hasSubmittedOrder()) { - if (to.query.issPage !== issPageValues.ENTRY_PAGE) { - return await GoToConfirmationPage(next, useMainStore().getSubmittedOrder()); - } - } - - // If the saved session has timed out, clear the session, execute 404 logic. - if (getISSCookie() !== null && !isSavedSessionStillActive()) { - // await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); + if (!arePagePrerequisitesValid(component)) { await GoToStartOn404(next); } - // Process ISS cookie. - // Skip if Entry Page or Refreshing Welcome page - if (issPageToUse !== issPageValues.ENTRY_PAGE - && !(issPageToUse === issPageValues.WELCOME_PAGE && fromQueryPage === undefined)) { - updateOrCreateISSCookie(); - } - - if (router.hasRoute(issPageToUse)) { - // Since our route is already in scope, we can grab the component and call the arePagePrerequisitesValid function. - let component = router.getRoutes().filter((x) => x.name === issPageToUse)[0].components; - - // If the component hasn't been loaded fully, load it before we check prerequisites. - if (component.default.methods === undefined) { - component = await component.default(); - } - - if (!arePagePrerequisitesValid(component)) { - await GoToStartOn404(next); - } - - return next({ name: issPageToUse, query: to.query, params: to.params }); - } - - const routeData = await GetRouteInfoFromPageName(issPageToUse); - - if (routeData[0].name.toLowerCase() === 'error') { - throw new Error('Page not found!'); - } - - // Add our dynamic route. - router.addRoute({ - path: routeData[0].path, // Always the same path, because we control it with query strings. - name: routeData[0].name, - component: routeData[0].component - }); - - // Call the next components arePagePrerequisitesValid method before load. - // If it returns false, use the 404 logic. - const nextComponent = await router - .getRoutes() - .filter((x) => x.name === routeData[0].name)[0] - .components.default(); - - if (!arePagePrerequisitesValid(nextComponent)) { - const tempMsgCopy = 'Pre Requisites failed, need to handle. Default is Welcome Page.'; - const tempMsgHeadline = `${issPageToUse}: pre-req failed...`; - await GoToStartOn404(next, tempMsgCopy, tempMsgHeadline); - } - - // Assign current query string parameters, as well as our issPage one. - next({ - name: routeData[0].name, - query: Object.assign(to.query, { issPage: routeData[0].name }), - params: to.params - }); - } catch (error) { - window.console.warn(error); - await GoToStartOn404(next); + return next({name: issPageToUse, query: to.query, params: to.params}); } + + const routeData = await GetRouteInfoFromPageName(issPageToUse); + + if (routeData[0].name.toLowerCase() === 'error') { + throw new Error('Page not found!'); + } + + // Add our dynamic route. + router.addRoute({ + path: routeData[0].path, // Always the same path, because we control it with query strings. + name: routeData[0].name, + component: routeData[0].component + }); + + // Call the next components arePagePrerequisitesValid method before load. + // If it returns false, use the 404 logic. + const nextComponent = await router + .getRoutes() + .filter((x) => x.name === routeData[0].name)[0] + .components.default(); + + if (!arePagePrerequisitesValid(nextComponent)) { + const tempMsgCopy = 'Pre Requisites failed, need to handle. Default is Welcome Page.'; + const tempMsgHeadline = `${issPageToUse}: pre-req failed...`; + await GoToStartOn404(next, tempMsgCopy, tempMsgHeadline); + } + + // Assign current query string parameters, as well as our issPage one. + next({ + name: routeData[0].name, + query: Object.assign(to.query, {issPage: routeData[0].name}), + params: to.params + }); return null; } } @@ -177,7 +172,7 @@ router.afterEach(async (to, from) => { const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; if (from.name !== undefined && !skipSaveSession && !store.hasSubmittedOrder()) { - await saveSession({}); + await saveSession({ bailoutOnError: from.name === issPageValues.ENTRY_PAGE}); } if (to.query.issPage !== issPageValues.ENTRY_PAGE) { @@ -350,17 +345,12 @@ router.navigateBailout = (bailoutData = null) => { // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap(scenario, currentRoute) { const issPageValue = currentRoute.query.issPage; - try { - const matchedQueryValue = routingTable(useMainStore()) - .filter((item) => item.issPageValue === issPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0); + const matchedQueryValue = routingTable(useMainStore()) + .filter((item) => item.issPageValue === issPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0); - const maps = matchedQueryValue ? matchedQueryValue.map((m) => m.maps.filter((map) => map.scenario === scenario))[0] : undefined; + const maps = matchedQueryValue ? matchedQueryValue.map((m) => m.maps.filter((map) => map.scenario === scenario))[0] : undefined; - return maps ? maps.filter((x) => x.filter === true || x.filter === undefined)[0] : undefined; - } catch (e) { - window.console.error(e); - return undefined; - } + return maps ? maps.filter((x) => x.filter === true || x.filter === undefined)[0] : undefined; } async function GoToAccessIsDenied(next) { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index f0603b96..07a012ed 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -12,7 +12,6 @@ const navigationScenarios = Object.freeze({ CLICKED_FORWARD_POLICY_UNVERIFIED: 'CLICKED_FORWARD_POLICY_UNVERIFIED', CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES: 'CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES', CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES: 'CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES', - SAVE_SESSION_FAILED: 'SAVE_SESSION_FAILED', // Duplicate Check CLICKED_FORWARD_LOADED_DUPLICATE_WITH_POLICY_VEHICLE: 'CLICKED_FORWARD_LOADED_DUPLICATE_WITH_POLICY_VEHICLE', @@ -70,11 +69,8 @@ const navigationScenarios = Object.freeze({ // Coverage Statement CLICKED_BACK_WITH_REPAIR: 'CLICKED_BACK_WITH_REPAIR', - CLICKED_FORWARD_WITH_INVALID_STATE: 'CLICKED_FORWARD_WITH_INVALID_STATE', - PRICING_LOOKUP_ERROR: 'PRICING_LOOKUP_ERROR', // TPA Search - CLICKED_NEED_HELP: 'CLICKED_NEED_HELP', CLICKED_FORWARD_WITH_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_SAFELITE_SHOP', CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP: 'CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP', @@ -88,7 +84,6 @@ const navigationScenarios = Object.freeze({ // Provider Preference CLICKED_FORWARD_WITH_SAFELITE: 'CLICKED_FORWARD_WITH_SAFELITE', CLICKED_FORWARD_WITH_TPA_ENABLED: 'CLICKED_FORWARD_WITH_TPA_ENABLED', - CLICKED_FORWARD_WITH_TPA_DISABLED: 'CLICKED_FORWARD_WITH_TPA_DISABLED', CLICKED_FORWARD_WITH_POLICY_AND_VEHICLES: 'CLICKED_FORWARD_WITH_POLICY_AND_VEHICLES', // Service Package @@ -112,8 +107,6 @@ const navigationScenarios = Object.freeze({ PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS', // Bailout - CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT', - CLICKED_NEED_HELP_WITH_BAILOUT: 'CLICKED_NEED_HELP_WITH_BAILOUT', BAILOUT: 'BAILOUT' }); diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3751060c..7911b5c6 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -14,10 +14,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD, destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -55,10 +51,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -141,14 +133,6 @@ const routingTable = () => [ { scenario: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP - }, - { - scenario: issPageValues.BAILOUT_PAGE, // TODO is this a bug - destinationIssPageValue: issPageValues.BAILOUT_PAGE - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -215,10 +199,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT - }, - { - scenario: navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -256,10 +236,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT - }, - { - scenario: navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -293,10 +269,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT - }, - { - scenario: navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -455,14 +427,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, destinationIssPageValue: issPageValues.POLICY_VEHICLES - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE - }, - { - scenario: navigationScenarios.SAVE_SESSION_FAILED, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -539,10 +503,6 @@ const routingTable = () => [ scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND, destinationIssPageValue: issPageValues.VIN_LOOKUP }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, - destinationIssPageValue: issPageValues.BAILOUT_PAGE - }, { scenario: navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, destinationIssPageValue: issPageValues.POLICY_ENDORSEMENTS @@ -591,18 +551,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, destinationIssPageValue: issPageValues.SCHEDULE_PAGE - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, - destinationIssPageValue: issPageValues.BAILOUT_PAGE - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE, - destinationIssPageValue: issPageValues.BAILOUT_PAGE - }, - { - scenario: navigationScenarios.PRICING_LOOKUP_ERROR, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -620,10 +568,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED, destinationIssPageValue: issPageValues.TPA_SEARCH - }, - { - scenario: navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -692,10 +636,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_PAY_NOW, destinationIssPageValue: issPageValues.PAYMENT_PAGE - }, - { - scenario: navigationScenarios.SAVE_SESSION_FAILED, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -768,10 +708,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD, destinationIssPageValue: issPageValues.TPA_CONFIRMATION - }, - { - scenario: navigationScenarios.SAVE_SESSION_FAILED, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, @@ -798,10 +734,6 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, destinationIssPageValue: issPageValues.TPA_SUBMIT - }, - { - scenario: navigationScenarios.CLICKED_NEED_HELP, - destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] }, diff --git a/src/router/router.spec.js b/src/router/router.spec.js index ee35151a..675fa7fa 100644 --- a/src/router/router.spec.js +++ b/src/router/router.spec.js @@ -4,6 +4,8 @@ import issPageValues from '@/router/router-constants/issPage-values'; import { createApp } from 'vue'; import { createPinia } from 'pinia'; import App from '@/App.vue'; +import bailoutMessage from '@/constants/bailoutMessage'; +import { useMainStore } from '@/store'; describe('Router', () => { beforeAll(() => { @@ -37,18 +39,15 @@ describe('Router', () => { expect(router.push.mock.calls[0][0].state).toBe(parameters); }); - it('Should route from CAPABILITY_QUESTIONS to BAILOUT_PAGE on CLICKED_NEED_HELP_WITH_BAILOUT', () => { - const scenario = navigationScenarios.CLICKED_NEED_HELP_WITH_BAILOUT; - const currentRoute = { query: { issPage: issPageValues.CAPABILITY_QUESTIONS } }; - + it('Should set bailout and navigate to bailout page when calling navigateBailout', () => { + // Arrange router.push = jest.fn(); // Act - router.navigate(scenario, currentRoute); + router.navigateBailout(bailoutMessage.unknown({})); // Assert - expect(router.push).toHaveBeenCalled(); - expect(router.push.mock.calls[0][0].query.issPage).toBe(issPageValues.BAILOUT_PAGE); + expect(useMainStore().isBailout).toBeTruthy() }); }); diff --git a/src/store/index.js b/src/store/index.js index 806ce1e6..7bcd88ab 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,7 +1,6 @@ import { defineStore } from 'pinia'; import applicationConfig from '@/constants/application-config'; import bailoutCode from '@/constants/bailoutCode'; -import bailoutMessage from '@/constants/bailoutMessage'; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; import damageLocationsSelected from '@/constants/damage-locations-selected'; @@ -22,11 +21,7 @@ import { noCoverageForSelectedVehicle, repairWaivedForSelectedVehicle } from '@/helpers/policy-vehicle-helper'; -import { - buildURLSearchParams, - getPartNumbersListForQueryString, - getTaxLineItemQueryString -} from '@/helpers/querystring-helper'; +import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helpers/querystring-helper'; import { getTopLevelGlassPartsWithRecal } from '@/helpers/recal-helper'; import { getDateForSavedSessionTimeout } from '@/helpers/session-helper'; import issPageValues from '@/router/router-constants/issPage-values'; @@ -534,20 +529,11 @@ export const useMainStore = defineStore({ }); }, getIsVinbyAddressPermissible() { - try { - const response = globalMethods.callHttpClient({ - method: endpoints.IsVinbyAddressPermissible.method, - endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`, - payload: {} - }); - return response; - } catch (responseError) { - return { - error: { - status: responseError.status - } - }; - } + return globalMethods.callHttpClient({ + method: endpoints.IsVinbyAddressPermissible.method, + endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`, + payload: {} + }); }, async getCoveragePolicyInfo() { const { order, issConfig, applicationUser } = this; @@ -561,49 +547,43 @@ export const useMainStore = defineStore({ this.applicationUser.coverageAttempts += 1; console.log(`Coverage lookup attempt #${this.applicationUser.coverageAttempts}. Max attempts allowed: 10.`); - try { - const response = await globalMethods.callHttpClient({ - method: endpoints.CoveragePolicyInfo.method, - endpoint: endpoints.CoveragePolicyInfo.url, - payload: { - accountNumber: order.parentAccountNumber?.toString(), - policyNumber: policy.policyNumber, - dateOfLoss: policy.dateOfLoss, - zipCode: policy.policyZipCode, - referralCorrelationId: order.referralCorrelationId - } - }); - - const responsePolicy = response?.data?.policies?.[0]; - if (responsePolicy) { - this.updateCoverageType(coverageType.Deductible); - const insured = responsePolicy.insureds?.[0]; - - // populate parent account number - if (response.data.accountNumber) { - order.parentAccountNumber = parseInt(response.data.accountNumber, 10); - } - - // populate policy holder details from policy lookup - order.customer.address.streetAddress = insured?.address; - order.customer.address.city = insured?.city; - order.customer.address.state = insured?.state; - order.customer.address.zipCode = insured?.zipCode?.toString(); - order.customer.firstName = insured?.firstName; - order.customer.lastName = insured?.lastName; - - // populate additional fields - order.policy.policyData = responsePolicy.policyData; - - // populate vehicles - order.policy.vehicles = responsePolicy.vehicles ?? []; - } else { - this.updateCoverageType(coverageType.NONE); + const response = await globalMethods.callHttpClient({ + method: endpoints.CoveragePolicyInfo.method, + endpoint: endpoints.CoveragePolicyInfo.url, + payload: { + accountNumber: order.parentAccountNumber?.toString(), + policyNumber: policy.policyNumber, + dateOfLoss: policy.dateOfLoss, + zipCode: policy.policyZipCode, + referralCorrelationId: order.referralCorrelationId } - return Promise.resolve(); - } catch (e) { + }); + + const responsePolicy = response?.data?.policies?.[0]; + if (responsePolicy) { + this.updateCoverageType(coverageType.Deductible); + const insured = responsePolicy.insureds?.[0]; + + // populate parent account number + if (response.data.accountNumber) { + order.parentAccountNumber = parseInt(response.data.accountNumber, 10); + } + + // populate policy holder details from policy lookup + order.customer.address.streetAddress = insured?.address; + order.customer.address.city = insured?.city; + order.customer.address.state = insured?.state; + order.customer.address.zipCode = insured?.zipCode?.toString(); + order.customer.firstName = insured?.firstName; + order.customer.lastName = insured?.lastName; + + // populate additional fields + order.policy.policyData = responsePolicy.policyData; + + // populate vehicles + order.policy.vehicles = responsePolicy.vehicles ?? []; + } else { this.updateCoverageType(coverageType.NONE); - return Promise.reject(e); } }, clearDuplicateOrders() { @@ -1360,7 +1340,8 @@ export const useMainStore = defineStore({ endpoint: endpoints.LookupVehicleByVin.url, payload: { vin - } + }, + bailoutOnError: false }); }, @@ -1392,7 +1373,7 @@ export const useMainStore = defineStore({ this.applicationUser.crmCustomerId = response.crmCustomerId.toString(); }, - saveSession({ submitAfterSave, createWorkOrderNumberForPIA }) { + saveSession({ submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError }) { const { vehicle, damage, policy, customer, contactInfo, payment, lineItems, serviceLocation, schedule, insuranceCoverage } = this.order; @@ -1544,7 +1525,7 @@ export const useMainStore = defineStore({ method: endpoints.SaveSession.method, endpoint: endpoints.SaveSession.url, payload, - bailoutOnError: false + bailoutOnError }).then((response) => { if (loadedFromDupeCheck) { this.order.loadedSessionClearedPreviousData = true; @@ -2461,6 +2442,7 @@ export const useMainStore = defineStore({ populateInitialState(forceReset) { if (!sessionStorage.getItem(storeId) || forceReset) { this.$state = getDefaultState(); + sessionStorage.removeItem(webStorageConstants.SUBMITTED_ORDER); } }, @@ -2699,34 +2681,26 @@ export const useMainStore = defineStore({ async getBillToInfo(componentProviderNumber = null) { const { order, issConfig } = this; - try { - const params = new URLSearchParams({ - parentAccountNumber: order.parentAccountNumber.toString(), - providerNumber: componentProviderNumber || this.providerNumber, - typeOfClaim: 'GLASS ONLY', - lineOfBusiness: 'PERSONAL', - isItac: this.isITAC - }); + const params = new URLSearchParams({ + parentAccountNumber: order.parentAccountNumber.toString(), + providerNumber: componentProviderNumber || this.providerNumber, + typeOfClaim: 'GLASS ONLY', + lineOfBusiness: 'PERSONAL', + isItac: this.isITAC + }); - const response = await globalMethods.callHttpClient({ - method: endpoints.GetBillToInfo.method, - endpoint: `${endpoints.GetBillToInfo.url}?${params.toString()}` - }); + const response = await globalMethods.callHttpClient({ + method: endpoints.GetBillToInfo.method, + endpoint: `${endpoints.GetBillToInfo.url}?${params.toString()}`, + bailoutOnError: false + }); - const billToInfo = response.data; - if (billToInfo != null) { - issConfig.billToAccountNumber = billToInfo.toString(); - return Promise.resolve(); - } - - return Promise.reject(new Error('Invalid billToInfo')); - } catch (e) { - return Promise.reject(e); - } + const billToInfo = response.data; + issConfig.billToAccountNumber = billToInfo.toString(); }, async validateClientTag(clientTag) { - return await globalMethods.callHttpClient({ + return globalMethods.callHttpClient({ method: endpoints.ValidateClientTag.method, endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}` }); From 991ef0ebb2974289faff868c2bd2a242c5c0e76a Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Wed, 18 Feb 2026 14:52:10 -0600 Subject: [PATCH 17/48] Missed file --- src/layouts/welcome-page/welcome-page.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 235f510b..e75d2c37 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -177,6 +177,7 @@ import { getPropertyCaseInsensitive } from '@/helpers/object-helper'; import { saveSession } from '@/helpers/order-helper'; import { getISSCookie } from '@/helpers/cookie-helper.js'; import bailoutMessage from '@/constants/bailoutMessage'; +import showIssLoadingModal from '@/helpers/loading-modal-helper'; // define validation rules defineRule( From 37e3bbbeeeb8c152574180849765dd2dde2df429 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 18 Feb 2026 16:10:37 -0500 Subject: [PATCH 18/48] text for coverage statement copy waiting to show --- .../__snapshots__/coverage-statement.spec.js.snap | 1 + .../coverage-statement/coverage-statement.spec.js | 15 ++++++++++++--- .../coverage-statement/coverage-statement.vue | 8 +++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap b/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap index 26f60304..40af428e 100644 --- a/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap +++ b/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap @@ -5,6 +5,7 @@ Object { "CANCEL_CLAIM_REF_NAME": "CancelClaimModal", "RECAL_MODAL_REF_NAME": "RecalModal", "baseServiceLineItems": Array [], + "isPageLoading": true, "widget": Object { "disclaimerText": "DisclaimerWidget", "explanatoryText": "ExplanatoryTextWidget", diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index aa9c3058..ea913872 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -134,7 +134,10 @@ describe('coverageStatement.vue', () => { }); test('Should render site subheader', () => { // Arrange - const { wrapper } = getMountedComponent({}); + const initialDataForTest = { + isPageLoading: false + }; + const { wrapper } = getMountedComponent({}, initialDataForTest); // Act const subheader = wrapper.find({ ref: 'siteSubHeader' }); @@ -145,7 +148,10 @@ describe('coverageStatement.vue', () => { test('Should render explanatory text', () => { // Arrange - const { wrapper } = getMountedComponent({}); + const initialDataForTest = { + isPageLoading: false + }; + const { wrapper } = getMountedComponent({}, initialDataForTest); // Act const explanatoryText = wrapper.find({ ref: 'explanatoryText' }); @@ -155,7 +161,10 @@ describe('coverageStatement.vue', () => { }); test('Should render secondary text', () => { // Arrange - const { wrapper } = getMountedComponent({}); + const initialDataForTest = { + isPageLoading: false + }; + const { wrapper } = getMountedComponent({}, initialDataForTest); // Act const secondaryText = wrapper.find({ ref: 'secondaryText' }); diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index c1c7abbd..e0475f47 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -10,7 +10,8 @@ cmsWidgetName="SiteHeaderWidget" />
-
+
Date: Wed, 18 Feb 2026 16:19:22 -0500 Subject: [PATCH 19/48] banner styling updates --- .../afterpay-modal-banner.vue | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue b/src/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue index 54ecc441..a56de829 100644 --- a/src/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue +++ b/src/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue @@ -3,20 +3,20 @@ src="https://js.squarecdn.com/square-marketplace.js" - async> + async> +
- - {{ afterpayPaymentAmount }} - + + {{ afterpayPaymentAmount }} + - .   + .   Learn more + class="afterpay-learn-more">Learn more
@@ -72,10 +72,10 @@ export default { imageUrl() { return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.IMAGE); }, - afterpayHeaderCopy() { + afterpayCopy() { return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT); }, - afterpaySubheaderCopy() { + afterpayCopyTwo() { return this.getCmsContent(this.cmsWidgetName, widgetFields.CONTENT_GROUP_WIDGET.SUBHEADER_TEXT); }, modalName() { @@ -114,33 +114,32 @@ export default { } .afterpay-content { - display: flex; - flex-direction: column; + display: block; + text-align: center; } .afterpay-copy { font-size: 0.875rem; color: $blue-700; font-weight: $font-weight-bold; - text-align: center; - flex-direction: column; } .image-and-link { - display: flex; justify-content: center; align-items: center; } .image { - flex-direction: column; border: 0; + height: 20px; + width: 83px; } -:deep(a.learn-more-link) { +:deep(a.afterpay-learn-more) { color: $blue-700; fill: $blue-700; text-decoration: underline; + font-size: 0.875rem; } .afterpay-modal { From 4e996145c3841825cb51d2abe164ad06a5d48dd4 Mon Sep 17 00:00:00 2001 From: Alex Humphries Date: Wed, 18 Feb 2026 16:22:35 -0500 Subject: [PATCH 20/48] INSR-7759: Update review sections, move contact details drawer --- src/constants/error-messages.js | 4 +- .../contact-details-drawer.spec.js.snap | 0 .../contact-details-drawer.spec.js | 2 +- .../contact-details-drawer.vue | 0 .../payment-method-list-button.vue | 17 +- src/layouts/payment-method/payment-method.vue | 46 +- .../review-block/review-block.vue | 55 +- .../review-dropdown/review-dropdown.vue | 94 +- .../customer-review/customer-review.vue | 21 +- .../damage-review/damage-review.spec.js | 80 -- .../damage-review/damage-review.vue | 47 - .../schedule-review/schedule-review.vue | 9 +- .../service-location-review.vue | 14 +- .../service-package-review.spec.js | 965 ------------------ .../service-package-review.vue | 100 -- .../vehicle-review/vehicle-review.vue | 38 +- src/layouts/tpa-submit/tpa-submit.vue | 2 +- .../router-constants/navigation-scenarios.js | 3 + src/router/router-constants/routing-table.js | 16 + src/styles/ux-variables.scss | 3 + 20 files changed, 219 insertions(+), 1297 deletions(-) rename src/{layouts/tpa-submit => iss-components}/contact-details-drawer/__snapshots__/contact-details-drawer.spec.js.snap (100%) rename src/{layouts/tpa-submit => iss-components}/contact-details-drawer/contact-details-drawer.spec.js (98%) rename src/{layouts/tpa-submit => iss-components}/contact-details-drawer/contact-details-drawer.vue (100%) delete mode 100644 src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.spec.js delete mode 100644 src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue delete mode 100644 src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.spec.js delete mode 100644 src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 66aa697a..62e79340 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -70,9 +70,7 @@ const errorMessages = Object.freeze({ TPA_SEARCH_SHOP_FORMAT: 'Please enter a valid shop name.', TPA_SEARCH_REQUIRED: 'Please enter a shop name or ZIP code.', SERVICE_ADDRESS_REQUIRED: 'Service street address is required.', - SERVICE_CITY_REQUIRED: 'Service city is required.', - - PAYMENT_METHOD_PAGE_OPTION_REQUIRED: 'Please select an Option', + SERVICE_CITY_REQUIRED: 'Service city is required.' }); export default errorMessages; diff --git a/src/layouts/tpa-submit/contact-details-drawer/__snapshots__/contact-details-drawer.spec.js.snap b/src/iss-components/contact-details-drawer/__snapshots__/contact-details-drawer.spec.js.snap similarity index 100% rename from src/layouts/tpa-submit/contact-details-drawer/__snapshots__/contact-details-drawer.spec.js.snap rename to src/iss-components/contact-details-drawer/__snapshots__/contact-details-drawer.spec.js.snap diff --git a/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js b/src/iss-components/contact-details-drawer/contact-details-drawer.spec.js similarity index 98% rename from src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js rename to src/iss-components/contact-details-drawer/contact-details-drawer.spec.js index 04fe6ce6..dd30a043 100644 --- a/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.spec.js +++ b/src/iss-components/contact-details-drawer/contact-details-drawer.spec.js @@ -1,7 +1,7 @@ // Components import { shallowMount } from '@vue/test-utils'; import { createTestingPinia } from '@pinia/testing'; -import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue'; +import contactDetailsDrawer from '@/iss-components/contact-details-drawer/contact-details-drawer.vue'; // Supporting Files import { getMountOptions } from '@/helpers/unit-test-helper.js'; diff --git a/src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue b/src/iss-components/contact-details-drawer/contact-details-drawer.vue similarity index 100% rename from src/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue rename to src/iss-components/contact-details-drawer/contact-details-drawer.vue diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue index c3601cbf..6bd161eb 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue @@ -2,7 +2,7 @@ + buttonWrapperClasses="list-group base-input-button list-button payment-method d-flex flex-column w-100 no-hover">
diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 73079f0b..ea76e31b 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -21,8 +21,10 @@ cmsWidgetName="SiteSubHeaderWidget" />

- -
+
{{ cartHeaderText }} {{ cartTotal }} @@ -104,6 +106,7 @@ import paymentMethodQuestion from '@/layouts/payment-method/payment-method-quest import alert from '@/ux-components/alert/alert.vue'; import textBlock from '@/digital-components/text-block/text-block.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue'; +import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue'; // Supporting Items import settleAllPromises from '@/helpers/layout-helper'; @@ -112,7 +115,7 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { paymentMethods } from '@/constants/payment-method-constants'; import queryStrings from '@/constants/query-strings'; import globalRules from '@/constants/global-rules'; -import { defineRule, Form } from 'vee-validate'; +import { Form } from 'vee-validate'; import issPageValues from '@/router/router-constants/issPage-values'; import bailoutMessage from '@/constants/bailoutMessage'; import { AppointmentTypeStrings } from '@/constants/schedule-constants'; @@ -124,13 +127,8 @@ import { supportsApplePay } from '@/helpers/browser-helper'; import { getCartTotal } from '@/helpers/cart-helper'; import { formatAmountInDollars } from '@/helpers/text-helper'; import widgetFields from '@/constants/cms-widget-fields'; -import errorMessages from '@/constants/error-messages'; -import { required } from '@/helpers/validation-rules'; -import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue'; import MaskaFormattedMasks from '@/constants/maska-masks'; -defineRule('option-required', required(errorMessages.PAYMENT_METHOD_PAGE_OPTION_REQUIRED)); - export default { name: 'payment-method', components: { @@ -391,13 +389,43 @@ export default { const scenario = this.mainStore.isMobileAppointment ? this.navigationScenarios.CLICKED_BACK_MOBILE : this.navigationScenarios.CLICKED_BACK_INSHOP; - this.$router.navigate( + this.$router.navigateWithSpinner( scenario, this.$route ); }, getSMSPhoneFromStore() { return useMainStore().contactInfo.servicePhone; + }, + handleEditClicked(section) { + switch (section) { + case 'location': + this.$router.navigateWithSpinner( + this.navigationScenarios.EDIT_SERVICE_LOCATION, + this.$route + ); + break; + case 'schedule': + this.$router.navigateWithSpinner( + this.navigationScenarios.EDIT_SCHEDULE, + this.$route + ); + break; + case 'vehicle': + this.$router.navigateWithSpinner( + this.navigationScenarios.EDIT_VEHICLE, + this.$route + ); + break; + case 'customer': + break; + case 'wipers': + this.$router.navigateWithSpinner( + this.navigationScenarios.EDIT_WIPERS, + this.$route + ); + break; + } } } }; diff --git a/src/layouts/payment-method/review-dropdown/review-block/review-block.vue b/src/layouts/payment-method/review-dropdown/review-block/review-block.vue index 2b7cf661..1ed4ddda 100644 --- a/src/layouts/payment-method/review-dropdown/review-block/review-block.vue +++ b/src/layouts/payment-method/review-dropdown/review-block/review-block.vue @@ -1,34 +1,55 @@ diff --git a/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue index e0c615df..3b0a5fee 100644 --- a/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue +++ b/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue @@ -1,7 +1,8 @@ diff --git a/src/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue index 56bee25e..b0500009 100644 --- a/src/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue +++ b/src/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue @@ -1,10 +1,13 @@