Adding string replace methods to alert widget
This commit is contained in:
parent
4e7debe2fb
commit
b41db74fd4
5 changed files with 174 additions and 24 deletions
|
|
@ -40,12 +40,15 @@ export function fetchCmsContentForPage(fmgPage) {
|
||||||
function mapStringToState(str) {
|
function mapStringToState(str) {
|
||||||
// Pull all matches out of the string.
|
// Pull all matches out of the string.
|
||||||
const regexExp = new RegExp("{(.*?):(.*?)}", "g");
|
const regexExp = new RegExp("{(.*?):(.*?)}", "g");
|
||||||
const matches = [...str.matchAll(regexExp)];
|
const regexMatches = [...str.matchAll(regexExp)];
|
||||||
|
const globalStateMatches = regexMatches.filter(match => {
|
||||||
|
return match[1] === "globalState";
|
||||||
|
})
|
||||||
|
|
||||||
// Our final string value that will be built from the matches.
|
// Our final string value that will be built from the matches.
|
||||||
let stringBuilder = "";
|
let stringBuilder = "";
|
||||||
|
|
||||||
for (const match of matches) {
|
for (const match of globalStateMatches) {
|
||||||
// Reset store state for each match.
|
// Reset store state for each match.
|
||||||
let storeState = store.state;
|
let storeState = store.state;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita
|
||||||
return 'vehicle-damage';
|
return 'vehicle-damage';
|
||||||
//return "vin-lookup"; (uncomment)
|
//return "vin-lookup"; (uncomment)
|
||||||
} else {
|
} else {
|
||||||
return 'license-plate-lookup';
|
return 'vehicle-damage';
|
||||||
//return "estimate" (uncomment)
|
//return "estimate" (uncomment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,18 +27,21 @@
|
||||||
<alert
|
<alert
|
||||||
class="my-3"
|
class="my-3"
|
||||||
cmsWidgetName="NoServiceZipWidget"
|
cmsWidgetName="NoServiceZipWidget"
|
||||||
|
v-model="customAlertData"
|
||||||
v-if="newServiceZipRequired"
|
v-if="newServiceZipRequired"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
/>
|
/>
|
||||||
<alert
|
<alert
|
||||||
class="my-3"
|
class="my-3"
|
||||||
cmsWidgetName="NoMatchAlertWidget"
|
cmsWidgetName="NoMatchAlertWidget"
|
||||||
|
v-model="customAlertData"
|
||||||
v-if="vinNotValid"
|
v-if="vinNotValid"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
/>
|
/>
|
||||||
<alert
|
<alert
|
||||||
class="my-3"
|
class="my-3"
|
||||||
cmsWidgetName="MatchedDifferentVehicleAlertWidget"
|
cmsWidgetName="MatchedDifferentVehicleAlertWidget"
|
||||||
|
v-model="customAlertData"
|
||||||
v-if="vinDoesNotMatchCarId"
|
v-if="vinDoesNotMatchCarId"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
/>
|
/>
|
||||||
|
|
@ -105,7 +108,6 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
console.log(resultMap.cmsContent)
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -120,6 +122,7 @@ export default {
|
||||||
zip: '',
|
zip: '',
|
||||||
email: '',
|
email: '',
|
||||||
serviceZip: '',
|
serviceZip: '',
|
||||||
|
customAlertData: {}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -139,6 +142,7 @@ export default {
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
const zipValidation = this.serviceZip ? await this.validateZip(this.serviceZip) : await this.validateZip(this.zip);
|
const zipValidation = this.serviceZip ? await this.validateZip(this.serviceZip) : await this.validateZip(this.zip);
|
||||||
if (!zipValidation.data.isServiceable) {
|
if (!zipValidation.data.isServiceable) {
|
||||||
|
this.customAlertData.zip = this.zip;
|
||||||
this.$refs.funnelFooter.removeLoader();
|
this.$refs.funnelFooter.removeLoader();
|
||||||
this.newServiceZipRequired = true;
|
this.newServiceZipRequired = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -149,6 +153,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
if (vinLookup.data.vehicle.carId !== store.getters.vehicle.carId && !this.vinDoesNotMatchCarId) {
|
if (vinLookup.data.vehicle.carId !== store.getters.vehicle.carId && !this.vinDoesNotMatchCarId) {
|
||||||
|
this.customAlertData.vehicleInfo = vinLookup.data.vehicle;
|
||||||
this.$refs.funnelFooter.updateButtonText(`Continue with ${vinLookup.data.vin} ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}`);
|
this.$refs.funnelFooter.updateButtonText(`Continue with ${vinLookup.data.vin} ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}`);
|
||||||
this.$refs.funnelFooter.removeLoader();
|
this.$refs.funnelFooter.removeLoader();
|
||||||
this.vinDoesNotMatchCarId = true;
|
this.vinDoesNotMatchCarId = true;
|
||||||
|
|
@ -156,22 +161,22 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
let vin;
|
let vin;
|
||||||
let carInfo;
|
let vehicleInfo;
|
||||||
|
|
||||||
if(this.vinDoesNotMatchCarId) {
|
if(this.vinDoesNotMatchCarId) {
|
||||||
vin = vinLookup.data.vin;
|
vin = vinLookup.data.vin;
|
||||||
carInfo = vinLookup.data.vehicle;
|
vehicleInfo = vinLookup.data.vehicle;
|
||||||
} else {
|
} else {
|
||||||
vin = store.getters.vehicle.vin;
|
vin = store.getters.vehicle.vin;
|
||||||
carInfo = store.getters.vehicle;
|
vehicleInfo = store.getters.vehicle;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateStore(vin, carInfo, zipValidation.data.state);
|
this.updateStore(vin, vehicleInfo, zipValidation.data.state);
|
||||||
|
|
||||||
const partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(
|
const partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(
|
||||||
this.storeActions.GET_PARTS_OR_QUESTIONS,
|
this.storeActions.GET_PARTS_OR_QUESTIONS,
|
||||||
{
|
{
|
||||||
carId: carInfo.carId,
|
carId: vehicleInfo.carId,
|
||||||
glassArray: store.getters.damage.glassToReplace,
|
glassArray: store.getters.damage.glassToReplace,
|
||||||
zipCode: this.serviceZip ? this.serviceZip : this.zip,
|
zipCode: this.serviceZip ? this.serviceZip : this.zip,
|
||||||
vin: vin
|
vin: vin
|
||||||
|
|
@ -204,20 +209,20 @@ export default {
|
||||||
{ licensePlate: plate, licenseState: state }
|
{ licensePlate: plate, licenseState: state }
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
updateStore(vin, carInfo, registrationState) {
|
updateStore(vin, vehicleInfo, registrationState) {
|
||||||
// if(vehicleDamage){
|
// if(vehicleDamage){
|
||||||
// store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
// store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
// }
|
// }
|
||||||
store.commit(storeMutations.UPDATE_VEHICLE_VIN, vin);
|
store.commit(storeMutations.UPDATE_VEHICLE_VIN, vin);
|
||||||
store.commit(storeMutations.UPDATE_YEAR, carInfo.year);
|
store.commit(storeMutations.UPDATE_YEAR, vehicleInfo.year);
|
||||||
store.commit(storeMutations.UPDATE_MAKE, carInfo.make);
|
store.commit(storeMutations.UPDATE_MAKE, vehicleInfo.make);
|
||||||
store.commit(storeMutations.UPDATE_MODEL, carInfo.model);
|
store.commit(storeMutations.UPDATE_MODEL, vehicleInfo.model);
|
||||||
store.commit(storeMutations.UPDATE_STYLE, carInfo.style);
|
store.commit(storeMutations.UPDATE_STYLE, vehicleInfo.style);
|
||||||
store.commit(storeMutations.UPDATE_CAR_ID, carInfo.carId);
|
store.commit(storeMutations.UPDATE_CAR_ID, vehicleInfo.carId);
|
||||||
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, carInfo.category);
|
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, vehicleInfo.category);
|
||||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl);
|
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, vehicleInfo.imageUrl);
|
||||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber);
|
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, vehicleInfo.imageVifNumber);
|
||||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageColor);
|
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, vehicleInfo.imageColor);
|
||||||
store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE, this.licensePlate);
|
store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE, this.licensePlate);
|
||||||
store.commit(storeMutations.UPDATE_REGISTRATION_STATE, registrationState);
|
store.commit(storeMutations.UPDATE_REGISTRATION_STATE, registrationState);
|
||||||
store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, this.zip);
|
store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, this.zip);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { createStore } from 'vuex'
|
||||||
import alert from "./alert";
|
import alert from "./alert";
|
||||||
|
|
||||||
describe("alert.vue", () => {
|
describe("alert.vue", () => {
|
||||||
|
|
@ -9,6 +10,13 @@ describe("alert.vue", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
isDismissible: true
|
isDismissible: true
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
mixins: [mockMixin]
|
mixins: [mockMixin]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -24,6 +32,13 @@ describe("alert.vue", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
alertClass: 'warning'
|
alertClass: 'warning'
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
mixins: [mockMixin]
|
mixins: [mockMixin]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -33,6 +48,84 @@ describe("alert.vue", () => {
|
||||||
expect(wrapperDiv.classes()).toContain('warning')
|
expect(wrapperDiv.classes()).toContain('warning')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should return original string if no custom string notations added", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(alert, {
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [mockMixin]
|
||||||
|
});
|
||||||
|
|
||||||
|
const stringWithNoCustomAtrributes = wrapper.vm.checkForCustomStrings("Test string")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(stringWithNoCustomAtrributes).toEqual("Test string")
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return link when custom string notation with 'routerLink' included", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(alert, {
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [mockMixin]
|
||||||
|
});
|
||||||
|
|
||||||
|
const stringWithNoCustomAtrributes = wrapper.vm.checkForCustomStrings("{routerLink:clickedChangeVinLookupMethod,provide your VIN}")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(stringWithNoCustomAtrributes).toEqual("{routerLink:clickedChangeVinLookupMethod,provide your VIN}")
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return zip when custom string notation with 'custom' for zip is called.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(alert, {
|
||||||
|
propsData: {modelValue: {zip: "12345"}},
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [mockMixin]
|
||||||
|
});
|
||||||
|
|
||||||
|
const stringWithNoCustomAtrributes = wrapper.vm.checkForCustomStrings("{custom:zip}")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(stringWithNoCustomAtrributes).toEqual("12345")
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return custom datum specified when custom string notation with 'custom' for lookup is called.", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = shallowMount(alert, {
|
||||||
|
propsData: {modelValue: {vehicleInfo: {year: "2020"}}},
|
||||||
|
computed: {
|
||||||
|
alertCopy: {
|
||||||
|
get() {
|
||||||
|
return "TEST";
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [mockMixin]
|
||||||
|
});
|
||||||
|
|
||||||
|
const stringWithNoCustomAtrributes = wrapper.vm.checkForCustomStrings("{custom:plateLookupYear}")
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(stringWithNoCustomAtrributes).toEqual("2020")
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,16 @@
|
||||||
role="alert"
|
role="alert"
|
||||||
:class="[isDismissible ? 'alert-dismissible' : '', this.alertClass]"
|
:class="[isDismissible ? 'alert-dismissible' : '', this.alertClass]"
|
||||||
>
|
>
|
||||||
<p class="m-0 fw-bold small alert-heading">{{ alertHeadline }}</p>
|
<p class="m-0 fw-bold small alert-heading" v-html="alertHeadline"></p>
|
||||||
<p class="m-0 text-body small">{{ alertCopy }}</p>
|
<p v-if="alertCopy.includes('routerLink:')">
|
||||||
|
<template v-for="copy in alertCopy.split(/{(.*?)}/g)" :key="copy">
|
||||||
|
<span v-if="copy.includes('routerLink:')" class="m-0 text-body small">
|
||||||
|
<router-link :to="{query: {fmgPage: `${copy.split(':')[1].split(',')[0]}`}, name: 'root'}">{{ copy.split(':')[1].split(',')[1] }}</router-link>
|
||||||
|
</span>
|
||||||
|
<span v-else class="m-0 text-body small">{{ copy }}</span>
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
<p v-else class="m-0 text-body small">{{ alertCopy }}</p>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn-close p-2"
|
class="btn-close p-2"
|
||||||
|
|
@ -26,6 +34,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "alert",
|
name: "alert",
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -41,15 +51,54 @@ export default {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
manualHeadline: String,
|
manualHeadline: String,
|
||||||
manualCopy: String,
|
manualCopy: String,
|
||||||
|
modelValue: {}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
alertHeadline(){
|
alertHeadline(){
|
||||||
return this.cmsWidgetName ? this.getCmsContent(this.cmsWidgetName, 'HeadlineText') : this.manualHeadline;
|
return this.cmsWidgetName ? this.checkForCustomStrings(this.getCmsContent(this.cmsWidgetName, 'HeadlineText')) : this.manualHeadline;
|
||||||
},
|
},
|
||||||
alertCopy(){
|
alertCopy(){
|
||||||
return this.cmsWidgetName ? this.getCmsContent(this.cmsWidgetName, 'BodyText') : this.manualCopy;
|
return this.cmsWidgetName ? this.checkForCustomStrings(this.getCmsContent(this.cmsWidgetName, 'BodyText')) : this.manualCopy;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
checkForCustomStrings(str){
|
||||||
|
let returnElement = "";
|
||||||
|
|
||||||
|
if(str.includes("{custom:")){
|
||||||
|
const regexExp = new RegExp("{(.*?)}", "g");
|
||||||
|
|
||||||
|
const splitOnSpecialData = str.split(regexExp);
|
||||||
|
for(const item of splitOnSpecialData){
|
||||||
|
let itemToAdd;
|
||||||
|
if(item.includes("custom:")){
|
||||||
|
const splitItem = item.split(":");
|
||||||
|
const customDataAttribute = splitItem[1].includes("plateLookup") ? splitItem[1].split("plateLookup")[1].toLowerCase() : splitItem[1];
|
||||||
|
switch(customDataAttribute){
|
||||||
|
case "damage":
|
||||||
|
itemToAdd = store.getters.damage.glassToReplace.length > 1 ? "match" : store.getters.damage.glassToReplace[0].location;
|
||||||
|
break;
|
||||||
|
case "zip":
|
||||||
|
itemToAdd = this.modelValue.zip;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
itemToAdd = this.modelValue.vehicleInfo[customDataAttribute];
|
||||||
|
}
|
||||||
|
} else if(item.includes("routerLink:")){
|
||||||
|
itemToAdd = `{${item}}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itemToAdd = item;
|
||||||
|
}
|
||||||
|
returnElement += itemToAdd;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
returnElement = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnElement;
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue