Merge branch 'develop' into feature/SSR-1023

This commit is contained in:
Katie Kroell 2023-12-05 09:06:04 -05:00
commit a0e60c1de2
6 changed files with 398 additions and 390 deletions

View file

@ -17,9 +17,30 @@ export function stripRteStyle(stringWithStyleTag) {
* @returns {string}
*/
export function toTitleCase(text) {
const temp = text.toLowerCase().split(' ');
const temp = text?.toLowerCase()?.split(' ') ?? [];
for (let i = 0; i < temp.length; i++) {
temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1);
}
return temp.join(' ');
}
/**
* @function toDisplayPhoneNumber
* @summary If 10 or 11 digits are in phoneNumber, then the expected number including dashes will be returned
* in either d-ddd-ddd-dddd or ddd-ddd-dddd format. Otherwise, an empty string will be returned.
* @param {string} phoneNumber
* @returns {string}
*/
export function toDisplayPhoneNumber(phoneNumber) {
let result = '';
if (!phoneNumber) { return result; }
let remainingDigits = phoneNumber.match(/\d+/g).join('');
if (remainingDigits.length === 11) {
result += `${remainingDigits[0]}-`;
remainingDigits = remainingDigits.substring(1);
}
if (remainingDigits.length === 10) {
result += remainingDigits.replace(/^(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
}
return result;
}

View file

@ -0,0 +1,42 @@
import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
describe('text-helper', () => {
test.each([
[undefined, ''],
[null, ''],
['', ''],
['hello world', 'Hello World'],
['hello world', 'Hello World'],
['HEllO worLD', 'Hello World'],
['a991,,:A froG FAMILY', 'A991,,:a Frog Family']
])(
'toTitleCase given "%p" returns "%p"',
(input, expected) => {
// Act
const result = toTitleCase(input);
// Assert
expect(result).toEqual(expected);
}
);
test.each([
[undefined, ''],
[null, ''],
['', ''],
['119', ''],
['1111999900', '111-199-9900'],
['111199-9900', '111-199-9900'],
['111-199-9900', '111-199-9900'],
['01111999900', '0-111-199-9900'],
['0-111-199-9900', '0-111-199-9900']
])(
'getDisplayPhoneNumber',
(input, expected) => {
// Act
const result = toDisplayPhoneNumber(input);
// Assert
expect(result).toEqual(expected);
}
);
});

View file

@ -5,25 +5,11 @@ Object {
"additionalButtonData": Object {
"displayAvailabilityIndicators": false,
},
"dataLoaded": false,
"filter": "",
"initialLoading": false,
"mapZipCode": "12663",
"providers": Array [],
"radiusFilterPairs": Array [
Object {
"filter": "25 miles",
"radius": 25,
},
Object {
"filter": "50 miles",
"radius": 50,
},
Object {
"filter": "100 miles",
"radius": 100,
},
],
"reloadProviders": false,
"reloadingProviders": false,
"rules": Object {
"filter": "option-required",
"provider": "option-required",

View file

@ -132,7 +132,7 @@ describe('TPA search page', () => {
// Assert
expect(searchQuestionField.exists()).toBeTruthy();
expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionField');
expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionFieldInput');
expect(searchQuestionField.props().isRequired).toBeTruthy();
expect(searchQuestionField.props().cmsWidgetName).toBe(expectedWidgetName);
expect(searchQuestionField.props().includeSearchIcon).toBeTruthy();
@ -150,18 +150,7 @@ describe('TPA search page', () => {
// Assert
expect(providerSelectionForm.exists()).toBeTruthy();
});
test('map loader when initialLoading is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: true });
// Act
const mapLoader = wrapper.findComponent('#mapLoader');
// Assert
expect(mapLoader.exists()).toBeTruthy();
});
test('map when initialLoading is false', async () => {
test('map', async () => {
// Arrange
const zipCode = '12345';
const { wrapper } = getMountedComponent();
@ -174,8 +163,7 @@ describe('TPA search page', () => {
zipCode: '99230'
}
}],
mapZipCode: zipCode,
initialLoading: false
mapZipCode: zipCode
});
const expectedAddresses = ['123 Lane Ave, New York, NY 99230'];
@ -188,10 +176,9 @@ describe('TPA search page', () => {
expect(map.props().addresses).toEqual(expectedAddresses);
expect(map.props().zipCode).toBe(zipCode);
});
test('search radius filter when initialLoading is false', async () => {
test('search radius filter', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false });
const expectedWidgetName = 'FilterByQuestion';
// Act
@ -202,10 +189,10 @@ describe('TPA search page', () => {
expect(searchRadiusFilter.props().cmsWidgetName).toBe(expectedWidgetName);
expect(searchRadiusFilter.props().validationRules).toBe(globalRules.OPTION_REQUIRED);
});
test('providers loader when initialLoading is false and reloadProviders is true', async () => {
test('providers loader when reloadingProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false, reloadProviders: true });
await wrapper.setData({ reloadingProviders: true });
// Act
const providersLoader = wrapper.findComponent('#providersLoader');
@ -213,7 +200,7 @@ describe('TPA search page', () => {
// Assert
expect(providersLoader.exists()).toBeTruthy();
});
test('select provider question when initialLoading and reloadProviders are false', async () => {
test('select provider question when reloadingProviders are false', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({
@ -229,8 +216,7 @@ describe('TPA search page', () => {
zipCode: '99230'
}
}],
initialLoading: false,
reloadProviders: false
reloadingProviders: false
});
const expectedAnswers = [{
buttonLabel: 'Shop Auto Glass',
@ -257,17 +243,14 @@ describe('TPA search page', () => {
expect(selectProviderQuestion.props().additionalButtonData).toEqual(expectedAdditionalButtonData);
});
test.each([[], null, undefined])(
'no network providers alert when providers length is 0, undefined, or null and initialLoading and reloadProviders are false',
'no network providers alert when providers length is 0, undefined, or null and reloadingProviders is false',
async (providers) => {
// Arrange
const initialData = {
providers
};
const wrapper = shallowMount(tpaSearch, getMountOptions({}, initialData));
await wrapper.setData({
initialLoading: false,
reloadProviders: false
});
await wrapper.setData({ reloadingProviders: false });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@ -279,13 +262,10 @@ describe('TPA search page', () => {
expect(noNetworkProvidersAlert.props().isDismissible).toBeFalsy();
}
);
test('preferred shop not listed link when initialLoading and reloadProviders are false', async () => {
test('preferred shop not listed link when reloadingProviders is false', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({
initialLoading: false,
reloadProviders: false
});
await wrapper.setData({ reloadingProviders: false });
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
@ -308,62 +288,16 @@ describe('TPA search page', () => {
});
});
describe('should not render', () => {
test('map loader when initialLoading is false', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false });
// Act
const mapLoader = wrapper.findComponent('#mapLoader');
// Assert
expect(mapLoader.exists()).toBeFalsy();
});
test('map when initialLoading is true', async () => {
test('select provider question when reloadingProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
await wrapper.setData({ reloadingProviders: true });
// Act
const map = wrapper.findComponent('#map');
const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
expect(map.exists()).toBeFalsy();
});
test('search radius filter when initialLoading is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
// Act
const searchRadiusFilter = wrapper.findComponent('#searchRadiusFilter');
// Assert
expect(searchRadiusFilter.exists()).toBeFalsy();
});
describe('select provider question', () => {
test('when initialLoading is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
// Act
const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
expect(selectProviderQuestion.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ reloadProviders: true });
// Act
const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
expect(selectProviderQuestion.exists()).toBeFalsy();
});
expect(selectProviderQuestion.exists()).toBeFalsy();
});
describe('no network providers alert', () => {
test('when providers length is not 0', async () => {
@ -377,21 +311,10 @@ describe('TPA search page', () => {
// Assert
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
test('when initialLoading is true', async () => {
test('when reloadingProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ providers: [], initialLoading: true });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
// Assert
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ providers: [], reloadProviders: true });
await wrapper.setData({ providers: [], reloadingProviders: true });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@ -400,29 +323,16 @@ describe('TPA search page', () => {
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
});
describe('preferred shop not listed link', () => {
test('when initialLoading is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
test('preferred shop not listed link when reloadingProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ reloadingProviders: true });
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
// Assert
expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ reloadProviders: true });
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
// Assert
expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
// Assert
expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
});
describe('computed', () => {
@ -538,41 +448,27 @@ describe('TPA search page', () => {
}
);
describe('radiusInMiles', () => {
test('returns 25 when filter is "25 miles"', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter: '25 miles' });
test.each([
[15, '15 miles'],
[25, '25 miles'],
[50, '50 miles'],
[100, '100 miles']
])(
'returns %p when filter is "%p"',
async (expectedRadius, filter) => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter });
// Act
const result = wrapper.vm.radiusInMiles;
// Act
const result = wrapper.vm.radiusInMiles;
// Assert
expect(result).toEqual(25);
});
test('returns 50 when filter is "50 miles"', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter: '50 miles' });
// Act
const result = wrapper.vm.radiusInMiles;
// Assert
expect(result).toEqual(50);
});
test('returns 100 when filter is "100 miles"', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter: '100 miles' });
// Act
const result = wrapper.vm.radiusInMiles;
// Assert
expect(result).toEqual(100);
});
// Assert
expect(result).toEqual(expectedRadius);
}
);
test.each([null, undefined, 'some random string'])(
'returns 0 when filter is not "25 miles", "50 miles", or "100 miles"',
'returns 0 when filter is "%p"',
async (filter) => {
// Arrange
const { wrapper } = getMountedComponent();
@ -787,7 +683,10 @@ describe('TPA search page', () => {
expect(result).toEqual(false);
}
);
test.each([[true, true], [false, false]])(
test.each([
[true, true],
[false, false]
])(
'returns %p when first instance of multiple matching providerNumbers has isSafeliteShop value %p',
async (expectedOutput, isSafeliteShop) => {
// Arrange
@ -803,7 +702,8 @@ describe('TPA search page', () => {
}
];
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ selectedProviderNumber, providers });
await wrapper.setData({ providers });
await wrapper.setData({ selectedProviderNumber });
// Act
const result = wrapper.vm.selectedProviderIsSafeliteShop;
@ -841,9 +741,10 @@ describe('TPA search page', () => {
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
zipCode,
mapZipCode: initialMapZipCode
mapZipCode: initialMapZipCode,
dataLoaded: true
});
const providers = { data: { shopProviders: ['some data', 'some more data']} };
const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter';
@ -855,6 +756,50 @@ describe('TPA search page', () => {
expect(wrapper.vm.providers).toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(zipCode);
});
describe('on filter', () => {
test('calls getTpaProviders once and sets providers when dataLoaded is true', async () => {
// Arrange
const zipCode = '78220';
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
zipCode,
mapZipCode: initialMapZipCode,
dataLoaded: true
});
const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter';
// Act
await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter);
// Assert
expect(useMainStore().getTpaProviders).toBeCalled();
expect(wrapper.vm.providers).toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(zipCode);
});
test('never calls getTpaProviders and does not set providers when dataLoaded is false', async () => {
// Arrange
const zipCode = '78220';
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
zipCode,
mapZipCode: initialMapZipCode,
dataLoaded: false
});
const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter';
// Act
await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter);
// Assert
expect(useMainStore().getTpaProviders).not.toBeCalled();
expect(wrapper.vm.providers).not.toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(initialMapZipCode);
});
});
// TODO confirm tests appropriate. Also should this method be async?
describe('on providers', () => {
test.each([null, undefined, []])(
@ -897,10 +842,10 @@ describe('TPA search page', () => {
});
describe('method', () => {
test.each([
['address', 'city', 'ST', 'zip', 'address, city, ST zip'],
['address', null, 'ST', 'zip', 'address, ST zip'],
['address', 'city', null, 'zip', 'address, city zip'],
['address', 'city', 'ST', null, 'address, city, ST'],
['address', 'city', 'ST', 'zip', 'Address, City, ST zip'],
['address', null, 'ST', 'zip', 'Address, ST zip'],
['address', 'city', null, 'zip', 'Address, City zip'],
['address', 'city', 'ST', null, 'Address, City, ST'],
[null, null, null, null, '']
])(
'getProviderAddress returns expected',
@ -1240,6 +1185,32 @@ describe('TPA search page', () => {
});
});
describe('before route enter', () => {
test('when providers exist at 15 mile radius, filter is set to "15 miles" and providers set to expected', async () => {
// Arrange
const { wrapper } = getMountedComponent();
const zipCode = '18394';
useMainStore().order.customer.address.zipCode = zipCode;
const providers = [{ companyName: 'provider' }];
useMainStore().getTpaProviders = jest.fn().mockImplementation((_, radius) =>
({ data: { shopProviders: radius === 15 ? providers : [] } }));
const expectedFilter = '15 miles';
// Act
await tpaSearch.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'tpa-search' } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(1);
});
test('when providers exist at 25 mile radius, filter is set to "25 miles" and providers set to expected', async () => {
// Arrange
const { wrapper } = getMountedComponent();
@ -1264,7 +1235,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(1);
expect(useMainStore().getTpaProviders).toBeCalledTimes(2);
});
test('when providers exist at 50 mile radius but not 25, filter is set to "50 miles" and providers set to expected', async () => {
// Arrange
@ -1290,7 +1261,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(2);
expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
});
test(
'when providers exist at 100 mile radius but not 50 or 25, filter is set to "100 miles" and providers set to expected',
@ -1318,7 +1289,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
}
);
test(
@ -1345,7 +1316,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual([]);
expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
}
);
});

View file

@ -26,95 +26,88 @@
<textboxQuestion
id="tpaSearchQuestionField"
v-model="zipCode"
inputId="tpaSearchQuestionField"
inputId="tpaSearchQuestionFieldInput"
:cmsWidgetName="widget.tpaSearchQuestion"
:includeSearchIcon="true"
:displayQuestionText="false"
isRequired
:isDisabled="reloadingProviders"
:validationRules="rules.zipCode"
@clickEvent="searchClick" />
</div>
</div>
</div>
</Form>
<loader
v-if="initialLoading"
id="mapLoader"
loaderPosition="center"
loaderColor="blue"
:width="4"
:height="4" />
<div v-else>
<googleMap
id="map"
class="mb-4"
:addresses="providerAddresses"
:zipCode="mapZipCode"></googleMap>
<Form
id="providerSelectionForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="container-fluid pb-2">
<div class="mx-5">
<dropdownQuestion
id="searchRadiusFilter"
v-model="filter"
:cmsWidgetName="widget.filterByQuestion"
inputId="filterByQuestionField"
:options="filterOptions"
disableAutoFill
:validationRules="rules.filter" />
<loader
v-if="reloadProviders"
id="providersLoader"
loaderPosition="center"
loaderColor="blue"
:width="4"
:height="4"
class="my-4" />
<div v-else>
<div class="my-4">
<buttonQuestion
id="selectProviderQuestion"
v-model="selectedProviderNumber"
buttonTypeString="shopListButton"
:buttonTypeObject="shopListButton"
class="radioQuestion"
:answers="providerButtonData"
groupName="chooseShop"
textPosition="text-start"
isRequired
:validationRules="rules.provider"
:additionalButtonData="additionalButtonData" />
<alert
v-if="providers?.length === 0 ?? true"
id="alertNoNetworkProviders"
:cmsWidgetName="widget.noNetworkShopsAlert"
alertClass="alert-warning"
:isDismissible="false"
:manualHeadline="noNetworkShopsAlertHeaderText" />
</div>
<div
class="text-center">
<textLink
id="preferredShopNotListedLink"
linkType="navigation"
href="#!"
:text="shopNotListedModalLink"
@clickEvent="doNotSeeMyShopLinkClick" />
</div>
<googleMap
id="map"
class="mb-4"
:addresses="providerAddresses"
:zipCode="mapZipCode"></googleMap>
<Form
id="providerSelectionForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalidSubmit="onInvalidSubmit">
<div class="container-fluid pb-2">
<div class="mx-5">
<dropdownQuestion
id="searchRadiusFilter"
v-model="filter"
:cmsWidgetName="widget.filterByQuestion"
inputId="searchRadiusFilterInput"
:options="filterOptions"
disableAutoFill
:isDisabled="reloadingProviders"
:validationRules="rules.filter" />
<loader
v-if="reloadingProviders"
id="providersLoader"
loaderPosition="center"
loaderColor="blue"
:width="2"
:height="2"
class="my-4" />
<div v-else>
<div class="my-4">
<buttonQuestion
id="selectProviderQuestion"
v-model="selectedProviderNumber"
buttonTypeString="shopListButton"
:buttonTypeObject="shopListButton"
class="radioQuestion"
:answers="providerButtonData"
groupName="chooseShop"
textPosition="text-start"
isRequired
:validationRules="rules.provider"
:additionalButtonData="additionalButtonData" />
<alert
v-if="providers?.length === 0 ?? true"
id="alertNoNetworkProviders"
:cmsWidgetName="widget.noNetworkShopsAlert"
alertClass="alert-warning"
:isDismissible="false"
:manualHeadline="noNetworkShopsAlertHeaderText" />
</div>
<div
class="text-center">
<textLink
id="preferredShopNotListedLink"
linkType="navigation"
href="#!"
:text="shopNotListedModalLink"
@clickEvent="doNotSeeMyShopLinkClick" />
</div>
</div>
<siteFooter
ref="siteFooter"
:cmsWidgetName="widget.siteFooter"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="backButtonAction" />
</div>
</Form>
</div>
<siteFooter
ref="siteFooter"
:cmsWidgetName="widget.siteFooter"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="backButtonAction" />
</div>
</Form>
</div>
</div>
</template>
@ -134,12 +127,40 @@ import loader from '@/ux-components/loader/loader.vue';
// Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import globalRules from '@/constants/global-rules.js';
import widgetFields from '@/constants/cms-widget-fields.js';
import { shallowRef } from 'vue';
import routerParams from '@/router/router-constants/router-params';
import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
const radiusFilterPairs = [
{ radius: 15, filter: '15 miles' },
{ radius: 25, filter: '25 miles' },
{ radius: 50, filter: '50 miles' },
{ radius: 100, filter: '100 miles' }
];
async function getInitialFilterAndProviders() {
const { zipCode } = useMainStore().order.customer.address;
let pairIndex = 0;
let providers = [];
let filter = '';
while (providers.length === 0 && pairIndex < radiusFilterPairs.length) {
const pair = radiusFilterPairs[pairIndex];
const { radius } = pair;
filter = pair.filter;
// eslint-disable-next-line no-await-in-loop
const result = await useMainStore().getTpaProviders(zipCode, radius);
providers = result?.data?.shopProviders ?? [];
pairIndex += 1;
}
return { filter, providers };
}
export default {
name: 'tpa-search',
@ -158,30 +179,25 @@ export default {
},
mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) {
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
const { filter, providers } = await getInitialFilterAndProviders();
const cmsContent = await fetchCmsContentForPage(to.query.issPage);
next(async (vm) => {
vm.setCmsContent(resultMap.cmsContent);
await vm.setInitialFilterAndProviders();
vm.setCmsContent(cmsContent);
vm.setFilter(filter);
vm.setProviders(providers);
});
},
data() {
const { zipCode } = useMainStore().order.customer.address;
return {
dataLoaded: false,
zipCode,
mapZipCode: zipCode,
filter: '',
providers: [],
selectedProviderNumber: '',
initialLoading: false,
reloadProviders: false,
reloadingProviders: false,
additionalButtonData: {
displayAvailabilityIndicators: false
},
@ -199,21 +215,7 @@ export default {
filter: globalRules.OPTION_REQUIRED, // TODO do we even need this?
provider: globalRules.OPTION_REQUIRED
},
shopListButton: shallowRef(shopListButton),
radiusFilterPairs: [
{
radius: 25,
filter: '25 miles'
},
{
radius: 50,
filter: '50 miles'
},
{
radius: 100,
filter: '100 miles'
}
]
shopListButton: shallowRef(shopListButton)
};
},
computed: {
@ -247,7 +249,7 @@ export default {
);
},
radiusInMiles() {
const pair = this.radiusFilterPairs.find((p) => p.filter === this.filter);
const pair = radiusFilterPairs.find((p) => p.filter === this.filter);
return pair?.radius ?? 0;
},
noNetworkShopsAlertHeaderText() {
@ -268,122 +270,108 @@ export default {
},
watch: {
async filter() {
if (!this.initialLoading) {
this.reloadProviders = true;
if (this.dataLoaded) {
await this.getProviderButtonData().then((providers) => {
this.providers = providers;
});
this.mapZipCode = this.zipCode;
this.reloadProviders = false;
} else {
this.initialLoading = false;
}
},
async providers(newProviders) {
if (newProviders?.length === 1 ?? false) {
this.selectedProviderNumber = newProviders[0]?.providerNumber ?? '';
}
providers(newProviders) {
this.selectedProviderNumber = newProviders?.length === 1 ?? false
? newProviders[0]?.providerNumber ?? ''
: '';
}
},
methods:
{
getProviderAddress(provider) {
const city = provider?.address?.city ?? '';
const state = provider?.address?.state ?? '';
const zipCode = provider?.address?.zipCode ?? '';
let addressLine2 = '';
if (city) {
addressLine2 = city;
if (state || zipCode) {
if (state) {
addressLine2 += ',';
}
addressLine2 += ' ';
}
}
if (state) {
addressLine2 += `${state}`;
if (zipCode) {
addressLine2 += ' ';
}
}
if (zipCode) {
addressLine2 += `${zipCode}`;
}
return provider?.address?.streetAddress
? `${provider.address.streetAddress}, ${addressLine2}`
: addressLine2;
},
async setInitialFilterAndProviders() {
this.initialLoading = true;
const { zipCode } = useMainStore().order.customer.address;
let pairIndex = 0;
let providers = [];
let filter = '';
while (providers.length === 0 && pairIndex < this.radiusFilterPairs.length) {
const pair = this.radiusFilterPairs[pairIndex];
const { radius } = pair;
filter = pair.filter;
// eslint-disable-next-line no-await-in-loop
const result = await useMainStore().getTpaProviders(zipCode, radius);
providers = result?.data?.shopProviders ?? [];
pairIndex += 1;
}
this.filter = filter;
this.providers = providers;
},
async getProviderButtonData() {
const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles);
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.$route
);
},
async searchClick() {
this.reloadProviders = true;
this.providers = await this.getProviderButtonData();
this.mapZipCode = this.zipCode;
this.reloadProviders = false;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
const scenario = this.selectedProviderIsSafeliteShop
? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP
: this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP;
this.$router.navigate(scenario, this.$route);
},
getCustomValueFromString(str) {
switch (str) {
case 'radiusInMiles':
return this.radiusInMiles;
default:
return null;
}
},
getShopButtonDataFromProvider(provider) {
const cellNumber = provider?.phoneNumber ?? '';
const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles))
? +provider.distanceInMiles.toFixed(1)
: null;
return {
buttonLabel: provider?.companyName ?? '',
buttonLabelSubCopy: distance === null
? ''
: `${distance} mi`,
buttonBodyCopy: `${this.getProviderAddress(provider)}<br>${cellNumber ?? ''}`,
value: provider?.providerNumber ?? ''
};
}
beforeUpdate() {
if (!this.dataLoaded) {
this.dataLoaded = true;
}
},
methods: {
setFilter(filter) {
this.filter = filter;
},
setProviders(providers) {
this.providers = providers;
},
getProviderAddress(provider) {
const city = toTitleCase(provider?.address?.city);
const state = provider?.address?.state ?? '';
const zipCode = provider?.address?.zipCode ?? '';
let addressLine2 = '';
if (city) {
addressLine2 += city;
if (state || zipCode) {
addressLine2 += state ? ', ' : ' ';
}
}
if (state) {
addressLine2 += state;
addressLine2 += zipCode ? ' ' : '';
}
if (zipCode) {
addressLine2 += zipCode;
}
const addressLine1 = this.toTitleCase(provider?.address?.streetAddress);
const joinString = addressLine1.length > 0 && addressLine2.length > 0 ? ', ' : '';
return [addressLine1, addressLine2].join(joinString);
},
async getProviderButtonData() {
this.reloadingProviders = true;
const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles);
this.reloadingProviders = false;
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.$route,
{},
{},
{ [routerParams.NOT_SEEING_PREFERRED_SHOP]: true }
);
},
async searchClick() {
this.providers = await this.getProviderButtonData();
this.mapZipCode = this.zipCode;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
const scenario = this.selectedProviderIsSafeliteShop
? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP
: this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP;
this.$router.navigate(scenario, this.$route);
},
getCustomValueFromString(str) {
switch (str) {
case 'radiusInMiles':
return this.radiusInMiles;
default:
return null;
}
},
getShopButtonDataFromProvider(provider) {
const cellNumber = this.toDisplayPhoneNumber(provider?.phoneNumber);
const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles))
? +provider.distanceInMiles.toFixed(1)
: null;
return {
buttonLabel: provider?.companyName ?? '',
buttonLabelSubCopy: distance === null
? ''
: `${distance} mi`,
buttonBodyCopy: `${this.getProviderAddress(provider)}<br>${cellNumber ?? ''}`,
value: provider?.providerNumber ?? ''
};
},
toDisplayPhoneNumber,
toTitleCase
}
};
</script>

View file

@ -186,7 +186,7 @@ router.overrideNavigation = (
isSavingNavigation,
optionalQuery = {},
optionalParams = {},
optionalPageData
optionalPageData = {}
) => {
navigate(
scenario,