Merge branch 'develop' into feature/INSR-7778

This commit is contained in:
SujathaAnishetty 2025-12-11 10:49:13 -05:00
commit be19e1ecee
32 changed files with 110 additions and 580 deletions

View file

@ -2,8 +2,12 @@
<div <div
class="date-picker text-center" class="date-picker text-center"
:class="[calendarViewDirection, { 'has-error': errors.length > 0 }]"> :class="[calendarViewDirection, { 'has-error': errors.length > 0 }]">
<fieldset id="date-picker-fieldset" ref="datePickerFieldset"> <fieldset
<legend class="sr-only">Select a day and time</legend> id="date-picker-fieldset"
ref="datePickerFieldset">
<legend class="sr-only">
Select a day and time
</legend>
<div <div
v-for="month in months" v-for="month in months"
:id="`${month.monthLabel}-${month.yearNum?.toString()}`" :id="`${month.monthLabel}-${month.yearNum?.toString()}`"
@ -80,12 +84,12 @@
</label> </label>
</div> </div>
</div> </div>
<loader <div
:class="[!isLoading ? 'date-picker-hidden' : '']" id="date-of-month-error"
loaderColor="blue" class="row form-test-error">
loaderPosition="center" /> <ErrorMessage
<div id="date-of-month-error" class="row form-test-error"> :name="customComponentId"
<ErrorMessage :name="customComponentId" class="small mt-1"> class="small mt-1">
</ErrorMessage> </ErrorMessage>
</div> </div>
<button <button
@ -106,7 +110,6 @@
<script> <script>
// Supporting files // Supporting files
import loader from '@/ux-components/loader/loader.vue';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { useField, ErrorMessage } from 'vee-validate'; import { useField, ErrorMessage } from 'vee-validate';
import { deepClone } from '@/helpers/object-helper'; import { deepClone } from '@/helpers/object-helper';
@ -124,7 +127,6 @@ import { selectableDaysOptions, requiredParameter } from './mixins/helpers';
export default { export default {
name: 'date-picker', name: 'date-picker',
components: { components: {
loader,
ErrorMessage ErrorMessage
}, },
props: { props: {
@ -206,8 +208,8 @@ export default {
computed: { computed: {
todayString() { todayString() {
return ( return (
this.todayOverrideDateString || this.todayOverrideDateString
convertDateToDateString(new Date()) || convertDateToDateString(new Date())
); );
}, },
todayDayIndex() { todayDayIndex() {
@ -307,9 +309,7 @@ export default {
let weekEndDate = this.getWeekEndDate(todayString); let weekEndDate = this.getWeekEndDate(todayString);
if (preSelectedDateString) { if (preSelectedDateString) {
const preSelectedDateMonthEnd = this.getMonthEnd( const preSelectedDateMonthEnd = this.getMonthEnd(preSelectedDateString);
preSelectedDateString
);
let weekIncludesPreSelectedMonthEnd = false; let weekIncludesPreSelectedMonthEnd = false;
let i = 0; let i = 0;
while (!weekIncludesPreSelectedMonthEnd) { while (!weekIncludesPreSelectedMonthEnd) {
@ -318,10 +318,10 @@ export default {
weekEndDate = this.getWeekEndDate(weekStartDate); weekEndDate = this.getWeekEndDate(weekStartDate);
if ( if (
(preSelectedDateMonthEnd > weekStartDate && (preSelectedDateMonthEnd > weekStartDate
preSelectedDateMonthEnd < weekEndDate) || && preSelectedDateMonthEnd < weekEndDate)
preSelectedDateMonthEnd === weekStartDate || || preSelectedDateMonthEnd === weekStartDate
preSelectedDateMonthEnd === weekEndDate || preSelectedDateMonthEnd === weekEndDate
) { ) {
weekEndDate = preSelectedDateMonthEnd; weekEndDate = preSelectedDateMonthEnd;
weekIncludesPreSelectedMonthEnd = true; weekIncludesPreSelectedMonthEnd = true;
@ -349,8 +349,8 @@ export default {
// If any of these weeks is split between two months, then make them 2 separate "weeks" // If any of these weeks is split between two months, then make them 2 separate "weeks"
// (a week split between two months is considered 2 weeks per business requirements) // (a week split between two months is considered 2 weeks per business requirements)
const hasSplitWeek = (week) => const hasSplitWeek = (week) =>
week.weekStartDate.split('-')[1] !== week.weekStartDate.split('-')[1]
week.weekEndDate.split('-')[1]; !== week.weekEndDate.split('-')[1];
const splitWeekIndex = weeks.findIndex(hasSplitWeek); const splitWeekIndex = weeks.findIndex(hasSplitWeek);
if (splitWeekIndex > -1) { if (splitWeekIndex > -1) {
@ -359,9 +359,7 @@ export default {
let switchToWeek2 = false; let switchToWeek2 = false;
for (let j = 0; j < 7; j++) { for (let j = 0; j < 7; j++) {
const newDate = convertDateStringToDate( const newDate = convertDateStringToDate(weeks[splitWeekIndex].weekStartDate);
weeks[splitWeekIndex].weekStartDate
);
newDate.setDate(newDate.getDate() + j); newDate.setDate(newDate.getDate() + j);
if (newDate.getDate() === 1) switchToWeek2 = true; if (newDate.getDate() === 1) switchToWeek2 = true;
if (switchToWeek2) { if (switchToWeek2) {
@ -412,10 +410,8 @@ export default {
} else { } else {
todayDateString = convertDateToDateString(new Date()); todayDateString = convertDateToDateString(new Date());
} }
if (config.selectableDatesSetting === 'past') if (config.selectableDatesSetting === 'past') calendarViewDirection = 'past';
calendarViewDirection = 'past'; if (config.selectableDatesSetting === 'custom') calendarViewDirection = 'future';
if (config.selectableDatesSetting === 'custom')
calendarViewDirection = 'future';
const currentMonthEnd = this.getMonthEnd(todayDateString); const currentMonthEnd = this.getMonthEnd(todayDateString);
// TODO - set up currentMonthStart if direction is PAST: // TODO - set up currentMonthStart if direction is PAST:
@ -484,11 +480,9 @@ export default {
const direction = config.calendarViewDirection; const direction = config.calendarViewDirection;
const monthsAfterToLoadOffset = 6; const monthsAfterToLoadOffset = 6;
const monthsBeforeToLoadOffset = 36; const monthsBeforeToLoadOffset = 36;
config.initialShopTimeSlotsResponse.days.forEach( config.initialShopTimeSlotsResponse.days.forEach((selectableDate) => {
(selectableDate) => { this.selectableDatesData.push(selectableDate);
this.selectableDatesData.push(selectableDate); });
}
);
// GENERATE MONTHS AND PUSH THEM INTO ARRAY // GENERATE MONTHS AND PUSH THEM INTO ARRAY
const months = []; const months = [];
@ -524,11 +518,10 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
// Advance to month // Advance to month
const monthToShow = this.months.find((month) => const monthToShow = this.months.find((month) =>
month.monthClass.includes('month-preselected') month.monthClass.includes('month-preselected'));
);
if ( if (
monthToShow.monthClass.includes('month-preselected') && monthToShow.monthClass.includes('month-preselected')
monthToShow.monthClass.includes('last-available-month') && monthToShow.monthClass.includes('last-available-month')
) { ) {
// disable View More dates button if the preSelectedDate in the last available month // disable View More dates button if the preSelectedDate in the last available month
this.disableViewMoreDatesButton = true; this.disableViewMoreDatesButton = true;
@ -553,12 +546,10 @@ export default {
*/ */
let monthNum = let monthNum =
convertDateStringToDate(this.todayString).getMonth() + convertDateStringToDate(this.todayString).getMonth()
offset + + offset
1; + 1;
let yearNum = convertDateStringToDate( let yearNum = convertDateStringToDate(this.todayString).getFullYear();
this.todayString
).getFullYear();
const { calendarViewDirection } = options; const { calendarViewDirection } = options;
if (calendarViewDirection === 'future' && offset > 0) { if (calendarViewDirection === 'future' && offset > 0) {
while (monthNum > 12) { while (monthNum > 12) {
@ -595,18 +586,18 @@ export default {
let monthEndDateNum = monthEndDate.getDate(); let monthEndDateNum = monthEndDate.getDate();
if ( if (
offset === 0 && offset === 0
calendarViewDirection === 'past' && && calendarViewDirection === 'past'
monthEndDateNum > this.currentWeekEndDateNum && monthEndDateNum > this.currentWeekEndDateNum
) { ) {
monthEndDateNum = this.currentWeekEndDateNum; monthEndDateNum = this.currentWeekEndDateNum;
} }
if (options.preSelectedDate) { if (options.preSelectedDate) {
if ( if (
monthStartDate.getFullYear() === monthStartDate.getFullYear()
preSelectedDateObj.getFullYear() && === preSelectedDateObj.getFullYear()
monthStartDate.getMonth() === preSelectedDateObj.getMonth() && monthStartDate.getMonth() === preSelectedDateObj.getMonth()
) { ) {
monthClass += ' month-preselected'; monthClass += ' month-preselected';
} else if (monthStartDate > preSelectedDateObj) { } else if (monthStartDate > preSelectedDateObj) {
@ -619,14 +610,14 @@ export default {
} }
if ( if (
Math.abs(offset) === options.monthsAfterToLoadOffset && Math.abs(offset) === options.monthsAfterToLoadOffset
calendarViewDirection === 'future' && calendarViewDirection === 'future'
) { ) {
monthClass += ' last-available-month'; monthClass += ' last-available-month';
} }
if ( if (
Math.abs(offset) === options.monthsBeforeToLoadOffset && Math.abs(offset) === options.monthsBeforeToLoadOffset
calendarViewDirection === 'past' && calendarViewDirection === 'past'
) { ) {
// TODO - re-check this logic if past direction // TODO - re-check this logic if past direction
monthClass += ' last-available-month'; monthClass += ' last-available-month';
@ -635,24 +626,22 @@ export default {
// populate dates array // populate dates array
for (let i = monthStartDateNum; i <= monthEndDateNum; i++) { for (let i = monthStartDateNum; i <= monthEndDateNum; i++) {
let dayClasses = ''; let dayClasses = '';
const dateString = `${yearNum.toString()}-${`0${monthNum}`.slice( const dateString = `${yearNum.toString()}-${`0${monthNum}`.slice(-2)}-${`0${i}`.slice(-2)}`;
-2
)}-${`0${i}`.slice(-2)}`;
if (offset === 0 && i === this.todayDateNum) { if (offset === 0 && i === this.todayDateNum) {
dayClasses += ' current-day'; dayClasses += ' current-day';
} }
if ( if (
offset === 0 && offset === 0
i < this.todayDateNum && && i < this.todayDateNum
calendarViewDirection === 'future' && calendarViewDirection === 'future'
) { ) {
dayClasses += ' unavailable-day'; dayClasses += ' unavailable-day';
} }
if ( if (
offset === 0 && offset === 0
i > this.todayDateNum && && i > this.todayDateNum
calendarViewDirection === 'past' && calendarViewDirection === 'past'
) { ) {
dayClasses += ' unavailable-day'; dayClasses += ' unavailable-day';
} }
@ -660,11 +649,11 @@ export default {
dayClasses += ' sunday'; dayClasses += ' sunday';
} }
if ( if (
this.hideSomeDaysForInitialView && this.hideSomeDaysForInitialView
convertDateStringToDate(initialViewEndDate).getMonth() + && convertDateStringToDate(initialViewEndDate).getMonth()
1 === + 1
monthNum && === monthNum
convertDateStringToDate(initialViewEndDate).getDate() < i && convertDateStringToDate(initialViewEndDate).getDate() < i
) { ) {
dayClasses += ' day-hidden'; dayClasses += ' day-hidden';
isMonthThatHidesSomeDaysForInitialView = true; isMonthThatHidesSomeDaysForInitialView = true;
@ -674,9 +663,7 @@ export default {
dayClasses, dayClasses,
inputValue: dateString, inputValue: dateString,
isSelectable: isSelectable:
this.selectableDatesData.findIndex( this.selectableDatesData.findIndex((date) => date.date === dateString) > -1
(date) => date.date === dateString
) > -1
}; };
dates.push(dateObject); dates.push(dateObject);
} }
@ -701,26 +688,21 @@ export default {
let monthStartDateNum = 0; let monthStartDateNum = 0;
if (this.hideSomeDaysForInitialView) { if (this.hideSomeDaysForInitialView) {
monthToShow = this.months.find( monthToShow = this.months.find(({ isMonthThatHidesSomeDaysForInitialView }) =>
({ isMonthThatHidesSomeDaysForInitialView }) => isMonthThatHidesSomeDaysForInitialView);
isMonthThatHidesSomeDaysForInitialView
);
// find the first day-hidden to become the next api call start date // find the first day-hidden to become the next api call start date
monthStartDateNum = monthStartDateNum =
monthToShow.dates.find(({ dayClasses }) => monthToShow.dates.find(({ dayClasses }) =>
dayClasses.includes('day-hidden') dayClasses.includes('day-hidden')).dateNum - 1;
).dateNum - 1;
} else { } else {
if (this.calendarViewDirection === 'future') { if (this.calendarViewDirection === 'future') {
monthToShow = this.months.find((month) => monthToShow = this.months.find((month) =>
month.monthClass.includes('month-hidden') month.monthClass.includes('month-hidden'));
);
} }
if (this.calendarViewDirection === 'past') { if (this.calendarViewDirection === 'past') {
// TODO: UPDATE THIS WITH CORRECT PAST LOOKING LOGIC // TODO: UPDATE THIS WITH CORRECT PAST LOOKING LOGIC
monthToShow = this.months.find((month) => monthToShow = this.months.find((month) =>
month.monthClass.includes('month-hidden') month.monthClass.includes('month-hidden'));
);
} }
} }
if (monthToShow) { if (monthToShow) {
@ -737,8 +719,7 @@ export default {
); );
this.scrollToElement(monthToShow.monthString); this.scrollToElement(monthToShow.monthString);
if (monthToShow.monthClass.includes('last-available-month')) if (monthToShow.monthClass.includes('last-available-month')) this.disableViewMoreDatesButton = true;
this.disableViewMoreDatesButton = true;
} }
}, },
async updateSelectableDates(monthStart, monthEnd) { async updateSelectableDates(monthStart, monthEnd) {
@ -751,9 +732,7 @@ export default {
); );
moreSelectableDates.days.forEach((selectableDate) => { moreSelectableDates.days.forEach((selectableDate) => {
const index = this.selectableDatesData.findIndex( const index = this.selectableDatesData.findIndex((dateObj) => dateObj.date === selectableDate.date);
(dateObj) => dateObj.date === selectableDate.date
);
if (index === -1) this.selectableDatesData.push(selectableDate); if (index === -1) this.selectableDatesData.push(selectableDate);
this.months.forEach((month) => { this.months.forEach((month) => {
// TODO: avoid checking all calendar dates; maybe only ones between monthStart and monthEnd as defined above? // TODO: avoid checking all calendar dates; maybe only ones between monthStart and monthEnd as defined above?
@ -821,19 +800,6 @@ export default {
flex-grow: 1; flex-grow: 1;
position: relative; position: relative;
} }
.loader {
height: 2rem;
width: 100%;
display: flex;
justify-content: center;
transform: unset;
right: unset;
&::after {
width: 1.5rem;
height: 1.5rem;
}
}
.calendar-grid-container { .calendar-grid-container {
margin: 0 auto 2rem auto; margin: 0 auto 2rem auto;
max-width: 414px; max-width: 414px;

View file

@ -19,9 +19,6 @@
align-items-center justify-content-center d-inline-flex mt-2 py-3 px-4 delay w-100" align-items-center justify-content-center d-inline-flex mt-2 py-3 px-4 delay w-100"
@click="continueReferral"> @click="continueReferral">
{{ modalBodyText }} {{ modalBodyText }}
<loader
v-if="isLoaderDisplayed"
class="ms-2 button-loader" />
</button> </button>
</modal> </modal>
</div> </div>
@ -29,20 +26,17 @@
</template> </template>
<script> <script>
import loader from '@/ux-components/loader/loader.vue';
import modal from '@/digital-components/modal/modal.vue'; import modal from '@/digital-components/modal/modal.vue';
import { getISSCookie } from '@/helpers/cookie-helper.js'; import { getISSCookie } from '@/helpers/cookie-helper.js';
export default { export default {
name: 'continue-modal', name: 'continue-modal',
components: { components: {
loader,
modal modal
}, },
emits: ['continue-previous-referral', 'start-new-referral'], emits: ['continue-previous-referral', 'start-new-referral'],
data() { data() {
return { return {
isLoaderDisplayed: false,
isModalOpened: false isModalOpened: false
}; };
}, },
@ -69,9 +63,6 @@ export default {
openModal() { openModal() {
this.$refs.continueModal.openModal(); this.$refs.continueModal.openModal();
}, },
removeLoader() {
this.isLoaderDisplayed = false;
},
setModalStatus(isOpened) { setModalStatus(isOpened) {
this.isModalOpened = isOpened; this.isModalOpened = isOpened;
}, },
@ -79,7 +70,6 @@ export default {
this.$refs.continueModal.closeModal(); this.$refs.continueModal.closeModal();
}, },
continueReferral() { continueReferral() {
this.isLoaderDisplayed = true;
this.$emit('continue-previous-referral'); this.$emit('continue-previous-referral');
}, },
startNewReferral() { startNewReferral() {

View file

@ -63,7 +63,6 @@ export default {
.footer-menu-container { .footer-menu-container {
display: flex; display: flex;
border-top: solid 0.125rem #d3d3d3; border-top: solid 0.125rem #d3d3d3;
font-family: $font-family-urbanist-regular-400;
@include media-breakpoint-up(xs) { @include media-breakpoint-up(xs) {
padding: 1rem 0 1.25rem 0; // Heritage 1.250rem 0 padding: 1rem 0 1.25rem 0; // Heritage 1.250rem 0

View file

@ -294,32 +294,6 @@ describe('Shop list button', () => {
expect(availabilityIndicatorBlock.classes()).toContain('availability-indicator'); expect(availabilityIndicatorBlock.classes()).toContain('availability-indicator');
expect(availabilityIndicatorBlock.classes()).toContain('rounded-pill'); expect(availabilityIndicatorBlock.classes()).toContain('rounded-pill');
}); });
test('availability indicator loader when displayAvailabilityIndicators', async () => {
// Arrange
const additionalButtonData = {
displayAvailabilityIndicators: true,
availabilityRatingCallback: () => Promise.resolve(null)
};
const wrapper = mount(shopListButton, {
propsData: {
value: 1234,
modelValue: 'value of modal',
groupName: 'name of group',
buttonLabel: 'label of button',
additionalButtonData
},
mixins: [inputButtonWrapperMixin]
});
await wrapper.vm.$nextTick();
// Act
const availabilityIndicatorLoader = wrapper.findComponent(loaderReference);
// Assert
expect(availabilityIndicatorLoader.exists()).toBeTruthy();
expect(availabilityIndicatorLoader.props().loaderPosition).toBe('left');
expect(availabilityIndicatorLoader.props().allowPageInteraction).toBe(true);
});
describe('availability badge when displayAvailabilityIndicators true', () => { describe('availability badge when displayAvailabilityIndicators true', () => {
test('and "availabilityRating" is "high"', async () => { test('and "availabilityRating" is "high"', async () => {
// Arrange // Arrange
@ -437,60 +411,6 @@ describe('Shop list button', () => {
}); });
}); });
describe('should not render', () => { describe('should not render', () => {
test.each([false, null, undefined])(
'availability indicator block when displayAvailabilityIndicators falsy',
async (displayAvailabilityIndicators) => {
// Arrange
const additionalButtonData = {
displayAvailabilityIndicators,
availabilityRatingCallback: () => Promise.resolve({})
};
const wrapper = mount(shopListButton, {
propsData: {
value: 1234,
modelValue: 'value of modal',
groupName: 'name of group',
buttonLabel: 'label of button',
additionalButtonData
},
mixins: [inputButtonWrapperMixin]
});
await wrapper.vm.$nextTick();
// Act
const availabilityIndicatorBlock = wrapper.find(availabilityIndicatorBlockReference);
// Assert
expect(availabilityIndicatorBlock.exists()).toBeFalsy();
}
);
test.each([null, undefined])(
'availability badge when displayAvailabilityIndicators true and "availabilityRating" is null',
async (availabilityRating) => {
// Arrange
const additionalButtonData = {
displayAvailabilityIndicators: true,
availabilityRatingCallback: () => Promise.resolve(availabilityRating)
};
const wrapper = mount(shopListButton, {
propsData: {
value: 1234,
modelValue: 'value of modal',
groupName: 'name of group',
buttonLabel: 'label of button',
additionalButtonData
},
mixins: [inputButtonWrapperMixin]
});
await wrapper.vm.$nextTick();
// Act
const availabilityBadge = wrapper.find(availabilityBadgeReference);
// Assert
expect(availabilityBadge.exists()).toBeFalsy();
}
);
test('button body copy when buttonBodyCopy not provided', async () => { test('button body copy when buttonBodyCopy not provided', async () => {
// Arrange // Arrange
const additionalButtonData = { const additionalButtonData = {
@ -542,33 +462,6 @@ describe('Shop list button', () => {
}); });
describe('computed', () => { describe('computed', () => {
describe('isLoaderDisplayed', () => { describe('isLoaderDisplayed', () => {
test.each([null, undefined])(
'should return true when availabilityRating is null or undefined',
async (availabilityRating) => {
// Arrange
const additionalButtonData = {
displayAvailabilityIndicators: true,
availabilityRatingCallback: () => Promise.resolve(availabilityRating)
};
const wrapper = mount(shopListButton, {
propsData: {
value: 1234,
modelValue: 'value of modal',
groupName: 'name of group',
buttonLabel: 'label of button',
additionalButtonData
},
mixins: [inputButtonWrapperMixin]
});
await wrapper.vm.$nextTick();
// Act
const result = wrapper.vm.isLoaderDisplayed;
// Assert
expect(result).toBeTruthy();
}
);
test('should return false when availabilityRating is empty string', async () => { test('should return false when availabilityRating is empty string', async () => {
// Arrange // Arrange
const availabilityRating = ''; const availabilityRating = '';

View file

@ -25,13 +25,7 @@
id="availabilityIndicatorBlock" id="availabilityIndicatorBlock"
class="availability-indicator rounded-pill" class="availability-indicator rounded-pill"
:class="availabilityRatingClass"> :class="availabilityRatingClass">
<loader
v-if="isLoaderDisplayed"
ref="availabilityIndicatorLoader"
loaderPosition="left"
:allowPageInteraction="true" />
<div <div
v-else
id="availabilityIndicator" id="availabilityIndicator"
class="d-flex align-items-center"> class="d-flex align-items-center">
<div <div
@ -64,13 +58,11 @@
<script> <script>
import baseInputButton from '@/digital-components/base-input-button/base-input-button.vue'; import baseInputButton from '@/digital-components/base-input-button/base-input-button.vue';
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin'; import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
import loader from '@/ux-components/loader/loader.vue';
export default { export default {
name: 'shop-list-button', name: 'shop-list-button',
components: { components: {
baseInputButton, baseInputButton
loader
}, },
mixins: [inputButtonWrapperMixin], mixins: [inputButtonWrapperMixin],
data() { data() {
@ -80,9 +72,6 @@ export default {
}; };
}, },
computed: { computed: {
isLoaderDisplayed() {
return this.availabilityRating == null;
},
availabilityRatingClass() { availabilityRatingClass() {
if (this.availabilityRating != null) { if (this.availabilityRating != null) {
return this.availabilityRating === 'high' ? 'green' : 'orange'; return this.availabilityRating === 'high' ? 'green' : 'orange';
@ -203,18 +192,6 @@ export default {
align-items: center; align-items: center;
} }
.loader {
padding: 0 0.25rem 0 0.25rem;
padding-top: 0.125rem;
padding-bottom: 0.125rem;
}
.loader:after {
background-color: $gray-550;
height: 1rem;
width: 1rem;
}
&.green { &.green {
color: $green-700; color: $green-700;
background-color: $green-100; background-color: $green-100;

View file

@ -94,10 +94,6 @@ export default {
updateButtonText(newText) { updateButtonText(newText) {
this.customButtontext = newText; this.customButtontext = newText;
}, },
removeLoader() {
this.$refs.buttonMain.removeLoader();
document.onkeydown = () => true;
},
buttonClick() { buttonClick() {
// prevent keyboard input after button click // prevent keyboard input after button click
document.onkeydown = () => false; document.onkeydown = () => false;

View file

@ -177,12 +177,7 @@ p {
} }
} }
.subheader-primary {
font-family: $font-family-urbanist-regular-400;
}
.subheader-secondary { .subheader-secondary {
font-family: $font-family-urbanist-regular-400;
p { p {
margin-bottom: 1.25rem; margin-bottom: 1.25rem;
color: #525656; color: #525656;

View file

@ -88,7 +88,6 @@ function setupMocks({
wrapper.vm.$router.navigateWithSpinner = jest.fn(); wrapper.vm.$router.navigateWithSpinner = jest.fn();
wrapper.vm.navigateBack = baseMixin.methods.navigateBack; wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn(); wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
@ -483,7 +482,7 @@ describe('address-lookup.vue', () => {
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
vinVehicles: [ vinVehicles: [
{ {
vehicle: { vehicle: {
carId: 'BIGTRUCKCARID', carId: 'BIGTRUCKCARID',
isBigTruck: true, isBigTruck: true,
@ -498,7 +497,7 @@ describe('address-lookup.vue', () => {
await wrapper.setData({ await wrapper.setData({
customerQuestions: { customerQuestions: {
addressQuestions: mockRegistrationAddress addressQuestions: mockRegistrationAddress
}, }
}); });
// Act // Act
@ -518,7 +517,7 @@ describe('address-lookup.vue', () => {
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
vinVehicles: [ vinVehicles: [
{ {
vehicle: { vehicle: {
carId: 'BIGTRUCKCARID2', carId: 'BIGTRUCKCARID2',
isBigTruck: true, isBigTruck: true,
@ -533,7 +532,7 @@ describe('address-lookup.vue', () => {
await wrapper.setData({ await wrapper.setData({
customerQuestions: { customerQuestions: {
addressQuestions: mockRegistrationAddress addressQuestions: mockRegistrationAddress
}, }
}); });
// Act // Act

View file

@ -250,8 +250,7 @@ export default {
if (!resultMap.vinLookupResponse.isStatePermissible) { if (!resultMap.vinLookupResponse.isStatePermissible) {
// State Restrictions forbid lookup by address // State Restrictions forbid lookup by address
this.displayVinLookupByHomeAddressNotAllowedAlert = true; this.displayVinLookupByHomeAddressNotAllowedAlert = true;
this.$refs.siteFooter.disableForwardButton(); return this.$refs.siteFooter.disableForwardButton();
return this.$refs.siteFooter.removeLoader();
} }
const carsFound = resultMap.vinLookupResponse.vinVehicles; const carsFound = resultMap.vinLookupResponse.vinVehicles;
@ -263,12 +262,10 @@ export default {
if (!carFound.canSafeliteService) { if (!carFound.canSafeliteService) {
this.displayNoServiceAlert = true; this.displayNoServiceAlert = true;
this.$refs.siteFooter.disableForwardButton(); return this.$refs.siteFooter.disableForwardButton();
return this.$refs.siteFooter.removeLoader();
} }
this.isCarIdDifferent = this.isCarIdDifferent = carFound.carId !== useMainStore().order.vehicle.carId;
carFound.carId !== useMainStore().order.vehicle.carId;
if (this.isCarIdDifferent && carFound.carId !== this.previouslyEnteredCarId) { if (this.isCarIdDifferent && carFound.carId !== this.previouslyEnteredCarId) {
// Display Alert // Display Alert
this.previouslyEnteredCarId = carFound.carId; this.previouslyEnteredCarId = carFound.carId;
@ -284,10 +281,9 @@ export default {
await isGlassAvailableForCarId(carFound.carId); await isGlassAvailableForCarId(carFound.carId);
// Update button "Continue with..." // Update button "Continue with..."
this.$refs.siteFooter return this.$refs.siteFooter
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`); .updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`);
return this.$refs.siteFooter.removeLoader();
} }
// update data // update data
@ -310,8 +306,7 @@ export default {
} else { } else {
// No VINS found. // No VINS found.
this.displayVinNotFoundAlert = true; this.displayVinNotFoundAlert = true;
this.$refs.siteFooter.disableForwardButton(); return this.$refs.siteFooter.disableForwardButton();
return this.$refs.siteFooter.removeLoader();
} }
// Save vehicle, customer, service and registration information // Save vehicle, customer, service and registration information

View file

@ -119,7 +119,6 @@ function setupMocks({
wrapper.vm.$router.navigateWithSpinner = jest.fn(); wrapper.vm.$router.navigateWithSpinner = jest.fn();
wrapper.vm.navigateBack = baseMixin.methods.navigateBack; wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
return { wrapper }; return { wrapper };
@ -147,7 +146,6 @@ describe('address-vehicles.vue', () => {
}; };
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse)); wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
wrapper.vm.$router.navigate = jest.fn(); wrapper.vm.$router.navigate = jest.fn();
wrapper.vm.saveVin = jest.fn().mockImplementation(() => {}); wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
@ -176,7 +174,6 @@ describe('address-vehicles.vue', () => {
}; };
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse)); wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
wrapper.vm.$router.navigate = jest.fn(); wrapper.vm.$router.navigate = jest.fn();
wrapper.vm.saveVin = jest.fn().mockImplementation(() => {}); wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
@ -323,7 +320,7 @@ describe('address-vehicles.vue', () => {
selectedVehicleVin: 'BIGTRUCKVIN2', selectedVehicleVin: 'BIGTRUCKVIN2',
previouslyEnteredCarId: 'BIGTRUCKCARID2' previouslyEnteredCarId: 'BIGTRUCKCARID2'
}); });
2
wrapper.vm.selectedVehicle = { wrapper.vm.selectedVehicle = {
vin: 'BIGTRUCKVIN2', vin: 'BIGTRUCKVIN2',
vehicle: { vehicle: {

View file

@ -259,16 +259,11 @@ export default {
return false; return false;
}, },
async forwardButtonAction() { async forwardButtonAction() {
const vinLookup = await useMainStore() const vinLookup = await useMainStore().lookupVehicleByVin(this.selectedVehicle.vin);
.lookupVehicleByVin(this.selectedVehicle.vin)
.catch(() => {
this.$refs.siteFooter.removeLoader();
});
if (!vinLookup) { if (!vinLookup) {
return; return;
} }
this.isSelectedGlassAvailableForVehicle = this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
await isGlassAvailableForCarId(vinLookup.data.carId);
await useMainStore().saveVin( await useMainStore().saveVin(
{ {
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, { vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {

View file

@ -2,7 +2,6 @@
exports[`returns the initial data 1`] = ` exports[`returns the initial data 1`] = `
Object { Object {
"isLoaderDisplayed": false,
"isModalOpened": false, "isModalOpened": false,
} }
`; `;

View file

@ -21,9 +21,6 @@
align-items-center justify-content-center d-inline-flex mt-4 py-3 px-4 delay w-100" align-items-center justify-content-center d-inline-flex mt-4 py-3 px-4 delay w-100"
@click="returnToClaim"> @click="returnToClaim">
{{ modalBodyText2 }} {{ modalBodyText2 }}
<loader
v-if="isLoaderDisplayed"
class="ms-2 button-loader" />
</button> </button>
</modal> </modal>
</div> </div>
@ -31,19 +28,16 @@
</template> </template>
<script> <script>
import loader from '@/ux-components/loader/loader.vue';
import modal from '@/digital-components/modal/modal.vue'; import modal from '@/digital-components/modal/modal.vue';
export default { export default {
name: 'cancel-claim-modal', name: 'cancel-claim-modal',
components: { components: {
loader,
modal modal
}, },
emits: ['cancel-claim-confirmation', 'return-to-claim'], emits: ['cancel-claim-confirmation', 'return-to-claim'],
data() { data() {
return { return {
isLoaderDisplayed: false,
isModalOpened: false isModalOpened: false
}; };
}, },
@ -65,9 +59,6 @@ export default {
openModal() { openModal() {
this.$refs.cancelClaimModal.openModal(); this.$refs.cancelClaimModal.openModal();
}, },
removeLoader() {
this.isLoaderDisplayed = false;
},
setModalStatus(isOpened) { setModalStatus(isOpened) {
this.isModalOpened = isOpened; this.isModalOpened = isOpened;
}, },

View file

@ -76,7 +76,6 @@ function setupMocks({
wrapper.vm.$router.navigateWithSpinner = jest.fn(); wrapper.vm.$router.navigateWithSpinner = jest.fn();
wrapper.vm.navigateBack = baseMixin.methods.navigateBack; wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn(); wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
@ -156,7 +155,7 @@ describe('license-plate-lookup.vue', () => {
// Arrange // Arrange
const mockRegistrationLicensePlate = { const mockRegistrationLicensePlate = {
licensePlate: 'BIGTRUCKTEST' licensePlate: 'BIGTRUCKTEST'
}; };
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
lookupVinByPlateResponse: { lookupVinByPlateResponse: {
@ -187,7 +186,7 @@ describe('license-plate-lookup.vue', () => {
// Arrange // Arrange
const mockRegistrationLicensePlate = { const mockRegistrationLicensePlate = {
licensePlate: 'BIGTRUCKTEST2' licensePlate: 'BIGTRUCKTEST2'
}; };
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
lookupVinByPlateResponse: { lookupVinByPlateResponse: {

View file

@ -266,8 +266,7 @@ export default {
if (vinLookupResponse.error) { if (vinLookupResponse.error) {
this.displayVinNotFoundAlert = true; this.displayVinNotFoundAlert = true;
this.previouslyEnteredCarId = null; this.previouslyEnteredCarId = null;
this.$refs.siteFooter.disableForwardButton(); return this.$refs.siteFooter.disableForwardButton();
return this.$refs.siteFooter.removeLoader();
} }
// Vehicle found from VIN lookup // Vehicle found from VIN lookup
@ -275,8 +274,7 @@ export default {
if (!vehicleFromLookup.canSafeliteService) { if (!vehicleFromLookup.canSafeliteService) {
this.displayNoServiceAlert = true; this.displayNoServiceAlert = true;
this.$refs.siteFooter.disableForwardButton(); return this.$refs.siteFooter.disableForwardButton();
return this.$refs.siteFooter.removeLoader();
} }
// Check if the CarId has changed // Check if the CarId has changed
@ -299,10 +297,9 @@ export default {
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleFromLookup.carId); this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleFromLookup.carId);
// Update button "Continue with..." // Update button "Continue with..."
this.$refs.siteFooter return this.$refs.siteFooter
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
.updateButtonText(`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`); .updateButtonText(`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`);
return this.$refs.siteFooter.removeLoader();
} }
// Save vehicle, license plate, and registration information // Save vehicle, license plate, and registration information

View file

@ -63,7 +63,6 @@ function setupMocks() {
wrapper.vm.$router.navigateWithSpinner = jest.fn(); wrapper.vm.$router.navigateWithSpinner = jest.fn();
wrapper.vm.navigateBack = baseMixin.methods.navigateBack; wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn(); wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();

View file

@ -72,7 +72,6 @@ function setupMocks() {
wrapper.vm.setCmsContent = jest.fn(); wrapper.vm.setCmsContent = jest.fn();
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
return { wrapper }; return { wrapper };
} }

View file

@ -232,7 +232,6 @@ export default {
if (this.mainStore.issConfig.enableTPAFlow) { if (this.mainStore.issConfig.enableTPAFlow) {
if (this.mainStore.hasRecalibrationPart) { if (this.mainStore.hasRecalibrationPart) {
this.$refs[TPA_RECAL_MODAL_REF_NAME].openModal(); this.$refs[TPA_RECAL_MODAL_REF_NAME].openModal();
this.$refs[SITE_FOOTER_REF_NAME].removeLoader();
return; return;
} }
scenario = scenario =

View file

@ -426,7 +426,6 @@ export default {
if (partsOrQuestionsResponse.error) { if (partsOrQuestionsResponse.error) {
this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data)); this.mainStore.setBailout(bailoutMessage.PartsServiceError(partsOrQuestionsResponse.error.data));
window.console.error('Error on retrieving PartsOrQuestions'); window.console.error('Error on retrieving PartsOrQuestions');
this.$refs.siteFooter.removeLoader();
this.hasBailedOut = true; this.hasBailedOut = true;
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,

View file

@ -91,7 +91,6 @@ function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {}
partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent; partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
return { wrapper, apiPromise }; return { wrapper, apiPromise };
} }

View file

@ -194,7 +194,6 @@ export default {
} }
// If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts) // If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts)
if (this.isForwardActionDisabled) { if (this.isForwardActionDisabled) {
this.$refs.siteFooter.removeLoader();
throw new Error('Could not match any parts to the selected parts'); throw new Error('Could not match any parts to the selected parts');
} }

View file

@ -179,7 +179,6 @@ export default {
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND; this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
this.mainStore.setBailout(bailoutMessage.vehicleNotFound(this.vin)); this.mainStore.setBailout(bailoutMessage.vehicleNotFound(this.vin));
this.resetVehicleFromLookup(); this.resetVehicleFromLookup();
this.$refs.siteFooter.removeLoader();
// Temp solution to turn on 'disabled' style on the Continue button // Temp solution to turn on 'disabled' style on the Continue button
// because the form itself actually passes its client-side validation. // because the form itself actually passes its client-side validation.
// SSR-189 Scenario #4. // SSR-189 Scenario #4.
@ -191,7 +190,6 @@ export default {
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE; this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE;
this.resetVehicleFromLookup(); this.resetVehicleFromLookup();
this.$refs.siteFooter.disableForwardButton(); this.$refs.siteFooter.disableForwardButton();
this.$refs.siteFooter.removeLoader();
return; return;
} }
@ -218,8 +216,6 @@ export default {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
`${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model} ${this.forwardButtonCarStyle}`; `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model} ${this.forwardButtonCarStyle}`;
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModelStyle}`); this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModelStyle}`);
this.$refs.siteFooter.removeLoader();
this.needToLookupVehicle = false; this.needToLookupVehicle = false;
return null; return null;

View file

@ -87,7 +87,6 @@ function setupMocks({
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ''); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
return { wrapper, apiPromise }; return { wrapper, apiPromise };
} }

View file

@ -341,7 +341,6 @@ export default {
return Promise.resolve(); return Promise.resolve();
} catch (e) { } catch (e) {
this.displayInvalidZipAlert = true; this.displayInvalidZipAlert = true;
this.$refs.siteFooter.removeLoader();
return Promise.reject(e); return Promise.reject(e);
} }
}, },
@ -465,11 +464,8 @@ export default {
console.error(`Error on loading session from cookie ${error}`); console.error(`Error on loading session from cookie ${error}`);
this.startNewReferral(); this.startNewReferral();
} finally { } finally {
this.$refs.continueModal.removeLoader();
this.$refs.continueModal.closeModal(); this.$refs.continueModal.closeModal();
} }
} else {
this.$refs.continueModal.removeLoader();
} }
}, },
startNewReferral() { startNewReferral() {

View file

@ -8,14 +8,9 @@
$accent-fill: #e6f1f3; // Calendar background $accent-fill: #e6f1f3; // Calendar background
$accent-color: #09748b; $accent-color: #09748b;
$link: #09748b; $link: #09748b;
$button-color: #a9e3e9;
$button-text-color: #181643;
$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-color: #181643;
//Variables
--iss-loader-color: #{$button-text-color};
svg, svg,
.modal-text { .modal-text {
fill: $accent-color; fill: $accent-color;
@ -30,51 +25,6 @@
a.new-window-link { a.new-window-link {
color: $link; color: $link;
} }
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
&.modal-open {
.modal {
.modal-body {
.btn {
&.btn-override[aria-disabled="false"]:not(.form-test-invalid) {
&.btn-primary {
background: $button-color;
color: $button-text-color;
}
&:focus-visible {
background: $button-color;
color: $button-text-color;
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $button-color;
}
}
}
}
.modal-footer {
.btn:not(.navigation-link) {
background: $button-color;
color: $button-text-color;
}
}
}
} }
.progress-bar-container { .progress-bar-container {

View file

@ -1,5 +1,5 @@
@import "@/styles/ux-variables-svg-strings.scss"; @import "@/styles/ux-variables-svg-strings.scss";
html { html {
.has-error { .has-error {
@ -202,24 +202,9 @@ html {
} }
.form-test-invalid { .form-test-invalid {
// Disable Gray coloring to match Heritage
&.btn.btn-primary { &.btn.btn-primary {
//color: $gray-600;
//background: $gray-200;
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
} }
//&.btn.btn-primary:hover,
//&.btn.btn-primary:focus {
//color: $gray-600;
//background: $gray-200;
//box-shadow: none;
//}
//&.btn.btn-primary:focus-visible {
// box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $gray-700;
//}
} }
} }

View file

@ -73,55 +73,55 @@ caption,
// Urbanist Fonts // Urbanist Fonts
@font-face { @font-face {
font-family: "UrbanistRegular"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-Regular.woff") format("woff2"), url("@/assets/fonts/Urbanist-Regular.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-Regular.woff2") format("woff"); url("@/assets/fonts/Urbanist-Regular.woff") format("woff");
font-weight: normal; font-weight: 400;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: "UrbanistSemibold"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-SemiBold.woff") format("woff2"), url("@/assets/fonts/Urbanist-SemiBold.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-SemiBold.woff2") format("woff"); url("@/assets/fonts/Urbanist-SemiBold.woff") format("woff");
font-weight: normal; font-weight: 600;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: "UrbanistBold"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-Bold.woff") format("woff2"), url("@/assets/fonts/Urbanist-Bold.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-Bold.woff2") format("woff"); url("@/assets/fonts/Urbanist-Bold.woff") format("woff");
font-weight: normal; font-weight: 700;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: "UrbanistExtraBold"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-ExtraBold.woff") format("woff2"), url("@/assets/fonts/Urbanist-ExtraBold.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-ExtraBold.woff2") format("woff"); url("@/assets/fonts/Urbanist-ExtraBold.woff") format("woff");
font-weight: normal; font-weight: 800;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: "UrbanistMedium_Italic"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-MediumItalic.woff") format("woff2"), url("@/assets/fonts/Urbanist-MediumItalic.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-MediumItalic.woff2") format("woff"); url("@/assets/fonts/Urbanist-MediumItalic.woff") format("woff");
font-weight: normal; font-weight: 500;
font-style: normal; font-style: italic;
} }
@font-face { @font-face {
font-family: "UrbanistBold_Italic"; font-family: "Urbanist";
src: src:
url("@/assets/fonts/Urbanist-BoldItalic.woff") format("woff2"), url("@/assets/fonts/Urbanist-BoldItalic.woff2") format("woff2"),
url("@/assets/fonts/Urbanist-BoldItalic.woff2") format("woff"); url("@/assets/fonts/Urbanist-BoldItalic.woff") format("woff");
font-weight: normal; font-weight: 700;
font-style: normal; font-style: italic;
} }

View file

@ -117,9 +117,7 @@ $theme-colors: (
$body-color: $gray-600; $body-color: $gray-600;
//Fonts //Fonts
$font-family-urbanist-regular-400: UrbanistRegular, Roboto, Arial, sans-serif; $font-family-sans-serif: Urbanist, Roboto, Arial, sans-serif;
$font-family-urbanist-semibold-600: UrbanistSemibold, Roboto, Arial, sans-serif;
$font-family-sans-serif: $font-family-urbanist-semibold-600;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace; monospace;
// stylelint-enable value-keyword-case // stylelint-enable value-keyword-case

View file

@ -1,6 +1,5 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { nextTick } from 'vue';
import buttonMain from '@/ux-components/button-main/button-main.vue'; import buttonMain from '@/ux-components/button-main/button-main.vue';
/** @ignore */ /** @ignore */
@ -48,27 +47,4 @@ describe('buttonMain.vue', () => {
// Expect // Expect
expect(button.attributes()['aria-disabled']).toEqual('true'); expect(button.attributes()['aria-disabled']).toEqual('true');
}); });
it('Should return loader position', async () => {
// Act
const wrapper = shallowMount(
buttonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true
}
})
);
// Assert
wrapper.vm.clicked();
await nextTick();
const loader = wrapper.find('loader-stub');
expect(loader.attributes('class')).toContain('right');
});
}); });

View file

@ -5,25 +5,15 @@
:class="[ :class="[
isPrimary ? 'btn-primary' : 'btn-secondary', isPrimary ? 'btn-primary' : 'btn-secondary',
isFloat ? 'float-end' : '', isFloat ? 'float-end' : '',
isLoaderDisplayed ? 'has-loader' : '',
]" ]"
@click="clicked"> @click="clicked">
<span class="m-0">{{ buttonText }}</span> <span class="m-0">{{ buttonText }}</span>
<loader
v-if="isLoaderDisplayed && !suppressLoader"
class="ms-2"
:class="[loaderPosition]" />
</button> </button>
</template> </template>
<script> <script>
import loader from '@/ux-components/loader/loader.vue';
export default { export default {
name: 'button-main', name: 'button-main',
components: {
loader
},
props: { props: {
isPrimary: Boolean, isPrimary: Boolean,
buttonText: String, buttonText: String,
@ -33,23 +23,11 @@ export default {
suppressLoader: Boolean suppressLoader: Boolean
}, },
emits: ['click-event'], emits: ['click-event'],
data() {
return {
isLoaderDisplayed: false
};
},
methods: { methods: {
removeLoader() {
this.isLoaderDisplayed = false;
},
clicked() { clicked() {
if (!this.isDisabled) { if (!this.isDisabled) {
this.isLoaderDisplayed = true;
this.$emit('click-event'); this.$emit('click-event');
} }
},
resetButtonStyle() {
this.isLoaderDisplayed = false;
} }
} }
}; };
@ -98,10 +76,6 @@ $button-width-heritage: 9.0625rem; // 145px
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
} }
&.has-loader {
color: $white;
background: $blue-700;
}
&.delay { &.delay {
// fixes flicker while transitioning between states // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out; transition: background 0s 0s ease-in-out;
@ -136,10 +110,6 @@ $button-width-heritage: 9.0625rem; // 145px
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
} }
&.has-loader {
color: $white;
@include blue-gradient;
}
&.delay { &.delay {
// fixes flicker while transitioning between states // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out; transition: background 0s 0s ease-in-out;

View file

@ -45,97 +45,6 @@ describe('modal-button-main.vue', () => {
expect(button.attributes()['aria-disabled']).toEqual('true'); expect(button.attributes()['aria-disabled']).toEqual('true');
}); });
it('Should return loader color', async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderColor: 'blue',
loaderEnabled: true
}
})
);
// Act
wrapper.vm.clicked();
await nextTick();
// Assert
const loader = wrapper.find('loader-stub');
expect(loader.attributes('class')).toContain('blue');
});
it('Should return loader position', async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true
}
})
);
// Act
wrapper.vm.clicked();
await nextTick();
// Assert
const loader = wrapper.find('loader-stub');
expect(loader.attributes('class')).toContain('right');
});
it("Should set 'isLoaderDisplayed' to false when calling 'removeLoader'", async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true
}
})
);
wrapper.setData({
isLoaderDisplayed: true
});
// Act
wrapper.vm.removeLoader();
await nextTick();
// Assert
expect(wrapper.vm.isLoaderDisplayed).toBe(false);
});
it("Should set 'isLoaderDisplayed' to false when calling 'resetButtonStyle'", async () => {
// Arrange
const wrapper = shallowMount(
modalButtonMain,
setupMocks({
propsData: {
loaderPosition: 'right',
loaderEnabled: true
}
})
);
wrapper.setData({
isLoaderDisplayed: true
});
// Act
wrapper.vm.resetButtonStyle();
await nextTick();
// Assert
expect(wrapper.vm.isLoaderDisplayed).toBe(false);
});
it("Should emit 'click-event' event when clicking if the button is enabled", async () => { it("Should emit 'click-event' event when clicking if the button is enabled", async () => {
// Arrange // Arrange
const wrapper = shallowMount( const wrapper = shallowMount(

View file

@ -6,25 +6,16 @@
:class="[ :class="[
isPrimary ? 'btn-primary' : 'btn-secondary', isPrimary ? 'btn-primary' : 'btn-secondary',
isFloat ? 'float-end' : '', isFloat ? 'float-end' : '',
isLoaderDisplayed ? 'has-loader' : '',
]" ]"
@click="clicked"> @click="clicked">
<span class="m-0">{{ buttonText }}</span> <span class="m-0">{{ buttonText }}</span>
<loader
v-if="isLoaderDisplayed && !suppressLoader"
class="ms-2"
:class="[loaderColor, loaderPosition]" />
</button> </button>
</template> </template>
<script> <script>
import loader from '@/ux-components/loader/loader.vue';
export default { export default {
name: 'modal-button-main', name: 'modal-button-main',
components: {
loader
},
props: { props: {
isPrimary: Boolean, isPrimary: Boolean,
buttonText: String, buttonText: String,
@ -35,15 +26,7 @@ export default {
suppressLoader: Boolean suppressLoader: Boolean
}, },
emits: ['click-event'], emits: ['click-event'],
data() {
return {
isLoaderDisplayed: false
};
},
methods: { methods: {
removeLoader() {
this.isLoaderDisplayed = false;
},
clicked() { clicked() {
this.pushEventToGA( this.pushEventToGA(
this.$route.query[this.queryStrings.ISS_PAGE], this.$route.query[this.queryStrings.ISS_PAGE],
@ -52,12 +35,8 @@ export default {
true true
); );
if (!this.isDisabled) { if (!this.isDisabled) {
this.isLoaderDisplayed = true;
this.$emit('click-event'); this.$emit('click-event');
} }
},
resetButtonStyle() {
this.isLoaderDisplayed = false;
} }
} }
}; };
@ -97,11 +76,6 @@ export default {
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
} }
&.has-loader {
color: $white;
background: $blue-700;
pointer-events: none;
}
&.delay { &.delay {
// fixes flicker while transitioning between states // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out; transition: background 0s 0s ease-in-out;
@ -138,11 +112,6 @@ export default {
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
} }
&.has-loader {
color: $white;
@include blue-gradient;
pointer-events: none;
}
&.delay { &.delay {
// fixes flicker while transitioning between states // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out; transition: background 0s 0s ease-in-out;