CSR-762 Add mini test

This commit is contained in:
Katie 2022-09-15 14:44:50 -04:00
parent 0ee3bb672a
commit 6e901a6918
6 changed files with 276 additions and 39 deletions

View file

@ -1,18 +1,60 @@
<!-- Documented in confluence https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Component --> <!-- Documented in confluence https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Component -->
<template> <template>
<div :class="isOverflowScrollable ? 'button-question button-question-overflow' : 'button-question'"> <div
<div v-if="questionText && answers && answers.length > 0" class="question-text d-flex"> :class="
isOverflowScrollable
? 'button-question button-question-overflow'
: 'button-question'
"
>
<div
v-if="questionText && answers && answers.length > 0"
class="question-text d-flex"
>
<span class="fw-bold w-100">{{ questionText }}</span> <span class="fw-bold w-100">{{ questionText }}</span>
</div> </div>
selectedValues: {{ selectedValues }}
<div class="w-100 d-flex justify-content-center"> <div class="w-100 d-flex justify-content-center">
<fieldset class="w-100" :aria-required=isRequired :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="formatString(groupName)"> <fieldset
<legend class="sr-only" :data-focus-target="formatString(groupName)" :id="formatString(groupName)" tabindex="-1"> class="w-100"
:aria-required="isRequired"
:class="getFieldSetClasses"
:role="isMultiSelect ? 'group' : 'radiogroup'"
:aria-labelledby="formatString(groupName)"
>
<legend
class="sr-only"
:data-focus-target="formatString(groupName)"
:id="formatString(groupName)"
tabindex="-1"
>
{{ questionText }} {{ questionText }}
{{(isMultiSelect && answers && answers.length > 1) ? 'Select one or more options below.' : 'Select an option below.' }} {{
isMultiSelect && answers && answers.length > 1
? "Select one or more options below."
: "Select an option below."
}}
</legend> </legend>
<div :class="getComponentLoopWrapperClasses"> <div :class="getComponentLoopWrapperClasses">
<div :class="getComponentWrapperClasses" v-for="answer in answers" :key="answer.Name ? answer.Name : answer"> <div
:class="getComponentWrapperClasses"
v-for="answer in answers"
:key="answer.Name ? answer.Name : answer"
>
<component <component
:is="buttonType"
:buttonLabel="
answer.Text ? answer.Text : getAnswerString(answer, 'Name')
"
:buttonLabelSubCopy="answer.SubText"
:isMultiSelect="isMultiSelect"
:groupName="groupName"
:value="answer.Value"
:modelValue="modelValue"
@change="e => handleSelectionChange(e, answer.Value)"
/>
<!-- <component
:is="buttonType" :is="buttonType"
@isCheckedChanged="handleCheckedChanged" @isCheckedChanged="handleCheckedChanged"
:buttonID="answer.Name ? formatString(groupName) + '-' + answer.Name : formatString(groupName) + '-' + getAnswerString(answer, 'Text')" :buttonID="answer.Name ? formatString(groupName) + '-' + answer.Name : formatString(groupName) + '-' + getAnswerString(answer, 'Text')"
@ -38,10 +80,15 @@
:validationRules="validationRules" :validationRules="validationRules"
:class="[suppressError ? 'alertError' : '' , isCashOrInsurance ? 'radio-fancy' : '']" :class="[suppressError ? 'alertError' : '' , isCashOrInsurance ? 'radio-fancy' : '']"
:valueToLogType="valueToLogType" :valueToLogType="valueToLogType"
/> /> -->
<!-- For nested questions --> <!-- For nested questions -->
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div v-if="typeof selectedValues == 'string' && selectedValues == answer.Name"> <div
v-if="
typeof selectedValues == 'string' &&
selectedValues == answer.Name
"
>
<slot></slot> <slot></slot>
</div> </div>
</transition> </transition>
@ -50,7 +97,10 @@
</fieldset> </fieldset>
</div> </div>
<div class="row form-test-error mt-1"> <div class="row form-test-error mt-1">
<error-message :name="formatString(groupName)" v-if="!suppressError"></error-message> <error-message
:name="formatString(groupName)"
v-if="!suppressError"
></error-message>
</div> </div>
</div> </div>
</template> </template>
@ -59,8 +109,9 @@
import listButton from "@/ux-components/list-button/list-button"; import listButton from "@/ux-components/list-button/list-button";
import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal"; import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal";
import listCard from "@/ux-components/list-card/list-card"; 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"; import radio from "@/ux-components/radio/radio";
import testButton from "@/common-components/test-button.vue";
export default { export default {
name: "buttonQuestion", name: "buttonQuestion",
@ -90,7 +141,8 @@ export default {
isOverflowScrollable: Boolean, isOverflowScrollable: Boolean,
isWide: Boolean, isWide: Boolean,
isCashOrInsurance: Boolean, isCashOrInsurance: Boolean,
modelValue: [Array, String], modelValue: [Array, Number, String],
value: [Number, String],
validationRules: String, validationRules: String,
suppressError: Boolean, suppressError: Boolean,
useTextForValue: Boolean, useTextForValue: Boolean,
@ -100,11 +152,9 @@ export default {
getFieldSetClasses() { getFieldSetClasses() {
if (this.isOverflowScrollable) { if (this.isOverflowScrollable) {
return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"; return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0";
} } else if (this.buttonType == "listCard") {
else if (this.buttonType == "listCard") {
return "w-100"; return "w-100";
} } else {
else {
return ""; return "";
} }
}, },
@ -117,11 +167,11 @@ export default {
case "listButtonHorizontal": case "listButtonHorizontal":
classes = "d-flex flex-row p-0"; classes = "d-flex flex-row p-0";
break; break;
case 'listCard': case "listCard":
classes = "row g-2 justify-content-center"; classes = "row g-2 justify-content-center";
break; break;
case 'radio': case "radio":
classes = 'ui-radio d-flex' classes = "ui-radio d-flex";
break; break;
} }
return classes; return classes;
@ -129,7 +179,7 @@ export default {
getComponentWrapperClasses() { getComponentWrapperClasses() {
let classes = ""; let classes = "";
classes += this.isWide ? "col-12" : "col"; classes += this.isWid ? "col-12" : "col";
if (this.buttonType == "radio") { if (this.buttonType == "radio") {
classes += " radio-button-container"; classes += " radio-button-container";
@ -137,28 +187,31 @@ export default {
return classes; return classes;
}, },
getColLength(){ getColLength() {
if(this.isWide) { if (this.isWide) {
return "12" return "12";
} else { } else {
return ""; return "";
} }
}, },
selectedValues: { selectedValues: {
get: function() { get: function () {
return this.modelValue; return this.modelValue;
}, },
set: function(newValue) { set: function (newValue) {
this.$emit("update:modelValue", newValue); // this.$emit("update:modelValue", newValue);
} },
}, },
}, },
methods: { methods: {
formatString(str) { formatString(str) {
return str.replace(" ", "-"); console.log(str);
return str?.replace(" ", "-");
}, },
getValue(answer){ getValue(answer) {
if (this.useTextForValue) { return answer.Text } if (this.useTextForValue) {
return answer.Text;
}
return answer.Name ? answer.Name : answer; return answer.Name ? answer.Name : answer;
}, },
getAnswerString(answer, prop = "Name") { getAnswerString(answer, prop = "Name") {
@ -168,24 +221,49 @@ export default {
case "boolean": case "boolean":
return this.formatString(answer.toString()); return this.formatString(answer.toString());
default: default:
return answer[prop] ? this.formatString(answer[prop]) : this.formatString(answer.toString()); return answer[prop]
? this.formatString(answer[prop])
: this.formatString(answer.toString());
} }
}, },
handleCheckedChanged(val) { handleCheckedChanged(val) {
if(this.selectingInitiatesLoad) { if (this.selectingInitiatesLoad) {
this.selectedValues = val.value; this.selectedValues = val.value;
} else { } else {
if(Array.isArray(this.selectedValues)) { if (Array.isArray(this.selectedValues)) {
const newSelectedValues = this.selectedValues; const newSelectedValues = this.selectedValues;
val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1); val.checkValue
? newSelectedValues.push(val.value)
: newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
this.selectedValues = newSelectedValues; this.selectedValues = newSelectedValues;
} } else {
else {
this.selectedValues = val.value; this.selectedValues = val.value;
} }
} }
this.$emit("isCheckedChanged", val); this.$emit("isCheckedChanged", val);
}, },
handleSelectionChange(event, value) {
console.log(value)
console.log("BQ handleSelectionChange: ", event)
let isChecked = event.target.checked;
if (this.isMultiSelect && this.modelValue instanceof Array) {
let newValue = [...this.modelValue];
const toggledValue = event.target.value;
console.log("A: ", this.modelValue)
console.log("isChecked: ", isChecked)
console.log("value: ", event.target.value)
if (isChecked) {
newValue.push(toggledValue);
} else {
newValue.splice(newValue.indexOf(toggledValue), 1);
}
console.log("handleCheckboxChange: ", newValue);
this.$emit("update:modelValue", newValue);
} else {
console.log("handleRadioChange: ", isChecked);
this.$emit("update:modelValue", value);
}
},
}, },
components: { components: {
listButton, listButton,
@ -193,6 +271,7 @@ export default {
listCard, listCard,
ErrorMessage, ErrorMessage,
radio, radio,
testButton,
}, },
}; };
</script> </script>
@ -231,9 +310,9 @@ export default {
.vehicle-parts { .vehicle-parts {
.question-text { .question-text {
span { span {
font-size: .875rem; font-size: 0.875rem;
text-align: left; text-align: left;
margin: 0 0 .5rem 0; margin: 0 0 0.5rem 0;
} }
} }
.question-text { .question-text {

View file

@ -0,0 +1,35 @@
<template>
<label :class="{ classNames }">
value: {{value}} <br/>
modelValue: {{modelValue}} <br/>
isChecked: {{isChecked}} <br/>
<input
v-if="isMultiSelect"
type="checkbox"
:id="JSON.stringify(modelValue)"
:name="groupName"
:aria-required="isRequired"
:value="value"
:checked="isChecked"
@change="handleSelectionChange"
/>
<input
v-else
type="radio"
:id="JSON.stringify(modelValue)"
:name="groupName"
:aria-required="isRequired"
v-model="modelValue"
:checked="isChecked"
@change="handleSelectionChange"
/>
</label>
</template>
<script>
import buttonMixin from "../mixins/button-mixin";
export default {
name: "test-button",
mixins: [buttonMixin],
};
</script>

56
src/layouts/test.vue Normal file
View file

@ -0,0 +1,56 @@
<template>
<div>
selectedMultiselectValues: {{ selectedMultiselectValues }}
<button-question
buttonType="testButton"
:answers="sampleAnswers"
:isMultiSelect="true"
groupName="multiselect-test"
v-model="selectedMultiselectValues"
></button-question>
<br /><br /><br />
selectedRadioValue: {{ selectedRadioValue }}
<button-question
buttonType="testButton"
:answers="sampleAnswers"
:isMultiSelect="false"
groupName="radio-test"
v-model="selectedRadioValue"
></button-question>
</div>
</template>
<script>
import ButtonQuestion from "../common-components/button-question/button-question.vue";
export default {
name: "test",
data() {
return {
sampleAnswers: [
{
Text: "Part 1",
Value: "PART1",
},
{
Text: "Part 2",
Value: "PART2",
},
{
Text: "Part 3",
Value: "PART3",
},
],
selectedMultiselectValues: [],
selectedRadioValue: "",
};
},
components: {
// testButton,
ButtonQuestion,
},
};
</script>

View file

@ -0,0 +1,61 @@
export default {
model: {
prop: "modelValue",
event: "change",
},
props: {
value: {
type: [String, Number],
required: true,
},
modelValue: {
type: [Array, String, Number],
required: true,
},
isMultiSelect: Boolean,
isWide: Boolean,
buttonImage: String,
buttonImageId: String,
buttonLabel: {
type: String,
required: true,
},
isRequired: {
type: Boolean,
required: true,
},
buttonLabelSubCopy: {
type: String,
required: true,
},
groupName: {
type: String,
required: true,
},
},
data() {},
methods: {
handleSelectionChange(event) {
let isChecked = event.target.checked;
if (this.isMultiSelect && this.modelValue instanceof Array) {
let newValue = [...this.modelValue];
if (isChecked && !newValue.includes(this.value)) {
newValue.push(this.value);
} else {
newValue.splice(newValue.indexOf(this.value), 1);
}
this.$emit("change", newValue);
} else {
this.$emit("change", isChecked);
}
},
},
computed: {
isChecked() {
if (this.isMultiSelect && this.modelValue instanceof Array) {
this.modelValue.includes(this.value);
}
return this.modelValue === this.value;
},
},
};

View file

@ -23,6 +23,7 @@ import { applicationConfig } from "../constants/application-config";
// Components // Components
import quote from "@/layouts/quote/quote.vue"; import quote from "@/layouts/quote/quote.vue";
import test from "@/layouts/test"
const routes = [ const routes = [
{ {
@ -30,6 +31,11 @@ const routes = [
name: "quote", name: "quote",
component: quote, component: quote,
}, },
{
path: "/test", // This is a temporary route for testing.
name: "test",
component: test,
},
{ {
path: "/", path: "/",
name: "root", name: "root",

View file

@ -76,7 +76,7 @@ export default {
buttonLabel: String, //Required: Label text buttonLabel: String, //Required: Label text
isRequired: Boolean, //Required: is aria-required required or not? isRequired: Boolean, //Required: is aria-required required or not?
altText: String, //Leave empty. Screen readers read the buttonLabel text. If alt has content, it will repeat unnecessarily. altText: String, //Leave empty. Screen readers read the buttonLabel text. If alt has content, it will repeat unnecessarily.
buttonID: String, //Required: Unique buttonID: String, // TODO KO We don't use this //Required: Unique
groupName: String, //Rquired: Unique groupName: String, //Rquired: Unique
buttonLabelSubCopy: String, //Optional: sub text buttonLabelSubCopy: String, //Optional: sub text
value: { value: {
@ -84,7 +84,7 @@ export default {
type: String, type: String,
default: "", default: "",
}, },
colLength: String, // colLength: String,
validationRules: String, validationRules: String,
selectedValues: [Array, String], selectedValues: [Array, String],
hasError: Boolean, hasError: Boolean,