Merge pull request #838 from Safelite/feature/richardson/SSR-1465
Updates for ITAC Coverage Statement redesign
This commit is contained in:
commit
7b40a8fcb2
7 changed files with 268 additions and 14 deletions
|
|
@ -35,17 +35,30 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer px-5 py-4">
|
<div class="modal-footer px-5 py-4">
|
||||||
<modalButtonMain
|
<modalButtonMain
|
||||||
|
v-if="useDefaultButton"
|
||||||
id="modalbtn"
|
id="modalbtn"
|
||||||
ref="modalButtonMain"
|
ref="modalButtonMain"
|
||||||
isPrimary
|
isPrimary
|
||||||
class="w-100"
|
class="w-100"
|
||||||
loaderColor="white"
|
loaderColor="white"
|
||||||
:buttonText="footerButtonText"
|
:buttonText="footerButtonText"
|
||||||
:class="
|
:class="[
|
||||||
(isButtonDisabled || isFooterButtonDisabled) &&
|
(isButtonDisabled || isFooterButtonDisabled) &&
|
||||||
'form-test-invalid'
|
'form-test-invalid',
|
||||||
"
|
additionalClassesString
|
||||||
|
]"
|
||||||
@clickEvent="validateAndEmit" />
|
@clickEvent="validateAndEmit" />
|
||||||
|
<button
|
||||||
|
v-if="!useDefaultButton"
|
||||||
|
class="w-100 btn d-flex align-items-center justify-content-center delay"
|
||||||
|
:class="[
|
||||||
|
(isButtonDisabled || isFooterButtonDisabled) &&
|
||||||
|
'form-test-invalid',
|
||||||
|
additionalClassesString
|
||||||
|
]"
|
||||||
|
@click="validateAndEmit">
|
||||||
|
<span class="m-0">{{ footerButtonText }}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,7 +86,15 @@ export default {
|
||||||
onModalClosedCallback: {
|
onModalClosedCallback: {
|
||||||
type: Function
|
type: Function
|
||||||
},
|
},
|
||||||
isButtonDisabled: Boolean
|
isButtonDisabled: Boolean,
|
||||||
|
useDefaultButton: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
additionalClassesString: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emits: ['footer-button-event', 'isModalOpened'],
|
emits: ['footer-button-event', 'isModalOpened'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
|
@ -181,6 +202,16 @@ export default {
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: $gray-100;
|
background-color: $gray-100;
|
||||||
|
|
||||||
|
> .navigation-link {
|
||||||
|
color: $black;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
line-height: 1.625rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: .3125rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.modal-component {
|
&.modal-component {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
exports[`coverageStatement.vue returns the initial data 1`] = `
|
exports[`coverageStatement.vue returns the initial data 1`] = `
|
||||||
Object {
|
Object {
|
||||||
|
"CANCEL_CLAIM_REF_NAME": "CancelClaimModal",
|
||||||
"DEDUCTIBLE_MODAL_REF_NAME": "DeductibleModal",
|
"DEDUCTIBLE_MODAL_REF_NAME": "DeductibleModal",
|
||||||
"RECAL_MODAL_REF_NAME": "RecalModal",
|
"RECAL_MODAL_REF_NAME": "RecalModal",
|
||||||
"SITE_FOOTER_REF_NAME": "siteFooter",
|
"SITE_FOOTER_REF_NAME": "siteFooter",
|
||||||
|
|
@ -12,6 +13,7 @@ Object {
|
||||||
},
|
},
|
||||||
"selectedProvider": "",
|
"selectedProvider": "",
|
||||||
"widget": Object {
|
"widget": Object {
|
||||||
|
"disclaimerText": "DisclaimerWidget",
|
||||||
"explanatoryText": "ExplanatoryTextWidget",
|
"explanatoryText": "ExplanatoryTextWidget",
|
||||||
"nextStep": "NextStepsWidget",
|
"nextStep": "NextStepsWidget",
|
||||||
"serviceProviderQuestion": "ServiceProviderQuestion",
|
"serviceProviderQuestion": "ServiceProviderQuestion",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`returns the initial data 1`] = `
|
||||||
|
Object {
|
||||||
|
"isLoaderDisplayed": false,
|
||||||
|
"isModalOpened": false,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import cancelClaimModal from '@/layouts/coverage-statement/cancel-claim-modal/cancel-claim-modal.vue';
|
||||||
|
|
||||||
|
const mockDataStrings = {
|
||||||
|
cmsBodyText: 'Some Body Text from CMS',
|
||||||
|
cmsBodyText2: 'Some Text for Button in Body from CMS',
|
||||||
|
cmsFooterText: 'Some Footer Text from CMS',
|
||||||
|
cmsHeaderText: 'Some Header Text from CMS'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCmsContent = {
|
||||||
|
BodyText: mockDataStrings.cmsBodyText,
|
||||||
|
BodyText2: mockDataStrings.cmsBodyText2,
|
||||||
|
FooterText: mockDataStrings.cmsFooterText,
|
||||||
|
HeaderText: mockDataStrings.cmsHeaderText
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((_, cmsFieldName) => mockCmsContent[cmsFieldName])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setupMocks() {
|
||||||
|
const wrapper = shallowMount(cancelClaimModal, {
|
||||||
|
mixins: [mockMixin],
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: 'test'
|
||||||
|
},
|
||||||
|
attachTo: document.body
|
||||||
|
});
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
test('returns the initial data', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.$data).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Computed', () => {
|
||||||
|
test('Should get modal body text from Widget CMS', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modalHeader = wrapper.vm.modalBodyText;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(modalHeader).toBe(mockDataStrings.cmsBodyText);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should get modal body text2 from Widget CMS', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modalHeader = wrapper.vm.modalBodyText2;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(modalHeader).toBe(mockDataStrings.cmsBodyText2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should get modal footer text from Widget CMS', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modalHeader = wrapper.vm.modalFooterText;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(modalHeader).toBe(mockDataStrings.cmsFooterText);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should get modal header text from Widget CMS', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const modalHeader = wrapper.vm.modalHeaderText;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(modalHeader).toBe(mockDataStrings.cmsHeaderText);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
|
<template>
|
||||||
|
<transition
|
||||||
|
name="fade"
|
||||||
|
mode="out-in">
|
||||||
|
<div class="cancel-claim-modal-container">
|
||||||
|
<modal
|
||||||
|
ref="cancelClaimModal"
|
||||||
|
:headerText="modalHeaderText"
|
||||||
|
:footerButtonText="modalFooterText"
|
||||||
|
additionalClassesString="navigation-link"
|
||||||
|
:useDefaultButton="false"
|
||||||
|
@isModalOpened="setModalStatus"
|
||||||
|
@footerButtonEvent="cancelClaimConfirmation">
|
||||||
|
<div v-html="modalBodyText"></div>
|
||||||
|
<button
|
||||||
|
id="btnContinueReferral"
|
||||||
|
type="button"
|
||||||
|
:aria-disabled="false"
|
||||||
|
class="btn btn-primary btn-override
|
||||||
|
align-items-center justify-content-center d-inline-flex mt-4 py-3 px-4 delay w-100"
|
||||||
|
@click="returnToClaim">
|
||||||
|
{{ modalBodyText2 }}
|
||||||
|
<loader
|
||||||
|
v-if="isLoaderDisplayed"
|
||||||
|
class="ms-2 button-loader" />
|
||||||
|
</button>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import loader from '@/ux-components/loader/loader.vue';
|
||||||
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'cancel-claim-modal',
|
||||||
|
components: {
|
||||||
|
loader,
|
||||||
|
modal
|
||||||
|
},
|
||||||
|
emits: ['cancel-claim-confirmation', 'return-to-claim'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoaderDisplayed: false,
|
||||||
|
isModalOpened: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
modalBodyText() {
|
||||||
|
return this.getCmsContent('CancelClaimModal', 'BodyText');
|
||||||
|
},
|
||||||
|
modalBodyText2() {
|
||||||
|
return this.getCmsContent('CancelClaimModal', 'BodyText2');
|
||||||
|
},
|
||||||
|
modalHeaderText() {
|
||||||
|
return this.getCmsContent('CancelClaimModal', 'HeaderText');
|
||||||
|
},
|
||||||
|
modalFooterText() {
|
||||||
|
return this.getCmsContent('CancelClaimModal', 'FooterText');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openModal() {
|
||||||
|
this.$refs.cancelClaimModal.openModal();
|
||||||
|
},
|
||||||
|
removeLoader() {
|
||||||
|
this.isLoaderDisplayed = false;
|
||||||
|
},
|
||||||
|
setModalStatus(isOpened) {
|
||||||
|
this.isModalOpened = isOpened;
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
this.$refs.cancelClaimModal.closeModal();
|
||||||
|
},
|
||||||
|
cancelClaimConfirmation() {
|
||||||
|
this.$emit('cancel-claim-confirmation');
|
||||||
|
},
|
||||||
|
returnToClaim() {
|
||||||
|
this.$emit('return-to-claim');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.btn {
|
||||||
|
&.btn-primary {
|
||||||
|
position: relative;
|
||||||
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
|
border: none;
|
||||||
|
border-radius: $border-radius-lg;
|
||||||
|
color: $white;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
@media (hover: hover) {
|
||||||
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -27,6 +27,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const SAFELITE_PROVIDER = 'Safelite';
|
const SAFELITE_PROVIDER = 'Safelite';
|
||||||
|
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
|
||||||
|
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -91,6 +92,7 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
const wrapper = shallowMount(coverageStatement, mountOptions);
|
const wrapper = shallowMount(coverageStatement, mountOptions);
|
||||||
|
wrapper.vm.$refs[CANCEL_CLAIM_REF_NAME].openModal = jest.fn();
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,9 @@
|
||||||
isRequired
|
isRequired
|
||||||
:validationRules="rules.selectionRequired">
|
:validationRules="rules.selectionRequired">
|
||||||
</buttonQuestion>
|
</buttonQuestion>
|
||||||
<text-block
|
<textBlock
|
||||||
v-if="isQuoteDisplayed"
|
v-if="isQuoteDisplayed"
|
||||||
cmsWidgetName="DisclaimerWidget"
|
:customText="disclaimerText"
|
||||||
typeStyle="caption" />
|
typeStyle="caption" />
|
||||||
<siteFooter
|
<siteFooter
|
||||||
:ref="SITE_FOOTER_REF_NAME"
|
:ref="SITE_FOOTER_REF_NAME"
|
||||||
|
|
@ -93,6 +93,10 @@
|
||||||
:ref="DEDUCTIBLE_MODAL_REF_NAME"
|
:ref="DEDUCTIBLE_MODAL_REF_NAME"
|
||||||
cmsWidgetName="DeductibleModal"
|
cmsWidgetName="DeductibleModal"
|
||||||
class="deductible-modal" />
|
class="deductible-modal" />
|
||||||
|
<cancelClaimModal
|
||||||
|
:ref="CANCEL_CLAIM_REF_NAME"
|
||||||
|
@cancelClaimConfirmation="cancelClaim"
|
||||||
|
@returnToClaim="continueClaim" />
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -101,6 +105,7 @@ import { Form } from 'vee-validate';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||||
import alert from '@/ux-components/alert/alert.vue';
|
import alert from '@/ux-components/alert/alert.vue';
|
||||||
|
import cancelClaimModal from '@/layouts/coverage-statement/cancel-claim-modal/cancel-claim-modal.vue';
|
||||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
||||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
|
|
@ -127,6 +132,7 @@ import { getPriceOfLineItems } from '@/helpers/price-calculator';
|
||||||
import coverageStatuses from '@/constants/coverage-statuses';
|
import coverageStatuses from '@/constants/coverage-statuses';
|
||||||
import coverageType from '@/constants/coverage-type';
|
import coverageType from '@/constants/coverage-type';
|
||||||
|
|
||||||
|
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
|
||||||
const SAFELITE_PROVIDER = 'Safelite';
|
const SAFELITE_PROVIDER = 'Safelite';
|
||||||
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
||||||
const DEDUCTIBLE_MODAL_REF_NAME = 'DeductibleModal';
|
const DEDUCTIBLE_MODAL_REF_NAME = 'DeductibleModal';
|
||||||
|
|
@ -140,6 +146,7 @@ export default {
|
||||||
// eslint-disable-next-line vue/no-reserved-component-names
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
Form,
|
Form,
|
||||||
alert,
|
alert,
|
||||||
|
cancelClaimModal,
|
||||||
contentGroupModal,
|
contentGroupModal,
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
textBlock
|
textBlock
|
||||||
|
|
@ -164,7 +171,7 @@ export default {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const { vehicle, isITAC, isDeductible, serviceLocation } = store;
|
const { isITAC, isDeductible, serviceLocation } = store;
|
||||||
if (isITAC || isDeductible) {
|
if (isITAC || isDeductible) {
|
||||||
promiseResultMap.push({
|
promiseResultMap.push({
|
||||||
resultKey: 'getFinalDeductible',
|
resultKey: 'getFinalDeductible',
|
||||||
|
|
@ -205,12 +212,14 @@ export default {
|
||||||
selectionRequired: globalRules.OPTION_REQUIRED
|
selectionRequired: globalRules.OPTION_REQUIRED
|
||||||
},
|
},
|
||||||
widget: {
|
widget: {
|
||||||
|
disclaimerText: 'DisclaimerWidget',
|
||||||
subheader: 'SiteSubHeaderWidget',
|
subheader: 'SiteSubHeaderWidget',
|
||||||
verifiedItacAlert: 'VerifiedITACAlert',
|
verifiedItacAlert: 'VerifiedITACAlert',
|
||||||
explanatoryText: 'ExplanatoryTextWidget',
|
explanatoryText: 'ExplanatoryTextWidget',
|
||||||
nextStep: 'NextStepsWidget',
|
nextStep: 'NextStepsWidget',
|
||||||
serviceProviderQuestion: 'ServiceProviderQuestion'
|
serviceProviderQuestion: 'ServiceProviderQuestion'
|
||||||
},
|
},
|
||||||
|
CANCEL_CLAIM_REF_NAME,
|
||||||
RECAL_MODAL_REF_NAME,
|
RECAL_MODAL_REF_NAME,
|
||||||
DEDUCTIBLE_MODAL_REF_NAME,
|
DEDUCTIBLE_MODAL_REF_NAME,
|
||||||
SITE_FOOTER_REF_NAME
|
SITE_FOOTER_REF_NAME
|
||||||
|
|
@ -237,7 +246,6 @@ export default {
|
||||||
widgetFields.ALERT_WIDGET.BODY_TEXT
|
widgetFields.ALERT_WIDGET.BODY_TEXT
|
||||||
)?.replaceAll(
|
)?.replaceAll(
|
||||||
'{custom:costSavings}',
|
'{custom:costSavings}',
|
||||||
|
|
||||||
formatAmountInDollars(itacCostSavings)
|
formatAmountInDollars(itacCostSavings)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -247,6 +255,12 @@ export default {
|
||||||
widgetFields.SUB_HEADER_WIDGET.SECONDARY_TEXT
|
widgetFields.SUB_HEADER_WIDGET.SECONDARY_TEXT
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
disclaimerText() {
|
||||||
|
return this.getCmsContent(this.widget.disclaimerText, widgetFields.TEXT_BLOCK_WIDGET.TEXT)?.replaceAll(
|
||||||
|
'{custom:disclaimerAmount}',
|
||||||
|
formatAmountInDollars(this.totalServicePrice)
|
||||||
|
);
|
||||||
|
},
|
||||||
explanatoryText() {
|
explanatoryText() {
|
||||||
return this.getTextFromCmsWithCustomIfStatements(
|
return this.getTextFromCmsWithCustomIfStatements(
|
||||||
this.widget.explanatoryText,
|
this.widget.explanatoryText,
|
||||||
|
|
@ -331,11 +345,9 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectedProvider() {
|
selectedProvider() {
|
||||||
const buttonText =
|
if (this.selectedProvider && this.selectedProvider !== SAFELITE_PROVIDER) {
|
||||||
this.selectedProvider === SAFELITE_PROVIDER
|
this.$refs[this.CANCEL_CLAIM_REF_NAME].openModal();
|
||||||
? 'Continue with Safelite'
|
}
|
||||||
: 'Continue';
|
|
||||||
this.$refs[SITE_FOOTER_REF_NAME].updateButtonText(buttonText);
|
|
||||||
},
|
},
|
||||||
nextStepsBody(newValue, oldValue) {
|
nextStepsBody(newValue, oldValue) {
|
||||||
if (newValue !== oldValue) {
|
if (newValue !== oldValue) {
|
||||||
|
|
@ -462,7 +474,16 @@ export default {
|
||||||
setBaseServiceLineItems(lineItems) {
|
setBaseServiceLineItems(lineItems) {
|
||||||
this.baseServiceLineItems = lineItems;
|
this.baseServiceLineItems = lineItems;
|
||||||
},
|
},
|
||||||
formatAmountInDollars
|
formatAmountInDollars,
|
||||||
|
cancelClaim() {
|
||||||
|
useMainStore().updateIsSafeliteProvider(false);
|
||||||
|
useMainStore().setBailout(bailoutMessage.RequestCallback());
|
||||||
|
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP);
|
||||||
|
},
|
||||||
|
continueClaim() {
|
||||||
|
useMainStore().updateIsSafeliteProvider(true);
|
||||||
|
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue