Merging from develop
This commit is contained in:
commit
52061134da
11 changed files with 815 additions and 238 deletions
|
|
@ -18,6 +18,7 @@ module.exports = {
|
|||
"!src/common-components/date-picker/**/*.vue", // Temp until unit tests completed
|
||||
"!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing
|
||||
"!src/common-components/funnel-header/menu-modal/**/*.vue",
|
||||
"!src/layouts/schedule/*.vue", // Temp test exclusion while in development
|
||||
// END
|
||||
], // ! means exclude from coverage.
|
||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const errorMessages = {
|
|||
OPTION_REQUIRED: "Please select an option",
|
||||
VEHICLE_REQUIRED: "Please select a vehicle",
|
||||
MOBILE_LOCATION_REQUIRED: "Please enter your service address",
|
||||
DATE_REQUIRED: "Please select a date",
|
||||
};
|
||||
|
||||
export { errorMessages };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="date-picker" :class="calendarViewDirection">
|
||||
<div class="date-picker text-center" :class="calendarViewDirection">
|
||||
<fieldset v-if="months">
|
||||
<legend class="sr-only">Date Picker</legend>
|
||||
<div
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
<button
|
||||
v-if="calendarViewDirection === 'future'"
|
||||
type="button"
|
||||
class="btn-link"
|
||||
class="btn btn-link"
|
||||
@click="goForward">
|
||||
View more dates
|
||||
</button>
|
||||
|
|
@ -371,92 +371,106 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.calendar-grid-container {
|
||||
margin: 0 auto;
|
||||
max-width: 414px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4px;
|
||||
|
||||
.grid-item {
|
||||
text-align: center;
|
||||
margin: 10%;
|
||||
|
||||
&.first-day-,
|
||||
&.first-day-0 {
|
||||
grid-column-start: 1;
|
||||
}
|
||||
&.first-day-1 {
|
||||
grid-column-start: 2;
|
||||
}
|
||||
&.first-day-2 {
|
||||
grid-column-start: 3;
|
||||
}
|
||||
&.first-day-3 {
|
||||
grid-column-start: 4;
|
||||
}
|
||||
&.first-day-4 {
|
||||
grid-column-start: 5;
|
||||
}
|
||||
&.first-day-5 {
|
||||
grid-column-start: 6;
|
||||
}
|
||||
&.first-day-6 {
|
||||
grid-column-start: 7;
|
||||
}
|
||||
}
|
||||
|
||||
.month-year {
|
||||
grid-area: 1 / 1 / 2 / 5;
|
||||
text-transform: uppercase;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.75px;
|
||||
}
|
||||
.legend {
|
||||
grid-area: 1 / 5 / 2 / 8;
|
||||
.legend-circle {
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
}
|
||||
}
|
||||
.nav-back,
|
||||
.nav-forward {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.radio-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
.date-picker {
|
||||
.calendar-grid-container {
|
||||
margin: 0 auto;
|
||||
max-width: 414px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
outline: none;
|
||||
padding: 4px;
|
||||
|
||||
input[type="radio"] {
|
||||
position: absolute; //override bootstrap
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
.grid-item {
|
||||
text-align: center;
|
||||
margin: 10%;
|
||||
|
||||
&:focus-visible + label {
|
||||
box-shadow: 0 0 0 2.5px $blue;
|
||||
&.first-day-,
|
||||
&.first-day-0 {
|
||||
grid-column-start: 1;
|
||||
}
|
||||
&.first-day-1 {
|
||||
grid-column-start: 2;
|
||||
}
|
||||
&.first-day-2 {
|
||||
grid-column-start: 3;
|
||||
}
|
||||
&.first-day-3 {
|
||||
grid-column-start: 4;
|
||||
}
|
||||
&.first-day-4 {
|
||||
grid-column-start: 5;
|
||||
}
|
||||
&.first-day-5 {
|
||||
grid-column-start: 6;
|
||||
}
|
||||
&.first-day-6 {
|
||||
grid-column-start: 7;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus + label,
|
||||
&:checked:focus + label {
|
||||
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
&.past-day {
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
color: $gray-500;
|
||||
font-weight: normal;
|
||||
.month-year {
|
||||
grid-area: 1 / 1 / 2 / 5;
|
||||
text-transform: uppercase;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.75px;
|
||||
}
|
||||
.legend {
|
||||
grid-area: 1 / 5 / 2 / 8;
|
||||
.legend-circle {
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
}
|
||||
}
|
||||
.nav-back,
|
||||
.nav-forward {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.radio-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
outline: none;
|
||||
|
||||
input[type="radio"] {
|
||||
position: absolute; //override bootstrap
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
|
||||
&:focus-visible + label {
|
||||
box-shadow: 0 0 0 2.5px $blue;
|
||||
}
|
||||
&.current-day {
|
||||
|
||||
&:focus + label,
|
||||
&:checked:focus + label {
|
||||
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
&.past-day {
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
color: $gray-500;
|
||||
font-weight: normal;
|
||||
}
|
||||
&.current-day {
|
||||
&:after {
|
||||
background-color: $white;
|
||||
}
|
||||
.first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:checked + label {
|
||||
color: $white;
|
||||
background: $blue;
|
||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue;
|
||||
&:after {
|
||||
background-color: $white;
|
||||
}
|
||||
|
|
@ -466,166 +480,158 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
&:checked + label {
|
||||
color: $white;
|
||||
background: $blue;
|
||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue;
|
||||
&:after {
|
||||
background-color: $white;
|
||||
}
|
||||
.first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.first-day {
|
||||
position: absolute;
|
||||
font-size: 9px;
|
||||
font-weight: 500;
|
||||
color: $gray-600;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
label {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
border-radius: 50%;
|
||||
|
||||
span {
|
||||
&.small {
|
||||
font-size: 0.75rem;
|
||||
color: $gray-550;
|
||||
}
|
||||
.first-day {
|
||||
position: absolute;
|
||||
font-size: 9px;
|
||||
font-weight: 500;
|
||||
color: $gray-600;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:checked {
|
||||
@include media-breakpoint-up(sm) {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
&:after {
|
||||
background-color: $white;
|
||||
}
|
||||
}
|
||||
cursor: pointer;
|
||||
&.current-day {
|
||||
+ .first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
.first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
+ p {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.selectable-day {
|
||||
label {
|
||||
color: $blue;
|
||||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
}
|
||||
}
|
||||
&.past-day,
|
||||
&.future-day,
|
||||
&.unavailable-day {
|
||||
label {
|
||||
color: $gray-500;
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
&.current-day {
|
||||
label {
|
||||
&:after {
|
||||
content: "";
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
border-radius: 50%;
|
||||
background-color: $blue;
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
}
|
||||
.first-day {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.initial-view {
|
||||
&.month-hidden {
|
||||
display: none;
|
||||
}
|
||||
.day-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.past {
|
||||
.calendar-grid-container {
|
||||
.month-year {
|
||||
grid-area: 1 / 1 / 2 / 6;
|
||||
}
|
||||
.nav-forward {
|
||||
grid-area: 1 / 7 / 2 / 8;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 12px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.66831 5.99879C6.66955 6.17554 6.60074 6.34558 6.47695 6.47168L1.15501 11.8017C1.02812 11.9287 0.85603 12 0.676587 12C0.497145 12 0.325053 11.9287 0.198168 11.8017C0.0712831 11.6748 7.268e-09 11.5026 8.07183e-09 11.3231C8.87567e-09 11.1436 0.0712831 10.9714 0.198168 10.8445L5.05126 5.99879L0.198168 1.14736C0.0725521 1.02042 0.00248585 0.848755 0.00338306 0.670131C0.00428028 0.491506 0.0760674 0.320554 0.202952 0.194881C0.329837 0.0692091 0.501426 -0.000888818 0.679971 9.54485e-06C0.858515 0.000906955 1.02939 0.0727263 1.15501 0.199668L6.47312 5.52399C6.59843 5.65017 6.66862 5.82092 6.66831 5.99879Z' fill='%231574A1'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-back {
|
||||
grid-area: 1 / 6 / 2 / 7;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 12px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.331685 6.00121C0.330445 5.82446 0.399256 5.65442 0.523053 5.52832L5.84499 0.198256C5.97188 0.0713149 6.14397 -8.63821e-08 6.32341 -6.72174e-08C6.50285 -4.80527e-08 6.67495 0.071315 6.80183 0.198256C6.92872 0.325198 7 0.497368 7 0.67689C7 0.856412 6.92872 1.02858 6.80183 1.15552L1.94874 6.00121L6.80183 10.8526C6.92745 10.9796 6.99751 11.1512 6.99662 11.3299C6.99572 11.5085 6.92393 11.6794 6.79705 11.8051C6.67016 11.9308 6.49857 12.0009 6.32003 12C6.14148 11.9991 5.97061 11.9273 5.84499 11.8003L0.526881 6.47601C0.401568 6.34983 0.331375 6.17908 0.331685 6.00121Z' fill='%231574A1'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-back,
|
||||
.nav-forward {
|
||||
button {
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
border: 2.5px solid $blue;
|
||||
box-shadow: none;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
border-radius: 50%;
|
||||
|
||||
span {
|
||||
&.small {
|
||||
font-size: 0.75rem;
|
||||
color: $gray-550;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:checked {
|
||||
@include media-breakpoint-up(sm) {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
&:after {
|
||||
background-color: $white;
|
||||
}
|
||||
}
|
||||
cursor: pointer;
|
||||
&.current-day {
|
||||
+ .first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
.first-day {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
+ p {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.selectable-day {
|
||||
label {
|
||||
color: $blue;
|
||||
background-color: $blue-100;
|
||||
color: $white;
|
||||
border: 1px solid $blue;
|
||||
}
|
||||
}
|
||||
&.past-day,
|
||||
&.future-day,
|
||||
&.unavailable-day {
|
||||
label {
|
||||
color: $gray-500;
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
&.current-day {
|
||||
label {
|
||||
&:after {
|
||||
content: "";
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
border-radius: 50%;
|
||||
background-color: $blue;
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
}
|
||||
.first-day {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.initial-view {
|
||||
&.month-hidden {
|
||||
display: none;
|
||||
}
|
||||
.day-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-link {
|
||||
font-weight: 500;
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
.past {
|
||||
.calendar-grid-container {
|
||||
.month-year {
|
||||
grid-area: 1 / 1 / 2 / 6;
|
||||
}
|
||||
.nav-forward {
|
||||
grid-area: 1 / 7 / 2 / 8;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 12px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.66831 5.99879C6.66955 6.17554 6.60074 6.34558 6.47695 6.47168L1.15501 11.8017C1.02812 11.9287 0.85603 12 0.676587 12C0.497145 12 0.325053 11.9287 0.198168 11.8017C0.0712831 11.6748 7.268e-09 11.5026 8.07183e-09 11.3231C8.87567e-09 11.1436 0.0712831 10.9714 0.198168 10.8445L5.05126 5.99879L0.198168 1.14736C0.0725521 1.02042 0.00248585 0.848755 0.00338306 0.670131C0.00428028 0.491506 0.0760674 0.320554 0.202952 0.194881C0.329837 0.0692091 0.501426 -0.000888818 0.679971 9.54485e-06C0.858515 0.000906955 1.02939 0.0727263 1.15501 0.199668L6.47312 5.52399C6.59843 5.65017 6.66862 5.82092 6.66831 5.99879Z' fill='%231574A1'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-back {
|
||||
grid-area: 1 / 6 / 2 / 7;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 12px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.331685 6.00121C0.330445 5.82446 0.399256 5.65442 0.523053 5.52832L5.84499 0.198256C5.97188 0.0713149 6.14397 -8.63821e-08 6.32341 -6.72174e-08C6.50285 -4.80527e-08 6.67495 0.071315 6.80183 0.198256C6.92872 0.325198 7 0.497368 7 0.67689C7 0.856412 6.92872 1.02858 6.80183 1.15552L1.94874 6.00121L6.80183 10.8526C6.92745 10.9796 6.99751 11.1512 6.99662 11.3299C6.99572 11.5085 6.92393 11.6794 6.79705 11.8051C6.67016 11.9308 6.49857 12.0009 6.32003 12C6.14148 11.9991 5.97061 11.9273 5.84499 11.8003L0.526881 6.47601C0.401568 6.34983 0.331375 6.17908 0.331685 6.00121Z' fill='%231574A1'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-back,
|
||||
.nav-forward {
|
||||
button {
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background-color: $blue-100;
|
||||
border: 1px solid $blue;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
border: 2.5px solid $blue;
|
||||
box-shadow: none;
|
||||
background-color: $blue-100;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
136
src/layouts/schedule/schedule.vue
Normal file
136
src/layouts/schedule/schedule.vue
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<template>
|
||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
||||
<div class="page-container-grouped-styles">
|
||||
<loadingModal ref="loadingModal" />
|
||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-5" />
|
||||
<div class="text-center mt-1 mb-3" v-if="ChangeShopLink.length">
|
||||
<span v-for="copy in ChangeShopLink" :key="copy">
|
||||
<span v-if="doesCopyContainRouterLink(copy)" class="text-body">
|
||||
<router-link
|
||||
:to="{
|
||||
query: { fmgPage: `${getRouterLinkRouteFromCopy(copy)}` },
|
||||
name: 'root',
|
||||
}"
|
||||
>{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link
|
||||
>
|
||||
</span>
|
||||
<span v-else class="m-0 text-body" v-html="copy"></span>
|
||||
</span>
|
||||
</div>
|
||||
<date-picker
|
||||
selectableDates="custom"
|
||||
v-model="selectedDate"
|
||||
:customSelectableDatesCallback="getAvailableDates" />
|
||||
<funnel-footer
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
ref="funnelFooter"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components
|
||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
|
||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||
import { Form, defineRule } from "vee-validate";
|
||||
import datePicker from "@/digital-components/date-picker/date-picker";
|
||||
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
import {
|
||||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
} from "@/helpers/cms-content-helper";
|
||||
import { errorMessages } from "@/constants/error-messages";
|
||||
import { required } from "@/helpers/validation-rules";
|
||||
|
||||
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
|
||||
|
||||
export default {
|
||||
name: "schedule",
|
||||
data() {
|
||||
return {
|
||||
selectedDate: null,
|
||||
mockSelectableDatesData: [
|
||||
{ year: 2023, month: 4, date: 13 },
|
||||
{ year: 2023, month: 4, date: 14 },
|
||||
{ year: 2023, month: 4, date: 26 },
|
||||
{ year: 2023, month: 5, date: 4 },
|
||||
{ year: 2023, month: 5, date: 5 },
|
||||
{ year: 2023, month: 5, date: 14 },
|
||||
{ year: 2023, month: 5, date: 21 },
|
||||
{ year: 2023, month: 5, date: 23 },
|
||||
{ year: 2023, month: 5, date: 25 },
|
||||
{ year: 2023, month: 6, date: 11 },
|
||||
],
|
||||
};
|
||||
},
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: "cmsContent",
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
||||
// Call the "next" function to complete the transition to this page.
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
ChangeShopLinkText() {
|
||||
return this.getCmsContent("ChangeShopLink", "Text");
|
||||
},
|
||||
ChangeShopLink() {
|
||||
// Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
|
||||
return this.splitCopyOnCMSPlaceHolder(this.ChangeShopLinkText);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
arePagePrerequisitesValid() {
|
||||
return true;
|
||||
// NEED TODO - WHAT ARE PAGE REQ'S FOR THIS PAGE?
|
||||
},
|
||||
getAvailableDates(startDate, endDate) {
|
||||
return this.mockSelectableDatesData;
|
||||
},
|
||||
backButtonAction() {
|
||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
forwardButtonAction() {
|
||||
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
|
||||
},
|
||||
},
|
||||
components: {
|
||||
funnelHeader,
|
||||
funnelFooter,
|
||||
funnelSubHeader,
|
||||
Form,
|
||||
loadingModal,
|
||||
datePicker,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
|
|
@ -812,6 +812,87 @@ describe("service-location.vue", () => {
|
|||
expect(wrapper.vm.isServiceableInshop).toEqual(false);
|
||||
expect(wrapper.vm.displayNoShopsAlert).toEqual(false);
|
||||
});
|
||||
|
||||
test("displayServiceableInshopOnly should be true if inshop is true and mobile is false", async () => {
|
||||
// Arrange
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: true,
|
||||
isRecalibrationServiceableInshop: true,
|
||||
isGlassServiceableMobile: false,
|
||||
isRecalibrationServiceableMobile: false,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isServiceableMobile).toEqual(false);
|
||||
expect(wrapper.vm.isServiceableInshop).toEqual(true);
|
||||
expect(wrapper.vm.displayServiceableInshopOnly).toEqual(true);
|
||||
});
|
||||
|
||||
test("displayServiceableInshopOnly should be false if inshop is false", async () => {
|
||||
// Arrange
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: false,
|
||||
isRecalibrationServiceableInshop: false,
|
||||
isGlassServiceableMobile: false,
|
||||
isRecalibrationServiceableMobile: false,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isServiceableMobile).toEqual(false);
|
||||
expect(wrapper.vm.isServiceableInshop).toEqual(false);
|
||||
expect(wrapper.vm.displayServiceableInshopOnly).toEqual(false);
|
||||
});
|
||||
|
||||
test("displayServiceableInshopOnly should be false if mobile is true", async () => {
|
||||
// Arrange
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: true,
|
||||
isRecalibrationServiceableInshop: true,
|
||||
isGlassServiceableMobile: true,
|
||||
isRecalibrationServiceableMobile: true,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isServiceableMobile).toEqual(true);
|
||||
expect(wrapper.vm.isServiceableInshop).toEqual(true);
|
||||
expect(wrapper.vm.displayServiceableInshopOnly).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("should be based only on glass serviceability if recalibration is not defined.", () => {
|
||||
|
|
@ -949,6 +1030,142 @@ describe("service-location.vue", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("should check for dual or static recalibration", () => {
|
||||
test("isDualOrStaticRecalibration should be true if dual recalibration is present", async () => {
|
||||
// Arrange
|
||||
store.getters = {
|
||||
lineItems: {
|
||||
supportingItems: [
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "SUPPLIES-REPAIR",
|
||||
partType: "REPAIR FEE",
|
||||
sellingPrice: 7.99,
|
||||
},
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "RECAL DUAL",
|
||||
partType: "RECALIBRATION",
|
||||
sellingPrice: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "43235",
|
||||
state: "OH",
|
||||
},
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
vehicle: {
|
||||
registration: {
|
||||
address: "5555 Sulgrave Dr",
|
||||
city: "New Albany",
|
||||
state: "OH",
|
||||
zipCode: "43054",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isDualOrStaticRecalibration).toBe(true);
|
||||
});
|
||||
|
||||
test("isDualOrStaticRecalibration should be true if static recalibration is present", async () => {
|
||||
// Arrange
|
||||
store.getters = {
|
||||
lineItems: {
|
||||
supportingItems: [
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "SUPPLIES-REPAIR",
|
||||
partType: "REPAIR FEE",
|
||||
sellingPrice: 7.99,
|
||||
},
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "RECAL STATIC",
|
||||
partType: "RECALIBRATION",
|
||||
sellingPrice: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "43235",
|
||||
state: "OH",
|
||||
},
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
vehicle: {
|
||||
registration: {
|
||||
address: "5555 Sulgrave Dr",
|
||||
city: "New Albany",
|
||||
state: "OH",
|
||||
zipCode: "43054",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isDualOrStaticRecalibration).toBe(true);
|
||||
});
|
||||
|
||||
test("isDualOrStaticRecalibration should be false if neither are present.", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.isDualOrStaticRecalibration).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("should properly display alerts.", () => {
|
||||
test("Should show mobile-only error if only mobile is available.", async () => {
|
||||
// Arrange
|
||||
|
|
@ -1057,6 +1274,150 @@ describe("service-location.vue", () => {
|
|||
// Assert
|
||||
expect(alertComponent.exists()).toBe(false);
|
||||
});
|
||||
|
||||
test("Should show inshop-only error if only inshop is available", async () => {
|
||||
// Arrange
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: true,
|
||||
isRecalibrationServiceableInshop: true,
|
||||
isGlassServiceableMobile: false,
|
||||
isRecalibrationServiceableMobile: false,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
const alertComponent = wrapper.findComponent({ ref: "alertInshopOnly" });
|
||||
|
||||
// Assert
|
||||
expect(alertComponent.exists()).toBe(true);
|
||||
});
|
||||
|
||||
test("Should not show inshop-only error if not inshop-only", async () => {
|
||||
// Arrange
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: false,
|
||||
isRecalibrationServiceableInshop: false,
|
||||
isGlassServiceableMobile: false,
|
||||
isRecalibrationServiceableMobile: false,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
const alertComponent = wrapper.findComponent({ ref: "alertInshopOnly" });
|
||||
|
||||
// Assert
|
||||
expect(alertComponent.exists()).toBe(false);
|
||||
});
|
||||
|
||||
test("Should not show inshop-only error if dual or static recalibration, but should show that error instead.", async () => {
|
||||
// Arrange
|
||||
store.getters = {
|
||||
lineItems: {
|
||||
supportingItems: [
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "SUPPLIES-REPAIR",
|
||||
partType: "REPAIR FEE",
|
||||
sellingPrice: 7.99,
|
||||
},
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "RECAL STATIC",
|
||||
partType: "RECALIBRATION",
|
||||
sellingPrice: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "43235",
|
||||
state: "OH",
|
||||
},
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
vehicle: {
|
||||
registration: {
|
||||
address: "5555 Sulgrave Dr",
|
||||
city: "New Albany",
|
||||
state: "OH",
|
||||
zipCode: "43054",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
getServiceabilityDetails.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isGlassServiceableInshop: false,
|
||||
isRecalibrationServiceableInshop: false,
|
||||
isGlassServiceableMobile: false,
|
||||
isRecalibrationServiceableMobile: false,
|
||||
})
|
||||
);
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
const alertInshopComponent = wrapper.findComponent({ ref: "alertInshopOnly" });
|
||||
const alertRecalComponent = wrapper.findComponent({ ref: "alertRecalNoMobile" });
|
||||
|
||||
// Assert
|
||||
expect(alertInshopComponent.exists()).toBe(false);
|
||||
expect(alertRecalComponent.exists()).toBe(true);
|
||||
});
|
||||
|
||||
test("Should not show dual/static recalibration error if not those recalibration types", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await serviceLocation.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "serviceLocation" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
const alertComponent = wrapper.findComponent({ ref: "alertRecalNoMobile" });
|
||||
|
||||
// Assert
|
||||
expect(alertComponent.exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,19 @@
|
|||
cmsWidgetName="AlertMobileOnlyWidget"
|
||||
v-if="displayServiceableMobileOnly"
|
||||
alertClass="alert-warning" />
|
||||
<alert
|
||||
ref="alertRecalNoMobile"
|
||||
class="my-4"
|
||||
cmsWidgetName="AlertRecalNoMobileWidget"
|
||||
v-if="displayRecalibrationWarning"
|
||||
@text-link-clicked="openModalAction"
|
||||
alertClass="alert-warning" />
|
||||
<alert
|
||||
ref="alertInshopOnly"
|
||||
class="my-4"
|
||||
cmsWidgetName="AlertInshopOnlyWidget"
|
||||
v-if="displayServiceableInshopOnly"
|
||||
alertClass="alert-warning" />
|
||||
<alert
|
||||
ref="alertNoShops"
|
||||
class="my-4"
|
||||
|
|
@ -51,6 +64,7 @@
|
|||
ref="mobileLocationModalQuestions"
|
||||
linkWidgetName="MobileLocationLinkWidget"
|
||||
modalWidgetName="MobileLocationModalWidget" />
|
||||
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
|
||||
<funnel-footer
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
ref="funnelFooter"
|
||||
|
|
@ -72,6 +86,7 @@ import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
|
|||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||
import { Form } from "vee-validate";
|
||||
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
|
||||
|
||||
// Supporting files
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
|
|
@ -209,6 +224,23 @@ export default {
|
|||
return this.isGlassServiceableInshop;
|
||||
}
|
||||
},
|
||||
isDualOrStaticRecalibration() {
|
||||
const supportingItems = store.getters.lineItems.supportingItems;
|
||||
|
||||
return supportingItems.some(
|
||||
(item) => item.partNumber === "RECAL STATIC" || item.partNumber === "RECAL DUAL"
|
||||
);
|
||||
},
|
||||
displayRecalibrationWarning() {
|
||||
return this.isDualOrStaticRecalibration;
|
||||
},
|
||||
displayServiceableInshopOnly() {
|
||||
return (
|
||||
!this.displayRecalibrationWarning &&
|
||||
this.isServiceableInshop &&
|
||||
!this.isServiceableMobile
|
||||
);
|
||||
},
|
||||
displayMilitaryZipAlert() {
|
||||
return this.zipContainsMilitaryBase && this.isServiceableMobile;
|
||||
},
|
||||
|
|
@ -279,7 +311,13 @@ export default {
|
|||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
forwardButtonAction() {
|
||||
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
|
||||
this.$router.navigateWithoutSaving(
|
||||
this.navigationScenarios.SELECTED_LOCATION,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
openModalAction(modalName) {
|
||||
this.$refs[modalName].openModal();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
|
@ -292,6 +330,7 @@ export default {
|
|||
funnelSubHeader,
|
||||
Form,
|
||||
loadingModal,
|
||||
contentGroupModal,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import { experimentTriggers } from "../constants/experiments";
|
|||
import { applicationConfig } from "../constants/application-config";
|
||||
|
||||
// Components
|
||||
import quote from "@/layouts/quote/quote.vue";
|
||||
import datePicker from "@/digital-components/date-picker/date-picker.vue";
|
||||
import demoDatePicker from "@/layouts/demo-date-picker/demo-date-picker.vue";
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const fmgPageValues = {
|
|||
QUOTE: "quote",
|
||||
SERVICE_LOCATION: "service-location",
|
||||
HERITAGE: "heritage",
|
||||
SCHEDULE: "schedule",
|
||||
};
|
||||
|
||||
export { fmgPageValues };
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ const navigationScenarios = {
|
|||
CLICKED_BACK_WITH_CAPABILITY_QUESTIONS: "CLICKED_BACK_WITH_CAPABILITY_QUESTIONS",
|
||||
CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS: "CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS",
|
||||
CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS: "CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS",
|
||||
|
||||
// Scheduling
|
||||
SELECTED_LOCATION: "SELECTED_LOCATION",
|
||||
};
|
||||
|
||||
export { navigationScenarios };
|
||||
|
|
|
|||
|
|
@ -420,6 +420,19 @@ const routingTable = function (store) {
|
|||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationFmgPageValue: fmgPageValues.QUOTE,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_LOCATION,
|
||||
destinationFmgPageValue: fmgPageValues.SCHEDULE,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
fmgPageValue: fmgPageValues.SCHEDULE,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationFmgPageValue: fmgPageValues.SERVICE_LOCATION,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -11,12 +11,11 @@
|
|||
<template v-for="paragraph in splitAlertCopyForParagraphTag" :key="paragraph">
|
||||
<p
|
||||
class="m-0 text-body small"
|
||||
v-if="!doesCopyContainRouterLink(paragraph)"
|
||||
v-if="!doesCopyContainRouterLink(paragraph) && !doesCopyContainTextLink(paragraph)"
|
||||
v-html="paragraph"></p>
|
||||
<p class="m-0 text-body small" v-else>
|
||||
<template v-for="copy in splitCopyOnCMSPlaceHolder(paragraph)" :key="copy">
|
||||
<span v-if="!doesCopyContainRouterLink(copy)" v-html="copy"></span>
|
||||
<span v-else>
|
||||
<span v-if="doesCopyContainRouterLink(copy)">
|
||||
<router-link
|
||||
:to="{
|
||||
query: { [pageQueryString]: `${getRouterLinkRouteFromCopy(copy)}` },
|
||||
|
|
@ -25,6 +24,18 @@
|
|||
>{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link
|
||||
>
|
||||
</span>
|
||||
<span v-else-if="doesCopyContainTextLink(copy)">
|
||||
<textLink
|
||||
linkType="text"
|
||||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||
href="#!"
|
||||
@click-event="
|
||||
$emit('textLinkClicked', getRouterLinkRouteFromCopy(copy))
|
||||
"
|
||||
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
||||
aria-label="Modal window" />
|
||||
</span>
|
||||
<span v-else v-html="copy"></span>
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
|
|
@ -40,11 +51,13 @@
|
|||
<script>
|
||||
import {
|
||||
doesCopyContainRouterLink,
|
||||
doesCopyContainTextLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
splitCMSCopyOnParagraphTag,
|
||||
} from "@/helpers/cms-content-helper";
|
||||
import textLink from "@/ux-components/text-link/text-link";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
|
||||
export default {
|
||||
|
|
@ -96,6 +109,7 @@ export default {
|
|||
methods: {
|
||||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
doesCopyContainTextLink,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
ensureAlertIsInViewPort() {
|
||||
|
|
@ -120,6 +134,9 @@ export default {
|
|||
mounted() {
|
||||
this.ensureAlertIsInViewPort();
|
||||
},
|
||||
components: {
|
||||
textLink,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue