CASH-2880 | Make the loader show upon page load & Add loader to datepick
Reduce time that the spinner shows upon page load Add a loading animation to date-picker
This commit is contained in:
parent
5d8c5b44f5
commit
d9b8c0906e
2 changed files with 91 additions and 59 deletions
|
|
@ -14,23 +14,39 @@
|
|||
class="date-picker__track d-flex flex-grow-1"
|
||||
:class="{ 'date-picker__track--loading': isLoadingDates }"
|
||||
:style="isLoadingDates ? { '--card-count': windowSize } : null">
|
||||
<button
|
||||
v-for="(date, index) in visibleDates"
|
||||
:key="date.value"
|
||||
class="date-picker__day-card d-flex flex-column align-items-center justify-content-center"
|
||||
:class="{
|
||||
'date-picker__day-card--selected': isSelected(date.value),
|
||||
'date-picker__day-card--disabled': !date.isAvailable,
|
||||
'date-picker__day-card--loading': isLoadingDates,
|
||||
}"
|
||||
:style="isLoadingDates ? { '--card-index': index } : null"
|
||||
:disabled="!date.isAvailable || isLoadingDates"
|
||||
:aria-pressed="isSelected(date.value)"
|
||||
:aria-label="`${date.dayAbbr} ${date.monthAbbr} ${date.day}`"
|
||||
@click="selectDate(date)">
|
||||
<span class="date-picker__day-abbr">{{ date.dayAbbr }}</span>
|
||||
<span class="date-picker__day-date">{{ date.monthAbbr }} {{ date.day }}</span>
|
||||
</button>
|
||||
<template v-if="showLoadingPlaceholders">
|
||||
<div
|
||||
v-for="index in windowSize"
|
||||
:key="index"
|
||||
class="date-picker__day-card date-picker__day-card--loading d-flex flex-column align-items-center justify-content-center"
|
||||
:style="{ '--card-index': index - 1 }"
|
||||
aria-hidden="true">
|
||||
<!-- Placeholder text is intentionally non-empty so the spans occupy the
|
||||
same height as real content. The --loading CSS hides them via
|
||||
visibility:hidden, so they are never visible to users. -->
|
||||
<span class="date-picker__day-abbr">MON</span>
|
||||
<span class="date-picker__day-date">Jan 00</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button
|
||||
v-for="(date, index) in visibleDates"
|
||||
:key="date.value"
|
||||
class="date-picker__day-card d-flex flex-column align-items-center justify-content-center"
|
||||
:class="{
|
||||
'date-picker__day-card--selected': isSelected(date.value),
|
||||
'date-picker__day-card--disabled': !date.isAvailable,
|
||||
'date-picker__day-card--loading': isLoadingDates,
|
||||
}"
|
||||
:style="isLoadingDates ? { '--card-index': index } : null"
|
||||
:disabled="!date.isAvailable || isLoadingDates"
|
||||
:aria-pressed="isSelected(date.value)"
|
||||
:aria-label="`${date.dayAbbr} ${date.monthAbbr} ${date.day}`"
|
||||
@click="selectDate(date)">
|
||||
<span class="date-picker__day-abbr">{{ date.dayAbbr }}</span>
|
||||
<span class="date-picker__day-date">{{ date.monthAbbr }} {{ date.day }}</span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
<button
|
||||
class="date-picker__nav-btn"
|
||||
|
|
@ -115,6 +131,9 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
showLoadingPlaceholders() {
|
||||
return this.isLoadingDates && !this.allDates.length;
|
||||
},
|
||||
allDates() {
|
||||
if (this.availableDates === null) return [];
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
@zip-code-clicked="onMobileZipCodeClicked" />
|
||||
<inshopSchedulingCard
|
||||
v-for="{ provider } in inShopProvidersAndTimeslots"
|
||||
v-show="selectedDate"
|
||||
v-show="showInshopSchedulingCards"
|
||||
:key="provider.providerNumber"
|
||||
class="mt-4"
|
||||
v-model="selectedScheduling"
|
||||
|
|
@ -138,17 +138,6 @@ export default {
|
|||
async beforeRouteEnter(to, from, next) {
|
||||
const serviceZipCode = store.getters.order.serviceLocation.zipCode;
|
||||
|
||||
const shopProviderData = await store.dispatch("getProviders", {
|
||||
payload: { serviceZipCode },
|
||||
pageNameToLog: to.name,
|
||||
});
|
||||
// Get the first 3 providers from the shopProviderData
|
||||
const providers = shopProviderData?.data?.shopProviders?.slice(0, 3) ?? [];
|
||||
const mobileProviderNumber = shopProviderData?.data?.mobileProviderNumber ?? null;
|
||||
|
||||
const startDate = toDateString(0);
|
||||
const endDate = toDateString(SCHEDULE_FETCH_DAYS - 1);
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: "cmsContent",
|
||||
|
|
@ -160,45 +149,64 @@ export default {
|
|||
pageNameToLog: to.name,
|
||||
}),
|
||||
},
|
||||
...providers.map((provider, i) => ({
|
||||
resultKey: `inshopTimeSlots_${i}`,
|
||||
promise: fetchInshopTimeSlots({
|
||||
startDate,
|
||||
endDate,
|
||||
providerNumber: provider.providerNumber,
|
||||
{
|
||||
resultKey: "providers",
|
||||
promise: store.dispatch("getProviders", {
|
||||
payload: { serviceZipCode },
|
||||
pageNameToLog: to.name,
|
||||
}),
|
||||
})),
|
||||
// Get the mobile time slots if a mobile provider number is available
|
||||
...(mobileProviderNumber
|
||||
? [
|
||||
{
|
||||
resultKey: "mobileTimeSlots",
|
||||
promise: fetchMobileTimeSlots({
|
||||
startDate,
|
||||
endDate,
|
||||
zipCode: serviceZipCode,
|
||||
pageNameToLog: to.name,
|
||||
}),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
},
|
||||
];
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
next((vm) => {
|
||||
// Get the first 3 providers from the shopProviderData
|
||||
const providers = resultMap.providers?.shopProviders?.slice(0, 3) ?? [];
|
||||
const mobileProviderNumber = resultMap.providers?.mobileProviderNumber ?? null;
|
||||
next(async (vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.inShopProvidersAndTimeslots = providers.map((provider, i) => ({
|
||||
vm.inShopProvidersAndTimeslots = providers.map((provider) => ({
|
||||
provider,
|
||||
timeSlots: resultMap[`inshopTimeSlots_${i}`] ?? null,
|
||||
timeSlots: null,
|
||||
}));
|
||||
vm.mobileProviderAndTimeSlot = mobileProviderNumber
|
||||
? {
|
||||
providerNumber: mobileProviderNumber,
|
||||
timeSlots: resultMap.mobileTimeSlots ?? null,
|
||||
}
|
||||
? { providerNumber: mobileProviderNumber, timeSlots: null }
|
||||
: null;
|
||||
const startDate = toDateString(0);
|
||||
const endDate = toDateString(SCHEDULE_FETCH_DAYS - 1);
|
||||
const timeSlotsPromiseResultMap = [
|
||||
...providers.map((provider, i) => ({
|
||||
resultKey: `inshopTimeSlots_${i}`,
|
||||
promise: fetchInshopTimeSlots({
|
||||
startDate,
|
||||
endDate,
|
||||
providerNumber: provider.providerNumber,
|
||||
pageNameToLog: to.name,
|
||||
}),
|
||||
})),
|
||||
// Get the mobile time slots if a mobile provider number is available
|
||||
...(mobileProviderNumber
|
||||
? [
|
||||
{
|
||||
resultKey: "mobileTimeSlots",
|
||||
promise: fetchMobileTimeSlots({
|
||||
startDate,
|
||||
endDate,
|
||||
zipCode: serviceZipCode,
|
||||
pageNameToLog: to.name,
|
||||
}),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
const timeSlotsResultMap = await settleAllPromises(timeSlotsPromiseResultMap);
|
||||
vm.inShopProvidersAndTimeslots.forEach((entry, i) => {
|
||||
entry.timeSlots = timeSlotsResultMap[`inshopTimeSlots_${i}`] ?? null;
|
||||
});
|
||||
if (vm.mobileProviderAndTimeSlot) {
|
||||
vm.mobileProviderAndTimeSlot.timeSlots = timeSlotsResultMap.mobileTimeSlots ?? null;
|
||||
}
|
||||
vm.datesLoaded = true;
|
||||
vm.mobilePremiumAppointmentFee = resultMap.mobilePremiumFee ?? null;
|
||||
vm.isLoadingDates = false;
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -217,7 +225,12 @@ export default {
|
|||
return store.getters.order.serviceLocation.zipCode;
|
||||
},
|
||||
showMobileSchedulingCard() {
|
||||
return Boolean(this.mobileProviderAndTimeSlot && this.selectedDate);
|
||||
return Boolean(
|
||||
this.mobileProviderAndTimeSlot && (this.selectedDate || this.isLoadingDates)
|
||||
);
|
||||
},
|
||||
showInshopSchedulingCards() {
|
||||
return this.selectedDate || this.isLoadingDates;
|
||||
},
|
||||
mobileTimeSlotsForSelectedDate() {
|
||||
if (!this.selectedDate) {
|
||||
|
|
@ -251,7 +264,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
selectedDate: null,
|
||||
isLoadingDates: false,
|
||||
isLoadingDates: true,
|
||||
datesLoaded: false,
|
||||
datePickerStartDate: toDateString(0),
|
||||
datePickerEndDate: toDateString(SCHEDULE_FETCH_DAYS - 1),
|
||||
|
|
|
|||
Loading…
Reference in a new issue