alert added

This commit is contained in:
FrankRua 2022-02-23 15:55:30 -05:00
parent 265e32f7a7
commit 213090b863
6 changed files with 238 additions and 209 deletions

View file

@ -1,158 +1,153 @@
<template>
<div :class="isOverflowScrollable ? 'button_question' : ''">
<div :class="isOverflowScrollable ? 'button_question' : ''">
<div v-if="questionText" class="d-flex">
<span :class="[buttonType === 'radio' ? ['mb-0', 'text-left', 'mt-2' ] : ['mb-4', 'mt-6', 'text-center'], 'fs-6 fw-bold w-100' ]">{{ questionText }}</span>
<span :class="[buttonType === 'radio' ? ['mb-0', 'text-left', 'mt-2' ] : ['mb-4', 'mt-6', 'text-center'], 'fs-6 fw-bold w-100' ]">{{ questionText }}</span>
</div>
<div class="w-100 d-flex justify-content-center">
<fieldset class="w-100" :class="getFieldSetClasses" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
<legend class="sr-only">{{groupName}}</legend>
<div :class="getComponentWrapperClasses">
<component
:is="buttonType"
v-for="answer in answers"
:key="answer.Name ? answer.Name : answer"
@isCheckedChanged="handleCheckedChanged"
:buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer"
:value="answer.Name ? answer.Name : answer"
:buttonLabel="answer.Text ? answer.Text : answer"
:buttonLabelSubCopy="answer.SubText"
:textPosition="textPosition"
:isMultiSelect="isMultiSelect"
:groupName="groupName"
:selectingInitiatesLoad="selectingInitiatesLoad"
:loaderColor="loaderColor"
:loaderPosition="loaderPosition"
:isWide=isWide
:isRequired=isRequired
:buttonImage="answer.AnswerImageUrl"
:buttonImageId="answer.ImageId"
:altText="answer.Name ? answer.Name : answer"
screenReaderOnlyText="(opens new window)"
:colLength="getColLength"
:selectedValues="selectedValues"
data-test="button"
:validationRules="validationRules"
/>
</div>
</fieldset>
<fieldset class="w-100" :class="getFieldSetClasses" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
<legend class="sr-only">{{groupName}}</legend>
<div :class="getComponentWrapperClasses">
<component :is="buttonType" v-for="answer in answers" :key="answer.Name ? answer.Name : answer" @isCheckedChanged="handleCheckedChanged" :buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer" :value="answer.Name ? answer.Name : answer" :buttonLabel="answer.Text ? answer.Text : answer" :buttonLabelSubCopy="answer.SubText" :textPosition="textPosition" :isMultiSelect="isMultiSelect" :groupName="groupName" :selectingInitiatesLoad="selectingInitiatesLoad" :loaderColor="loaderColor" :loaderPosition="loaderPosition" :isWide=isWide :isRequired=isRequired :buttonImage="answer.AnswerImageUrl" :buttonImageId="answer.ImageId" :altText="answer.Name ? answer.Name : answer" screenReaderOnlyText="(opens new window)" :colLength="getColLength" :selectedValues="selectedValues" data-test="button" :validationRules="validationRules" />
</div>
</fieldset>
</div>
<div class="row mt-2 form-test-error" v-if="!suppressError">
<error-message :name="groupName"></error-message>
</div>
</div>
</div>
</template>
<script>
import listButton from "@/ux-components/list-button/list-button";
import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal";
import listCard from "@/ux-components/list-card/list-card";
import { ErrorMessage } from 'vee-validate';
import {
ErrorMessage
} from 'vee-validate';
import radio from "@/ux-components/radio/radio";
export default {
name: "buttonQuestion",
props: {
buttonType: {
type: String,
default: "listButton",
name: "buttonQuestion",
props: {
buttonType: {
type: String,
default: "listButton",
},
isMultiSelect: Boolean,
groupName: String,
questionText: String,
answers: Array,
textPosition: {
type: String,
default: "text-center",
},
selectingInitiatesLoad: Boolean,
loaderColor: {
type: String,
default: "blue",
},
loaderPosition: {
type: String,
default: "right",
},
isRequired: Boolean,
isOverflowScrollable: Boolean,
isWide: Boolean,
modelValue: Array,
validationRules: String,
suppressError: Boolean,
},
isMultiSelect: Boolean,
groupName: String,
questionText: String,
answers: Array,
textPosition: {
type: String,
default: "text-center",
computed: {
getFieldSetClasses() {
return this.isOverflowScrollable ?
"container-fluid overflow-scroll position-absolute px-5 pt-1 py-0" :
"";
},
getComponentWrapperClasses() {
let classes;
switch (this.buttonType) {
case "listButton":
classes = "w-100";
break;
case "listButtonHorizontal":
classes = "d-flex flex-row p-0";
break;
case 'listCard':
classes = 'row justify-content-center g-2'
break;
case 'radio':
classes = 'ui-radio d-flex'
break;
}
return classes;
},
getColLength() {
if (this.isWide) {
return "12"
} else {
return this.answers.length < 3 ? '' : '-4';
}
},
selectedValues: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
}
},
},
selectingInitiatesLoad: Boolean,
loaderColor: {
type: String,
default: "blue",
methods: {
handleCheckedChanged(val) {
const newSelectedValues = this.selectedValues;
if (this.isMultiSelect && this.selectedValues) {
// Add or remove item to array of data to emit
if (Array.isArray(this.selectedValues)) {
val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
this.selectedValues = newSelectedValues;
}
} else {
if (Array.isArray(this.selectedValues)) {
newSelectedValues.splice(0, newSelectedValues.length);
newSelectedValues.push(val.value);
this.selectedValues = newSelectedValues;
}
}
// handleCheckedChanged(val) {
// if(this.isMultiSelect && this.selectedValues) {
// // Add or remove item to array of data to emit
// if(Array.isArray(this.selectedValues)) {
// const newSelectedValues = this.selectedValues;
// val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
// this.selectedValues = newSelectedValues;
// }
// } else {
// this.selectedValues = [val.value];
// }
// },
},
},
loaderPosition: {
type: String,
default: "right",
components: {
listButton,
listButtonHorizontal,
listCard,
ErrorMessage,
radio,
},
isRequired: Boolean,
isOverflowScrollable: Boolean,
isWide: Boolean,
modelValue: Array,
validationRules: String,
suppressError: Boolean,
},
computed: {
getFieldSetClasses() {
return this.isOverflowScrollable
? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
: "";
},
getComponentWrapperClasses() {
let classes;
switch (this.buttonType) {
case "listButton":
classes = "w-100";
break;
case "listButtonHorizontal":
classes = "d-flex flex-row p-0";
break;
case 'listCard':
classes = 'row justify-content-center g-2'
break;
case 'radio':
classes = 'ui-radio d-flex'
break;
}
return classes;
},
getColLength(){
if(this.isWide) {
return "12"
} else {
return this.answers.length < 3 ? '' : '-4';
}
},
selectedValues: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
},
methods: {
handleCheckedChanged(val) {
if(this.isMultiSelect && this.selectedValues) {
// Add or remove item to array of data to emit
if(Array.isArray(this.selectedValues)) {
const newSelectedValues = this.selectedValues;
val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
this.selectedValues = newSelectedValues;
}
} else {
this.selectedValues = [val.value];
}
},
},
components: {
listButton,
listButtonHorizontal,
listCard,
ErrorMessage,
radio,
},
};
</script>
<style lang="scss" scoped>
.button_question {
color: $black;
height: calc(100vh - 280px);
color: $black;
height: calc(100vh - 280px);
.overflow-scroll {
// Height will be determined by overall height of content above list
height: calc(100% - 320px);
-webkit-overflow-scrolling: touch;
}
.overflow-scroll {
// Height will be determined by overall height of content above list
height: calc(100% - 320px);
-webkit-overflow-scrolling: touch;
}
}
</style>

View file

@ -8,7 +8,7 @@
<div class="container nested-radio" v-for="(value, name, index) in featureListData" :key="index">
<div class="row my-2">
<div class="col">
{{ selectedTint }}
<listCard v-model="selectedTint[name]" :isRadio="true" :isWide="true" :buttonImage="
require(`@/assets/img/tints/${getTintSourceImage(
glassLocation,
@ -123,7 +123,7 @@ export default {
ResetTintAndPartSelections() {
this.selectedTint = {};
this.selectedPart = {};
},
}
},
};
</script>

View file

@ -3,12 +3,19 @@
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage="false" />
<funnelSubHeader ref="funnelSubHeader" />
{{ glassParts }}
<div class="container-fluid prevent-squish my-5">
<div class="row">
<div class="col">
<alert class="rounded border-0 shadow-sm" alertClass="alert-warning" :alertHeadline="alertWidgetData.headline" :alertCopy="alertWidgetData.copy" :isDismissible="false" />
</div>
</div>
</div>
<div v-for="(item, i) in Parts" :key="i">
<partQuestion :ref="`${refPrefix}-${item.glassLocation}`" v-model="glassParts[item.glassLocation + '-' + item.glassName]" :glassLocation="item.glassLocation" :glassName="item.glassName" :colorAnswers="item.colorAnswers" />
<br />
</div>
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" />
</div>
</template>
@ -20,6 +27,7 @@ import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import alert from "@/ux-components/alert/alert";
// Supporting Files
import {
@ -29,6 +37,7 @@ import {
settleAllPromises
} from "@/helpers/layout-helper";
export default {
name: "vehicle-parts",
async beforeRouteEnter(to, from, next) {
@ -38,8 +47,8 @@ export default {
// Settle promises and get results
const promiseResultMap = [{
resultKey: "cmsContent",
promise: cmsContentPromise
}];
promise: cmsContentPromise,
}, ];
const resultMap = await settleAllPromises(promiseResultMap);
@ -61,16 +70,27 @@ export default {
// Part Question dynamic component
Object.keys(vm.$refs)
.filter((r) => r.includes(vm.refPrefix) && vm.$refs[r][0] !== undefined)
.forEach((c) => vm.$refs[c][0].initializeComponent({
ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget
}));
.forEach((c) =>
vm.$refs[c][0].initializeComponent({
ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget,
})
);
// Set alertData for the page alert. These use props so we don't call
// initializeComponent here.
vm.alertWidgetData = {
copy: resultMap.cmsContent.AlertWidget.BodyText,
headline: resultMap.cmsContent.AlertWidget.HeadlineText
};
});
},
data() {
return {
glassParts: {},
refPrefix: "partQuestion",
alertWidgetData: Object,
};
},
components: {
@ -79,82 +99,85 @@ export default {
vehicleBanner,
funnelSubHeader,
funnelFooter,
alert,
},
computed: {
Parts() {
return [{
glassLocation: "Rear",
glassName: "Stationary",
colorAnswers: [{
ColorAnswerText: "Green Tint",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 1 hole",
PartNumber: "test-backglass-green-tint-1-hole",
}, ],
},
{
ColorAnswerText: "Green Tint",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 2 hole",
PartNumber: "test-backglass-green-tint-2-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 3 hole",
PartNumber: "test-backglass-gray-tint-privacy-3-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 4 hole",
PartNumber: "test-backglass-blue-tint-4-hole",
}, ],
},
],
},
{
glassLocation: "Windshield",
glassName: "Single",
colorAnswers: [{
ColorAnswerText: "Blue Tint",
FeatureAnswers: [{
FeatureAnswerText: "Windshield - heated glass, solar, 1 hole",
PartNumber: "test-windshield-blue-tint-1-hole",
}, ],
},
{
ColorAnswerText: "Blue Tint",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 2 hole",
PartNumber: "test-blue-tint-windshield-2-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 3 hole",
PartNumber: "test-gray-tint-privacy-windshield-3-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 4 hole",
PartNumber: "test-brown-tint-windshield-4-hole",
}, ],
},
],
},
]
}
glassLocation: "Rear",
glassName: "Stationary",
colorAnswers: [{
ColorAnswerText: "Green Tint",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 1 hole",
PartNumber: "test-backglass-green-tint-1-hole",
}, ],
},
{
ColorAnswerText: "Green Tint",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 2 hole",
PartNumber: "test-backglass-green-tint-2-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 3 hole",
PartNumber: "test-backglass-gray-tint-privacy-3-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Backglass - heated glass, solar, 4 hole",
PartNumber: "test-backglass-blue-tint-4-hole",
}, ],
},
],
},
{
glassLocation: "Windshield",
glassName: "Single",
colorAnswers: [{
ColorAnswerText: "Blue Tint",
FeatureAnswers: [{
FeatureAnswerText: "Windshield - heated glass, solar, 1 hole",
PartNumber: "test-windshield-blue-tint-1-hole",
}, ],
},
{
ColorAnswerText: "Blue Tint",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 2 hole",
PartNumber: "test-blue-tint-windshield-2-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 3 hole",
PartNumber: "test-gray-tint-privacy-windshield-3-hole",
}, ],
},
{
ColorAnswerText: "Gray Tint Privacy",
FeatureAnswers: [{
FeatureAnswerText: "Windshield -heated glass, solar, 4 hole",
PartNumber: "test-brown-tint-windshield-4-hole",
}, ],
},
],
},
];
},
},
methods: {
arePagePrerequisitesValid() {
// return store.getters.damage.isRepair !== null;
return true;
},
}
},
};
</script>

View file

@ -25,6 +25,11 @@ export const state = {
numberOfChips: null,
glassToReplace: null,
},
lineItems:{
glassParts: null,
childParts: null,
otherParts: null
}
},
applicationUser: {
eventBus: [],
@ -102,7 +107,9 @@ export const mutations = {
},
resetPartsAndDependencies(state) {
state.glassParts = null;
state.childParts = null;
state.otherParts = null;
}
}
@ -118,6 +125,8 @@ export const getters = {
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
},
eventBus: (state) => state.applicationUser.eventBus,
damage: (state) => state.order.damage,
lineItems: (state) => state.order.lineItems
}
// Export Actions

View file

@ -3,7 +3,6 @@
body {
font-size: 16px;
background-color: #fff;
.container-fluid {
max-width: 576px; //Remove once desktop app is complete
&.container-shadow {
@ -14,6 +13,9 @@ body {
display: flex;
flex-direction: column;
}
.prevent-squish{
overflow-x: unset;
}
}
.pointer {
cursor: pointer;

View file

@ -63,7 +63,7 @@ export default {
};
this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent);
//this.$emit("update:modelValue", emitEvent);
}
},
},