Merge branch 'develop' into feature/INSR-7778

This commit is contained in:
SujathaAnishetty 2025-12-15 14:47:09 -05:00
commit 33b1ac796e
16 changed files with 206 additions and 128 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View file

@ -53,10 +53,10 @@ const errorMessages = Object.freeze({
POLICYHOLDER_LAST_NAME_REQUIRED: 'Please enter the policyholder last name', POLICYHOLDER_LAST_NAME_REQUIRED: 'Please enter the policyholder last name',
ACKNOWLEDGEMENT_REQUIRED: 'You must agree to the terms to continue', ACKNOWLEDGEMENT_REQUIRED: 'You must agree to the terms to continue',
YEAR_REQUIRED: 'Please select your vehicle year', YEAR_REQUIRED: 'Vehicle year is required.',
MAKE_REQUIRED: 'Please select your vehicle make', MAKE_REQUIRED: 'Vehicle make is required.',
MODEL_REQUIRED: 'Please select your vehicle model', MODEL_REQUIRED: 'Vehicle model is required.',
STYLE_REQUIRED: 'Please select your vehicle style', STYLE_REQUIRED: 'Vehicle style is required.',
MOBILE_LOCATION_REQUIRED: 'Please enter your service address', MOBILE_LOCATION_REQUIRED: 'Please enter your service address',
DATE_REQUIRED: 'Please select a date' DATE_REQUIRED: 'Please select a date'
}); });

View file

@ -2,20 +2,24 @@
<div <div
v-if="showModalContent" v-if="showModalContent"
class="container-fluid modal-loader"> class="container-fluid modal-loader">
<div class="row g-2 h-100 d-flex align-items-center"> <div class="modal-loader-background"></div>
<div class="container-fluid overflow-hidden"> <div class="modal-loader-content">
<div class="row h-100"> <div class="modal-loader-content-container">
<div class="col text-center tagbg mb-4"> <div class="modal-loader-spinner-container">
<div <div class="modal-loader-text">
class="spinner-border text-danger" Processing...
role="status"> </div>
<span class="visually-hidden">Loading...</span> <div
</div> class="modal-loader-spinner"
role="status">
<img
src="~@/assets/img/heritage-loader-blue.gif"
alt="Loading spinner" />
</div> </div>
</div> </div>
<div <div
v-if="showTextCarouselContent" v-if="showTextCarouselContent"
class="row"> class="row modal-loader-text-container">
<div class="col"> <div class="col">
<div class="text-container slide"> <div class="text-container slide">
<p <p
@ -94,71 +98,116 @@ export default {
@import "@/styles/ux-variables-svg-strings.scss"; @import "@/styles/ux-variables-svg-strings.scss";
.modal-loader { .modal-loader {
position: fixed; .modal-loader-background,
top: 0; .modal-loader-content {
left: 0; position: fixed;
right: 0; top: 0;
bottom: 0; left: 0;
z-index: 1057; right: 0;
width: 100%; bottom: 0;
height: 100%; width: 100%;
overflow-x: hidden; height: 100%;
overflow-y: auto; overflow-x: hidden;
outline: 0; overflow-y: auto;
background: $gray-100; outline: 0;
}
.tagbg { .modal-loader-background {
background-image: url($svg-loading-modal-image); z-index: 1057;
background-repeat: no-repeat; background: #000;
background-position: center center; opacity: 0.5;
background-size: 96px; }
.modal-loader-content {
z-index: 1058;
display: flex; display: flex;
justify-content: center; justify-content: flex-start;
align-items: center; align-items: center;
} flex-direction: column;
@include media-breakpoint-up(xs) {
.spinner-border { padding-top: 5rem;
width: 6.5rem;
height: 6.5rem;
border: 0.45em solid currentColor;
border-right-color: transparent;
}
.text-container {
display: flex;
width: 350px;
overflow: hidden;
white-space: nowrap;
margin: 0 auto;
position: relative;
&:after {
content: "";
background: rgb(245, 245, 245);
background: linear-gradient(
270deg,
rgba(245, 245, 245, 1) 0%,
rgba(245, 245, 245, 0) 5%,
rgba(245, 245, 245, 0) 95%,
rgba(245, 245, 245, 1) 100%
);
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
top: 0;
left: 0;
right: 0;
bottom: 0;
} }
&.slide p { @include media-breakpoint-up(md) {
animation: slide-in 20s ease-in-out 1s forwards 1; padding-top: 7rem;
} }
p { .modal-loader-content-container {
margin: 0 175px; min-width: 15rem; // 240px
transform: translateX(180px); min-height: 15rem; // 240px
font-weight: 600;
padding: 1rem 0;
display: flex;
align-items: flex-start;
justify-content: center;
background-color: #fff;
background-clip: padding-box;
outline: 0;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 0.375rem;
box-shadow: 0 .375rem 11rem rgba(0, 0, 0, .5);
.modal-loader-spinner-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #1574a1;
font-weight: 600;
.modal-loader-spinner {
margin-top: 0.75rem;
}
}
}
.tagbg {
background-image: url($svg-loading-modal-image);
background-repeat: no-repeat;
background-position: center center;
background-size: 96px;
display: flex;
justify-content: center;
align-items: center;
}
.text-container {
display: flex;
width: 350px;
overflow: hidden;
white-space: nowrap;
margin: 0 auto;
position: relative;
&:after {
content: "";
background: rgb(245, 245, 245);
background: linear-gradient(
270deg,
rgba(245, 245, 245, 1) 0%,
rgba(245, 245, 245, 0) 5%,
rgba(245, 245, 245, 0) 95%,
rgba(245, 245, 245, 1) 100%
);
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&.slide p {
animation: slide-in 20s ease-in-out 1s forwards 1;
}
p {
margin: 0 175px;
transform: translateX(180px);
}
} }
} }
} }
</style> </style>

View file

@ -49,6 +49,7 @@
<script> <script>
import textLink from '@/ux-components/text-link/text-link.vue'; import textLink from '@/ux-components/text-link/text-link.vue';
import buttonMain from '@/ux-components/button-main/button-main.vue'; import buttonMain from '@/ux-components/button-main/button-main.vue';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
export default { export default {
name: 'site-footer', name: 'site-footer',
@ -97,6 +98,10 @@ export default {
buttonClick() { buttonClick() {
// prevent keyboard input after button click // prevent keyboard input after button click
document.onkeydown = () => false; document.onkeydown = () => false;
if ((!this.disableForwardAction && !this.isForwardActionDisabled)) {
showIssLoadingModal(true);
}
this.$emit('forwardClicked'); this.$emit('forwardClicked');
}, },
linkClick() { linkClick() {

View file

@ -44,7 +44,7 @@ export default {
.progress-bar-header { .progress-bar-header {
padding-right: 0.3125rem; padding-right: 0.3125rem;
color: $progress-bar-color; color: $progress-bar-success-color;
font-weight: 600; font-weight: 600;
font-size: 0.875rem; font-size: 0.875rem;
line-height: 0.9375rem; line-height: 0.9375rem;
@ -63,9 +63,10 @@ export default {
margin-left: 0; margin-left: 0;
border-radius: $border-radius-pill; border-radius: $border-radius-pill;
overflow: visible; overflow: visible;
background-color: $progress-bar-background-color;
.progress-bar { .progress-bar {
background-color: $progress-bar-color; background-color: $progress-bar-success-color;
border-radius: $border-radius-pill 0 0 $border-radius-pill; border-radius: $border-radius-pill 0 0 $border-radius-pill;
overflow: visible; overflow: visible;
@ -78,7 +79,7 @@ export default {
margin-top: -1px; margin-top: -1px;
border: 0.125rem solid #ffffff; border: 0.125rem solid #ffffff;
border-radius: 50%; border-radius: 50%;
background-color: $progress-bar-color; background-color: $progress-bar-success-color;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
} }
} }

View file

@ -3,7 +3,7 @@
<div <div
class="subheader-primary d-flex overflow-hidden"> class="subheader-primary d-flex overflow-hidden">
<h5 <h5
:class="[justifySubheaderSubText, headerColor]" :class="[justifySubheader, headerColor]"
class="fw-normal mb-0 subheader-primary"> class="fw-normal mb-0 subheader-primary">
<span> <span>
{{ content }} {{ content }}
@ -15,13 +15,13 @@
</h5> </h5>
</div> </div>
<div <div
v-if="hasSubText" v-if="hasSecondaryText"
:class="[justifySubheader, subHeaderClasses, subHeaderMarginClasses]" :class="[justifySubheaderSecondaryText, subHeaderClasses, subHeaderMarginClasses]"
class="subheader-secondary d-flex align-items-center overflow-hidden"> class="subheader-secondary d-flex align-items-start overflow-hidden">
<p <p
class="dark-header" class="dark-header"
:class="[alternateFormatting, subTextClasses]"> :class="[alternateFormatting, secondaryTextClasses]">
<span v-html="subText"> </span> <span v-html="secondaryText"> </span>
</p> </p>
</div> </div>
</div> </div>
@ -49,7 +49,7 @@ export default {
hasBackButton: Boolean, hasBackButton: Boolean,
issContainingPage: String, issContainingPage: String,
justification: String, justification: String,
justificationSubText: String, justificationSecondaryText: String,
stripRteStyle: Boolean, stripRteStyle: Boolean,
subContentProperty: String, subContentProperty: String,
subHeaderClasses: String, subHeaderClasses: String,
@ -57,7 +57,7 @@ export default {
type: String, type: String,
default: 'mt-1' default: 'mt-1'
}, },
subTextClasses: String secondaryTextClasses: String
}, },
emits: ['click-event'], emits: ['click-event'],
computed: { computed: {
@ -67,33 +67,33 @@ export default {
this.contentProperty ?? 'SubHeaderText' this.contentProperty ?? 'SubHeaderText'
); );
}, },
subText() { secondaryText() {
let subTextFromCms = this.getCmsContent( let secondaryTextFromCms = this.getCmsContent(
this.cmsWidgetName, this.cmsWidgetName,
this.subContentProperty ?? 'SecondaryText' this.subContentProperty ?? 'SecondaryText'
); );
if (this.stripRteStyle) { if (this.stripRteStyle) {
subTextFromCms = stripRteStyle(subTextFromCms); secondaryTextFromCms = stripRteStyle(secondaryTextFromCms);
} }
let subText = ''; let secondaryText = '';
if (this.doesCopyContainRouterLink(subTextFromCms)) { if (this.doesCopyContainRouterLink(secondaryTextFromCms)) {
splitCopyOnCMSPlaceHolder(subTextFromCms).forEach((sc) => { splitCopyOnCMSPlaceHolder(secondaryTextFromCms).forEach((sc) => {
if (this.doesCopyContainRouterLink(sc)) { if (this.doesCopyContainRouterLink(sc)) {
subText += getRouterLinkHtmlStringFromCopy(sc); secondaryText += getRouterLinkHtmlStringFromCopy(sc);
} else { } else {
subText += sc; secondaryText += sc;
} }
}); });
} else { } else {
subText = subTextFromCms; secondaryText = secondaryTextFromCms;
} }
return subText ?? ''; return secondaryText ?? '';
}, },
hasSubText() { hasSecondaryText() {
return this.subText.length > 0; return this.secondaryText.length > 0;
}, },
backButtonAccessibleText() { backButtonAccessibleText() {
return this.getCmsContent( return this.getCmsContent(
@ -102,15 +102,15 @@ export default {
); );
}, },
headerColor() { headerColor() {
return this.subText ? 'dark-header' : 'light-header'; return this.secondaryText ? 'dark-header' : 'light-header';
}, },
justifySubheader() { justifySubheader() {
return this.justification?.toLowerCase() === 'left' return this.justification?.toLowerCase() === 'center'
? 'justify-content-left' ? 'justify-content-center'
: 'justify-content-center'; : 'justify-content-left';
}, },
justifySubheaderSubText() { justifySubheaderSecondaryText() {
return this.justificationSubText?.toLowerCase() === 'center' return this.justificationSecondaryText?.toLowerCase() === 'center'
? 'justify-content-center' ? 'justify-content-center'
: 'justify-content-left'; : 'justify-content-left';
}, },

View file

@ -15,7 +15,7 @@
<siteSubHeader <siteSubHeader
class="mb-5 mt-4 px-3" class="mb-5 mt-4 px-3"
cmsWidgetName="SiteSubHeaderWidget" cmsWidgetName="SiteSubHeaderWidget"
subTextClasses="text-center" secondaryTextClasses="text-center"
subHeaderClasses="mt-4" /> subHeaderClasses="mt-4" />
<div class="main-content-container"> <div class="main-content-container">
<hr class="my-0" /> <hr class="my-0" />

View file

@ -14,7 +14,7 @@
<div class="schedule-page-container iss-heritage-content-container-width"> <div class="schedule-page-container iss-heritage-content-container-width">
<siteSubHeader <siteSubHeader
cmsWidgetName="ScheduleSubHeaderWidget" cmsWidgetName="ScheduleSubHeaderWidget"
subTextClasses="text-center small sub-text" secondaryTextClasses="text-center small sub-text"
class="mt-4" /> class="mt-4" />
<template v-if="ChangeShopLink.length"> <template v-if="ChangeShopLink.length">
<textBlock <textBlock

View file

@ -53,6 +53,12 @@
class="my-5" class="my-5"
cmsWidgetName="AlertNoShopsWidget" cmsWidgetName="AlertNoShopsWidget"
alertClass="alert-warning" /> alertClass="alert-warning" />
<alert
v-if="displayBigTruckNoShops"
ref="alertBigTruckNoShops"
class="my-5"
cmsWidgetName="AlertBigTruckNoShopsWidget"
alertClass="alert-warning" />
<div class="appointment-type"> <div class="appointment-type">
<appointmentTypeQuestion <appointmentTypeQuestion
v-show="isAppointmentTypeDisplayed" v-show="isAppointmentTypeDisplayed"
@ -361,7 +367,10 @@ export default {
return this.zipContainsMilitaryBase && this.isServiceableMobile; return this.zipContainsMilitaryBase && this.isServiceableMobile;
}, },
displayNoShopsAlert() { displayNoShopsAlert() {
return !this.isServiceableInshop && !this.isServiceableMobile; return !this.isBigTruck && !this.isServiceableInshop && !this.isServiceableMobile;
},
displayBigTruckNoShops() {
return this.isBigTruck && !this.isServiceableInshop && !this.isServiceableMobile;
}, },
displayRecalibrationWarning() { displayRecalibrationWarning() {
return this.requiresInshopRecalibration; return this.requiresInshopRecalibration;
@ -381,6 +390,9 @@ export default {
return isNoComp || isITAC return isNoComp || isITAC
? this.navigationScenarios.CLICKED_BACK_CANNOT_REACH_TPA_FLOW ? this.navigationScenarios.CLICKED_BACK_CANNOT_REACH_TPA_FLOW
: this.navigationScenarios.CLICKED_BACK_CAN_REACH_TPA_FLOW; : this.navigationScenarios.CLICKED_BACK_CAN_REACH_TPA_FLOW;
},
isBigTruck() {
return this.mainStore.order.vehicle.isBigTruck;
} }
}, },
methods: { methods: {

View file

@ -112,16 +112,19 @@ export default {
const { feeItems } = store.order.lineItems; const { feeItems } = store.order.lineItems;
let availableLineItems = []; const availableLineItems = [];
if ( resultMap?.rainDefense?.length > 0 ) if (resultMap?.rainDefense?.length > 0) {
availableLineItems.push(resultMap.rainDefense); availableLineItems.push(resultMap.rainDefense);
}
if ( resultMap?.wipers?.length > 0 ) if (resultMap?.wipers?.length > 0) {
availableLineItems.push(...resultMap.wipers); availableLineItems.push(...resultMap.wipers);
}
if ( feeItems?.length > 0 ) if (feeItems?.length > 0) {
availableLineItems.push(...feeItems); availableLineItems.push(...feeItems);
}
let hasBailedOut = false; let hasBailedOut = false;
await store.getCombinedQuote(availableLineItems) await store.getCombinedQuote(availableLineItems)

View file

@ -3,8 +3,9 @@
v-model="selectedValue" v-model="selectedValue"
:options="values" :options="values"
disableAutoFill disableAutoFill
placeHolderText="Select an option" :placeHolderText="isDisabled ? '' : placeHolderText"
:isDisabled="!values.length" /> :cmsWidgetName="cmsWidgetName"
:isDisabled="isDisabled" />
</template> </template>
<script> <script>
@ -18,7 +19,8 @@ export default {
}, },
props: { props: {
modelValue: String, modelValue: String,
updateValues: Function updateValues: Function,
cmsWidgetName: String
}, },
emits: ['update:modelValue'], emits: ['update:modelValue'],
data() { data() {
@ -37,6 +39,12 @@ export default {
const newValue = newIndex != null && newIndex > -1 ? this.values[newIndex] : null; const newValue = newIndex != null && newIndex > -1 ? this.values[newIndex] : null;
this.$emit('update:modelValue', newValue); this.$emit('update:modelValue', newValue);
} }
},
isDisabled() {
return this.values.length === 0;
},
placeHolderText() {
return this.getCmsContent(this.cmsWidgetName, 'ButtonText');
} }
}, },
methods: { methods: {

View file

@ -1032,7 +1032,7 @@ export const useMainStore = defineStore({
}, },
getTpaProviders(zipCode, radius) { getTpaProviders(zipCode, radius) {
const { carId } = this.order.vehicle; const { carId, isBigTruck } = this.order.vehicle;
const damageType = this.damage.isRepair ? 'Repair' : 'Replace'; const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
const { parentAccountNumber } = this.order; const { parentAccountNumber } = this.order;
const partsWithRecal = getTopLevelGlassPartsWithRecal(this.order.lineItems.glassParts); const partsWithRecal = getTopLevelGlassPartsWithRecal(this.order.lineItems.glassParts);
@ -1043,6 +1043,7 @@ export const useMainStore = defineStore({
if (windshieldPartWithRecal) { if (windshieldPartWithRecal) {
url += `/${windshieldPartWithRecal.partNumber}`; url += `/${windshieldPartWithRecal.partNumber}`;
} }
url += `/${isBigTruck}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
globalMethods.callHttpClient({ globalMethods.callHttpClient({
@ -1242,16 +1243,9 @@ export const useMainStore = defineStore({
if (availableLineItems && availableLineItems.length > 0) { if (availableLineItems && availableLineItems.length > 0) {
const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order; const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order;
const availableLineItemsFiltered = availableLineItems.filter((lineItem) => { const availableLineItemsFiltered = availableLineItems.filter((lineItem) => !!(lineItem.partNumber));
if ( lineItem.partNumber )
return true;
else
return false;
});
const lineItemsWithOnlyPartNumbers = availableLineItemsFiltered.map((lineItem) => { const lineItemsWithOnlyPartNumbers = availableLineItemsFiltered.map((lineItem) => ({ partNumber: lineItem.partNumber }));
return {partNumber: lineItem.partNumber};
});
const payload = { const payload = {
ParentAccountNumber: this.order.parentAccountNumber, ParentAccountNumber: this.order.parentAccountNumber,

View file

@ -1930,6 +1930,8 @@ describe('Store', () => {
store.order.vehicle.carId = carId; store.order.vehicle.carId = carId;
const zipCode = getRandomString(6, 6); const zipCode = getRandomString(6, 6);
const radius = getRandomInt(5, 100); const radius = getRandomInt(5, 100);
const isBigTruck = false;
store.order.vehicle.isBigTruck = isBigTruck;
const expectedEndpoint = [ const expectedEndpoint = [
endpoints.GetProviders.url, endpoints.GetProviders.url,
zipCode, zipCode,
@ -1937,7 +1939,8 @@ describe('Store', () => {
radius, radius,
parentAccountNumber, parentAccountNumber,
'false', 'false',
carId carId,
isBigTruck
].join('/'); ].join('/');
// Act // Act

View file

@ -9,7 +9,8 @@
$accent-color: #09748b; $accent-color: #09748b;
$link: #09748b; $link: #09748b;
$svg-fill-color: '%2309748b'; // Color of calendar icon. Place HEX code *after* %23 $svg-fill-color: '%2309748b'; // Color of calendar icon. Place HEX code *after* %23
$progress-bar-color: #181643; $progress-bar-success-color: #1a1446;
$progress-bar-background-color: #ffffff;
svg, svg,
.modal-text { .modal-text {
@ -29,15 +30,17 @@
.progress-bar-container { .progress-bar-container {
.progress-bar-header { .progress-bar-header {
color: $progress-bar-color; color: $progress-bar-success-color;
} }
.progress { .progress {
background-color: $progress-bar-background-color;
.progress-bar { .progress-bar {
background-color: $progress-bar-color; background-color: $progress-bar-success-color;
.progress-bar-middle { .progress-bar-middle {
background-color: $progress-bar-color; background-color: $progress-bar-success-color;
} }
} }
} }

View file

@ -197,8 +197,7 @@ html {
.form-test-error { .form-test-error {
color: $red; color: $red;
font-size: 0.875rem; font-size: 1rem;
font-weight: 500;
} }
.form-test-invalid { .form-test-invalid {

View file

@ -156,7 +156,8 @@ $border-radius-lg: 0.5rem; //Used for buttons. Can be used for other things, of
$border-radius-pill: 50rem; $border-radius-pill: 50rem;
//Progress Bar Styling //Progress Bar Styling
$progress-bar-color: $green; $progress-bar-success-color: $green;
$progress-bar-background-color: #cacbcc;
//Spacing //Spacing
// 8 spacers available instead of the usual 5 // 8 spacers available instead of the usual 5