Merge branch 'develop' into feature/CSR-6
This commit is contained in:
commit
6bafa88c28
35 changed files with 1042 additions and 341 deletions
29
package-lock.json
generated
29
package-lock.json
generated
|
|
@ -14,7 +14,6 @@
|
|||
"canvas-confetti": "^1.4.0",
|
||||
"core-js": "^3.6.5",
|
||||
"http-status-codes": "^2.1.4",
|
||||
"jest-junit": "^13.0.0",
|
||||
"vue": "^3.0.0",
|
||||
"vue-router": "^4.0.11",
|
||||
"vuex": "^4.0.2",
|
||||
|
|
@ -32,6 +31,7 @@
|
|||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"jest-junit": "^13.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
|
|
@ -10962,6 +10962,7 @@
|
|||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz",
|
||||
"integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mkdirp": "^1.0.4",
|
||||
"strip-ansi": "^6.0.1",
|
||||
|
|
@ -10976,6 +10977,7 @@
|
|||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
|
|
@ -10984,6 +10986,7 @@
|
|||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
|
|
@ -10995,6 +10998,7 @@
|
|||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
|
|
@ -11006,6 +11010,7 @@
|
|||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
|
|
@ -11743,9 +11748,6 @@
|
|||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
|
|
@ -18003,7 +18005,6 @@
|
|||
"integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"neo-async": "^2.5.0"
|
||||
},
|
||||
|
|
@ -18067,7 +18068,6 @@
|
|||
"anymatch": "^2.0.0",
|
||||
"async-each": "^1.0.1",
|
||||
"braces": "^2.3.2",
|
||||
"fsevents": "^1.2.7",
|
||||
"glob-parent": "^3.1.0",
|
||||
"inherits": "^2.0.3",
|
||||
"is-binary-path": "^1.0.0",
|
||||
|
|
@ -18982,7 +18982,8 @@
|
|||
"node_modules/xml": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
|
||||
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU="
|
||||
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xml-name-validator": {
|
||||
"version": "3.0.0",
|
||||
|
|
@ -27872,6 +27873,7 @@
|
|||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz",
|
||||
"integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mkdirp": "^1.0.4",
|
||||
"strip-ansi": "^6.0.1",
|
||||
|
|
@ -27882,17 +27884,20 @@
|
|||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
|
|
@ -27900,7 +27905,8 @@
|
|||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -34454,7 +34460,8 @@
|
|||
"xml": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
|
||||
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU="
|
||||
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
|
||||
"dev": true
|
||||
},
|
||||
"xml-name-validator": {
|
||||
"version": "3.0.0",
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"jest-junit": "^13.0.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-unit-jest": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
|
|
@ -33,6 +32,7 @@
|
|||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"jest-junit": "^13.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
|
|
|
|||
BIN
src/assets/img/blurrycar.png
Normal file
BIN
src/assets/img/blurrycar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
3
src/assets/img/icons/spinner.svg
Normal file
3
src/assets/img/icons/spinner.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" xml:space="preserve">
|
||||
<path d="M24.01 48c-2.93 0-5.92-.52-8.85-1.58-6.25-2.25-11.33-7.33-13.58-13.57C-1.25 25-.25 16.76 4.34 10.22A24.05 24.05 0 0 1 24 0v2.26c-7.08 0-13.74 3.46-17.81 9.27-4.16 5.91-5.07 13.4-2.49 20.55 2.03 5.62 6.6 10.19 12.22 12.22 7.14 2.58 14.64 1.67 20.56-2.49A21.78 21.78 0 0 0 45.74 24H48c0 7.81-3.82 15.16-10.22 19.66A23.846 23.846 0 0 1 24.01 48z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 446 B |
|
|
@ -19,8 +19,7 @@ describe("radioQuestion.vue", () => {
|
|||
"Question Text"
|
||||
);
|
||||
const radioButtons = wrapper.findAllComponents('[data-test="radio"]');
|
||||
expect(radioButtons[0].attributes("text")).toEqual("2023");
|
||||
expect(radioButtons[2].attributes("text")).toEqual("2021");
|
||||
expect(radioButtons.length).toBe(3);
|
||||
expect(typeof wrapper.props().chooseAnswer).toBe("function");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
<template>
|
||||
<div class="radio_question">
|
||||
<div class="needed_car_info d-flex mt-4 mb-3">
|
||||
<div class="needed_car_info mt-4 mb-2 d-flex">
|
||||
<span class="text-center fs-6 fw-bold w-100 needed_car_info-text">{{
|
||||
questionText
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="car_list overflow-scroll position-absolute">
|
||||
<div v-for="answer in answers" :key="answer" class="mb-2">
|
||||
<radio
|
||||
:text="answer"
|
||||
:value="answer"
|
||||
@click="chooseAnswer(answer)"
|
||||
data-test="radio"
|
||||
/>
|
||||
<div class="w-100 d-flex justify-content-center">
|
||||
<div class="car_list overflow-scroll position-absolute container-fluid pt-1" role="radiogroup" aria-labelledby="select-year-radio-group">
|
||||
<h3 class="visually-hidden" id="select-year-radio-group">*</h3>
|
||||
<radio v-for="answer in answers" :key="answer" class="mb-2"
|
||||
:radioID="answer"
|
||||
@click="chooseAnswer(answer)"
|
||||
loaderColor="blue"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1.5"
|
||||
data-test="radio"
|
||||
groupName="radio-list"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -31,4 +35,4 @@ export default {
|
|||
radio,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
</script>
|
||||
144
src/common-components/vehicle-banner/vehicle-banner.spec.js
Normal file
144
src/common-components/vehicle-banner/vehicle-banner.spec.js
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import vehicleBanner from './vehicle-banner';
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
describe('vehicleBanner', () => {
|
||||
const $store = {
|
||||
state: {
|
||||
order: {
|
||||
vehicle: {
|
||||
vin: null,
|
||||
year: null,
|
||||
make: null,
|
||||
model: null,
|
||||
style: null
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const actionList = {
|
||||
actionList: [
|
||||
{
|
||||
actionName: storeActions.LOOKUP_VEHICLE_BY_YMMS,
|
||||
data: [
|
||||
{
|
||||
CarId: "CR00068434"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
actionName: storeActions.LOOKUP_VEHICLE_BY_VIN,
|
||||
data: [
|
||||
{
|
||||
CarId: "CR00068434"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
actionName: storeActions.GET_EVOX_IMAGE,
|
||||
data: {
|
||||
imgSrc: "https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
test('renders the blurrycar image when vehicleImageSrc is not present', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
...mountOptions.global.mocks,
|
||||
$store
|
||||
}
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleBanner, {
|
||||
...mountOptions
|
||||
});
|
||||
// Assert
|
||||
expect(wrapper.find('img').attributes('class')).toContain('blurrycar');
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('does not render the blurrycar image when vehicleImageSrc exists', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
...mountOptions.global.mocks,
|
||||
$store
|
||||
}
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleBanner, {
|
||||
...mountOptions,
|
||||
data() {
|
||||
return {
|
||||
vehicleImageSrc: "https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg"
|
||||
}
|
||||
}
|
||||
});
|
||||
// Assert
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('does not render the blurrycar image when passedCarId is set', async () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
...mountOptions.global.mocks,
|
||||
$store,
|
||||
}
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleBanner, {
|
||||
...mountOptions,
|
||||
props: {
|
||||
passedCarId: "CR00068434"
|
||||
}
|
||||
});
|
||||
// Assert
|
||||
await nextTick();
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('receives a carId when a YMMS object is found', async () => {
|
||||
// Arrange
|
||||
$store.state.order.vehicle.year = "2019"
|
||||
$store.state.order.vehicle.make = "acura"
|
||||
$store.state.order.vehicle.model = "rdx"
|
||||
$store.state.order.vehicle.style = "4 door utility"
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
...mountOptions.global.mocks,
|
||||
$store
|
||||
}
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleBanner, {
|
||||
...mountOptions
|
||||
});
|
||||
// Assert
|
||||
await nextTick();
|
||||
expect(wrapper.vm.$data.carId.length).toBeGreaterThan(0);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('receives a carId when a VIN is found', async () => {
|
||||
// Arrange
|
||||
$store.state.order.vehicle.vin = "1J4GW58S4XC541166";
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
...mountOptions.global.mocks,
|
||||
$store
|
||||
}
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleBanner, {
|
||||
...mountOptions
|
||||
});
|
||||
// Assert
|
||||
await nextTick();
|
||||
expect(wrapper.vm.$data.carId.length).toBeGreaterThan(0);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
});
|
||||
81
src/common-components/vehicle-banner/vehicle-banner.vue
Normal file
81
src/common-components/vehicle-banner/vehicle-banner.vue
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<div class="vehicle_banner mb-3 text-center">
|
||||
<img
|
||||
class="vehicle-image img-fluid"
|
||||
:src="vehicleImageSrc"
|
||||
v-if="vehicleImageSrc"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
class="vehicle-image img-fluid blurrycar"
|
||||
src='@/assets/img/blurrycar.png'
|
||||
alt=""
|
||||
v-else
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "vehicle-banner",
|
||||
computed: {
|
||||
vin () {
|
||||
return this.$store.state.order.vehicle.vin;
|
||||
},
|
||||
ymms () {
|
||||
return {
|
||||
year: this.$store.state.order.vehicle.year,
|
||||
make: this.$store.state.order.vehicle.make,
|
||||
model: this.$store.state.order.vehicle.model,
|
||||
style: this.$store.state.order.vehicle.style
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
passedCarId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
years: [],
|
||||
carId: '',
|
||||
vehicleImageSrc: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.passedCarId && this.passedCarId.length > 0) {
|
||||
this.getVehicleImage(this.passedCarId)
|
||||
} else if (this.vin && this.vin.length > 0) {
|
||||
this.getCarIdWithVin(this.vin)
|
||||
} else if (!Object.values(this.ymms).includes(null) && !Object.values(this.ymms).includes('')) {
|
||||
this.getCarIdWithYmms(this.ymms)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCarIdWithYmms(ymms) { // retrieve carId with YMMS object
|
||||
this.dispatchNonBlockingStoreAction(this.storeActions.LOOKUP_VEHICLE_BY_YMMS, ymms).then((response) => {
|
||||
this.carId = response.data[0].CarId;
|
||||
this.getVehicleImage(this.carId)
|
||||
});
|
||||
},
|
||||
getCarIdWithVin(vin) { // retrieve carId with VIN string
|
||||
this.dispatchNonBlockingStoreAction(this.storeActions.LOOKUP_VEHICLE_BY_VIN, vin).then((response) => {
|
||||
this.carId = response.data[0].CarId;
|
||||
this.getVehicleImage(this.carId)
|
||||
});
|
||||
},
|
||||
getVehicleImage(carId) { // look up evox with carId
|
||||
this.dispatchNonBlockingStoreAction(this.storeActions.GET_EVOX_IMAGE, {relativeUrl: "https://mockey.qa.sagaws.net/service/evox-image?carId=" + carId}).then((response) => {
|
||||
if (response.data && response.data.imgSrc) {
|
||||
this.vehicleImageSrc = response.data.imgSrc;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vehicle-image {
|
||||
max-width: 290px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -23,6 +23,14 @@ const endpoints = {
|
|||
url: "/content/api/v1/content",
|
||||
method: "GET",
|
||||
},
|
||||
LookupVehicleByYmms: {
|
||||
url: "/vehicle/api/v1/vehicle/Lookup",
|
||||
method: "GET",
|
||||
},
|
||||
LookupVehicleByVin: {
|
||||
url: "/vehicle/api/v1/vehicle/Lookup",
|
||||
method: "POST",
|
||||
},
|
||||
};
|
||||
|
||||
export { endpoints };
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ const storeActions = {
|
|||
GET_VEHICLE_MAKES: "getVehicleMakes",
|
||||
GET_VEHICLE_MODELS: "getVehicleModels",
|
||||
GET_VEHICLE_STYLES: "getVehicleStyles",
|
||||
GET_EVOX_IMAGE: "getEvoxImage",
|
||||
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
|
||||
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin"
|
||||
};
|
||||
|
||||
export { storeActions };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { storeActions } from "@/constants/store-actions";
|
||||
import store from "@/store";
|
||||
|
||||
export function getMountOptions(mockData) {
|
||||
// Define our mocks to attached to the 'global' object for Vue/Jest.
|
||||
|
|
@ -22,7 +23,8 @@ export function getMountOptions(mockData) {
|
|||
|
||||
const global = {
|
||||
mocks: mocks,
|
||||
plugins: [store]
|
||||
};
|
||||
|
||||
return { global };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,125 +1,273 @@
|
|||
<template>
|
||||
<div class="container-fluid container-shadow p-2 rounded-3">
|
||||
<div class="container-fluid container-shadow p-2 rounded-3">
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Radio Card</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-2">
|
||||
<radioCard radioLabel="Windshield" radioImage="windshield-damage.svg" altText="Windshield" groupName="damageKey" radioID="windshield" />
|
||||
<radioCard radioLabel="Side Window" radioImage="side-window-damage.svg" altText="Side Window" groupName="damageKey" radioID="sidewindow" />
|
||||
<radioCard radioLabel="Back Glass" radioImage="back-glass-damage.svg" altText="Back Glass" groupName="damageKey" radioID="backglass" />
|
||||
<radioCard
|
||||
radioLabel="Windshield"
|
||||
radioImage="windshield-damage.svg"
|
||||
altText="Windshield"
|
||||
groupName="damageKey"
|
||||
radioID="windshield"
|
||||
/>
|
||||
<radioCard
|
||||
radioLabel="Side Window"
|
||||
radioImage="side-window-damage.svg"
|
||||
altText="Side Window"
|
||||
groupName="damageKey"
|
||||
radioID="sidewindow"
|
||||
/>
|
||||
<radioCard
|
||||
radioLabel="Back Glass"
|
||||
radioImage="back-glass-damage.svg"
|
||||
altText="Back Glass"
|
||||
groupName="damageKey"
|
||||
radioID="backglass"
|
||||
/>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Buttons</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary buttonText="Primary" />
|
||||
</div>
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary
|
||||
buttonText="Primary"
|
||||
loaderColor="white"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonSecondary buttonText="Secondary" />
|
||||
</div>
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonSecondary
|
||||
buttonText="Secondary"
|
||||
loaderColor="white"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">List Button</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<listButton buttonText="List Button" errorText="Test error message" />
|
||||
</div>
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<listButton
|
||||
buttonText="List Button"
|
||||
errorText="Test error message"
|
||||
loaderColor="blue"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1.5"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Radio Button Group</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- The role="radiogroup" and aria-labelledby must be included in the parent component for the radio group -->
|
||||
<div role="radiogroup" aria-labelledby="select-year-radio-group" class="col my-3 d-flex align-items-center flex-column">
|
||||
<!-- The h3 and id must be included. The id must match the aria-labelledby of the parent div. -->
|
||||
<h3 class="visually-hidden" id="select-year-radio-group">
|
||||
Select Vehicle Year
|
||||
</h3>
|
||||
<radioList groupName="demo" ariaLabelBy="vehicle-year" radioID="2021" errorMessage="Test error message" />
|
||||
<radioList groupName="demo" ariaLabelBy="vehicle-year" radioID="2020" errorMessage="Test error message" />
|
||||
<radioList groupName="demo" ariaLabelBy="vehicle-year" radioID="2019" errorMessage="Test error message" />
|
||||
</div>
|
||||
<!-- The role="radiogroup" and aria-labelledby must be included in the parent component for the radio group -->
|
||||
<div role="radiogroup" aria-labelledby="select-year-radio-group" class="col my-3 d-flex align-items-center flex-column">
|
||||
<!-- The h3 and id must be included. The id must match the aria-labelledby of the parent div. -->
|
||||
<h3 class="visually-hidden" id="select-year-radio-group">Select Vehicle Year</h3>
|
||||
<radioList
|
||||
groupName="demo"
|
||||
ariaLabelBy="vehicle-year"
|
||||
radioID="2021"
|
||||
loaderColor="blue"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1.5"
|
||||
/>
|
||||
<radioList
|
||||
groupName="demo"
|
||||
ariaLabelBy="vehicle-year"
|
||||
radioID="2020"
|
||||
loaderColor="blue"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1.5"
|
||||
/>
|
||||
<radioList
|
||||
groupName="demo"
|
||||
ariaLabelBy="vehicle-year"
|
||||
radioID="2019"
|
||||
loaderColor="blue"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1.5"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Text Link</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<a href="#">Text Link</a>
|
||||
</div>
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<a href="#">Text Link</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Typogrophy</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<p>This is default body copy font size/weight</p>
|
||||
<p class="small">This is small body copy using <code>.small</code> class</p>
|
||||
<p><small>This is also small using <code><small></code> tag</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Headings</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h1>h1 Heading</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h2>h2 Heading</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h3>h3 Heading</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h4>h4 Heading</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h5>h5 Heading</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h6>h6 Heading</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Alerts</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<alert
|
||||
alertClass="alert-success"
|
||||
alertHeadline="Dismissible Alert"
|
||||
alertCopy="This is an example of a DISMISSIBLE alert. It will fade away and content around it will shift when dismissed."
|
||||
v-bind:isDismissible = "true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<alert
|
||||
alertClass="alert-danger"
|
||||
alertHeadline="NON-Dismissible Alert"
|
||||
alertCopy="This is an example of a NON-DISMISSIBLE alert."
|
||||
v-bind:isDismissible = "false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<p>This is default body copy font size/weight</p>
|
||||
<p class="small">
|
||||
This is small body copy using <code>.small</code> class
|
||||
</p>
|
||||
<p>
|
||||
<small>This is also small using <code><small></code> tag</small>
|
||||
</p>
|
||||
</div>
|
||||
<alert
|
||||
alertClass="alert-warning"
|
||||
alertHeadline="Warning Alert"
|
||||
alertCopy="This is an example of a WARNING alert."
|
||||
v-bind:isDismissible = "false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h1>h1 Heading</h1>
|
||||
</div>
|
||||
<div class="col">
|
||||
<alert
|
||||
alertClass="alert-info"
|
||||
alertHeadline="Info Alert"
|
||||
alertCopy="This is an example of a INFO alert."
|
||||
v-bind:isDismissible = "false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h2>h2 Heading</h2>
|
||||
</div>
|
||||
<div class="col">
|
||||
<alert
|
||||
alertClass="alert-danger"
|
||||
alertHeadline="Danger Alert"
|
||||
alertCopy="This is an example of a DANGER alert."
|
||||
v-bind:isDismissible = "false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h3>h3 Heading</h3>
|
||||
</div>
|
||||
<div class="col">
|
||||
<alert
|
||||
alertClass="alert-success"
|
||||
alertHeadline="No Body Copy Alert"
|
||||
alertCopy=""
|
||||
v-bind:isDismissible = "false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h4>h4 Heading</h4>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Vehicle Banner</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h5>h5 Heading</h5>
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="col">
|
||||
<vehicleBanner
|
||||
passedCarId=""
|
||||
/>
|
||||
<vehicleBanner
|
||||
passedCarId="CR00068434"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<h6>h6 Heading</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary buttonText="Primary" @click="testMethod" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<div class="select-car">
|
||||
<div class="select-car-form">
|
||||
<radioQuestion questionText="What year is your vehicle?" :answers="this.years" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import buttonPrimary from "@/ux-components/button-primary/button-primary";
|
||||
import buttonSecondary from "@/ux-components/button-secondary/button-secondary";
|
||||
import radioCard from "@/ux-components/radio-card/radio-card";
|
||||
import listButton from "@/ux-components/list-button/list-button";
|
||||
import radioList from "@/ux-components/radio-list/radio-list";
|
||||
export default {
|
||||
import buttonPrimary from "@/ux-components/button-primary/button-primary";
|
||||
import buttonSecondary from "@/ux-components/button-secondary/button-secondary";
|
||||
import radioCard from "@/ux-components/radio-card/radio-card";
|
||||
import listButton from "@/ux-components/list-button/list-button";
|
||||
import radioList from "@/ux-components/radio-list/radio-list";
|
||||
import alert from "@/ux-components/alert/alert";
|
||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
buttonPrimary,
|
||||
buttonSecondary,
|
||||
radioCard,
|
||||
listButton,
|
||||
radioList,
|
||||
buttonPrimary,
|
||||
buttonSecondary,
|
||||
radioCard,
|
||||
listButton,
|
||||
radioList,
|
||||
alert,
|
||||
vehicleBanner
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
years: [2023, 2022, 2021, 2020],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
console.log("App created");
|
||||
},
|
||||
methods: {
|
||||
testMethod() {
|
||||
this.$router.push("/?fmgPage=vehicle-year");
|
||||
},
|
||||
},
|
||||
};
|
||||
return {
|
||||
years: [2023, 2022, 2021, 2020],
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
28
src/layouts/loader-demo/loader-demo.vue
Normal file
28
src/layouts/loader-demo/loader-demo.vue
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div class="container-fluid container-shadow p-2 rounded-3">
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Loader</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<loader
|
||||
sizeInRem="10"
|
||||
loaderColor="blue"
|
||||
loaderPosition="center"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
loader
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -55,3 +55,15 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.select-car {
|
||||
height: calc(100vh - 1rem);
|
||||
|
||||
.car_list {
|
||||
// Height will be determined by overall height of content above list
|
||||
height: calc(100% - 255px);
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -8,13 +8,13 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
dispatchBlockingStoreAction(type, payload) {
|
||||
// globalMethods.showWaitingModal(true);
|
||||
// dispatchBlockingStoreAction(type, payload) {
|
||||
// // globalMethods.showWaitingModal(true);
|
||||
|
||||
return this.dispatchNonBlockingStoreAction(type, payload).finally(() => {
|
||||
// globalMethods.showWaitingModal(false);
|
||||
});
|
||||
},
|
||||
// return this.dispatchNonBlockingStoreAction(type, payload).finally(() => {
|
||||
// // globalMethods.showWaitingModal(false);
|
||||
// });
|
||||
// },
|
||||
dispatchNonBlockingStoreAction(type, payload, encodePayload = false) {
|
||||
// Encode the payload if required
|
||||
if (encodePayload) {
|
||||
|
|
@ -23,6 +23,30 @@ export default {
|
|||
|
||||
return this.$store.dispatch(type, payload);
|
||||
},
|
||||
GetContentFromCms() {
|
||||
return this.dispatchNonBlockingStoreAction(this.storeActions.GET_PAGE_DATA,{ pageName: this.$route.query.fmgPage }).then((response) => {
|
||||
|
||||
const pageDataFromCms = {};
|
||||
|
||||
response.data.Result.forEach((widget) => {
|
||||
if (Object.values(this.widgetNames).includes(widget.Type)) {
|
||||
// If we already have this widget, push it on the collection
|
||||
if (widget.Type in pageDataFromCms) {
|
||||
pageDataFromCms[widget.Type].push(widget.Model);
|
||||
return;
|
||||
}
|
||||
|
||||
pageDataFromCms[widget.Type] = [widget.Model];
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Our 'Page' is ready because we have data now
|
||||
this.isCmsContentReady = true;
|
||||
|
||||
return pageDataFromCms;
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
storeActions() {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { createWebHistory, createRouter } from "vue-router";
|
|||
import { storeActions } from "@/constants/store-actions.js";
|
||||
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js";
|
||||
import ComponentTest from "@/layouts/component-test/component-test.vue";
|
||||
import LoaderDemo from "@/layouts/loader-demo/loader-demo.vue";
|
||||
import NotFound from "@/layouts/not-found/not-found.vue";
|
||||
import store from "@/store";
|
||||
|
||||
|
|
@ -16,6 +17,11 @@ const routes = [
|
|||
name: "ComponentTest",
|
||||
component: ComponentTest,
|
||||
},
|
||||
{
|
||||
path: "/loader-demo", // This is a temporary route for testing.
|
||||
name: "LoaderDemo",
|
||||
component: LoaderDemo,
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
beforeEnter(to, from, next) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export default createStore({
|
|||
evoxImageId: null,
|
||||
hasSplitWindshieldOption: null,
|
||||
hasBackglassSliderOption: null,
|
||||
imageSrc: '',
|
||||
registration: {
|
||||
rawAddress: null,
|
||||
zipCode: null,
|
||||
|
|
@ -62,7 +63,11 @@ export default createStore({
|
|||
experiments: null,
|
||||
}
|
||||
},
|
||||
mutations: {},
|
||||
mutations: {
|
||||
updateVehicleImage(state, data) {
|
||||
state.order.vehicle.imageSrc = data.imgSrc;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// Vehicle API Actions
|
||||
getVehicleYears(context) {
|
||||
|
|
@ -72,6 +77,22 @@ export default createStore({
|
|||
payload: {},
|
||||
});
|
||||
},
|
||||
lookupVehicleByYmms(context, { year, make, model, style }) {
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.LookupVehicleByYmms.method,
|
||||
endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
lookupVehicleByVin(context, { vin }) {
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.LookupVehicleByVin.method,
|
||||
endpoint: endpoints.LookupVehicleByVin.url,
|
||||
payload: {
|
||||
"vin": vin // EX "1J4GW58S4XC541166"
|
||||
},
|
||||
});
|
||||
},
|
||||
getVehicleMakes(context, { year }) {
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.GetVehicleMakes.method,
|
||||
|
|
@ -111,5 +132,12 @@ export default createStore({
|
|||
payload: {},
|
||||
});
|
||||
},
|
||||
getEvoxImage(context, { relativeUrl }) {
|
||||
return globalMethods.callMockHttpClient({
|
||||
method: endpoints.GetPageData.method,
|
||||
endpoint: relativeUrl,
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
112
src/store/store.spec.js
Normal file
112
src/store/store.spec.js
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import store from './index'
|
||||
import globalMethods from '@/global-methods'
|
||||
|
||||
describe("Actions", () => {
|
||||
it("Should return list of years retrieved", async () => {
|
||||
// Arrange
|
||||
let years = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient = jest.fn();
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: [2023,2022,2021]});
|
||||
});
|
||||
await store.dispatch('getVehicleYears')
|
||||
.then( (response) => {
|
||||
years = response.data;
|
||||
console.log(response);
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(years[0]).toBe(2023);
|
||||
});
|
||||
|
||||
it("Should return list of makes retrieved", async () => {
|
||||
// Arrange
|
||||
let makes = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: ['Baic','Honda','Ford']});
|
||||
});
|
||||
await store.dispatch('getVehicleMakes', {year: 2023})
|
||||
.then( (response) => {
|
||||
makes = response.data;
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(makes[0]).toBe('Baic');
|
||||
});
|
||||
|
||||
it("Should return list of models retrieved", async () => {
|
||||
// Arrange
|
||||
let models = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: ['BJ40 (MEX)','Civic','Accord']});
|
||||
});
|
||||
await store.dispatch('getVehicleModels', {year: 2023, make: 'Baic'})
|
||||
.then( (response) => {
|
||||
models = response.data;
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(models[0]).toBe('BJ40 (MEX)');
|
||||
});
|
||||
|
||||
it("Should return list of styles retrieved", async () => {
|
||||
// Arrange
|
||||
let styles = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: ['4 DOOR UTILITY','2 DOOR']});
|
||||
});
|
||||
await store.dispatch('getVehicleStyles', {year: 2023, make: 'Baic', model: 'BJ40 (MEX)'})
|
||||
.then( (response) => {
|
||||
styles = response.data;
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(styles[0]).toBe('4 DOOR UTILITY');
|
||||
});
|
||||
|
||||
it("Should return data from url retrieved", async () => {
|
||||
// Arrange
|
||||
let routeInfo = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: {
|
||||
Result: 'Route Info Data'
|
||||
}});
|
||||
});
|
||||
await store.dispatch('getRouteInfo', { pageName: 'vehicle-year' })
|
||||
.then( (response) => {
|
||||
routeInfo = response.data.Result;
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(routeInfo).toBe('Route Info Data');
|
||||
});
|
||||
|
||||
it("Should return page data from url retrieved", async () => {
|
||||
// Arrange
|
||||
let pageData = [];
|
||||
|
||||
// Act
|
||||
globalMethods.callHttpClient.mockImplementation(() => {
|
||||
return Promise.resolve({ data: {
|
||||
Result: 'Page Info Data'
|
||||
}});
|
||||
});
|
||||
await store.dispatch('getPageData', { pageName: 'vehicle-year' })
|
||||
.then( (response) => {
|
||||
pageData = response.data.Result;
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(pageData).toBe('Page Info Data');
|
||||
});
|
||||
})
|
||||
|
|
@ -16,23 +16,8 @@
|
|||
&:focus-visible { // Keyboard focus for accessibility
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
||||
}
|
||||
&.button-loader {
|
||||
padding: 0 40px 0 12px;
|
||||
&:after {
|
||||
content: url(../../assets/img/icons/button-spinner-white.svg);
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
color: $white;
|
||||
@include blue-gradient;
|
||||
}
|
||||
&:disabled {
|
||||
background: $gray-100 !important;
|
||||
|
|
@ -59,39 +44,8 @@
|
|||
&:focus-visible { // Keyboard focus for accessibility
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue-700;
|
||||
}
|
||||
&.button-loader {
|
||||
padding: 0 40px 0 12px;
|
||||
&:after {
|
||||
content: url(../../assets/img/icons/button-spinner-blue.svg);
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:focus:hover {
|
||||
&:after {
|
||||
content: url(../../assets/img/icons/button-spinner-white.svg);
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
color: $white;
|
||||
@include blue-gradient;
|
||||
}
|
||||
&:disabled {
|
||||
background: transparent;
|
||||
|
|
@ -130,22 +84,5 @@
|
|||
color: $danger;
|
||||
}
|
||||
}
|
||||
&.button-loader {
|
||||
padding: 0 40px 0 12px;
|
||||
&:after {
|
||||
content: url(../../assets/img/icons/button-spinner-blue.svg);
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
.select-car {
|
||||
height: calc(100vh - 1rem);
|
||||
|
||||
.car_list {
|
||||
// Height will be determined by overall height of content above list
|
||||
height: calc(100% - 100px);
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
}
|
||||
|
||||
// Animations
|
||||
.slide-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(30vw);
|
||||
}
|
||||
.slide-enter-active, .slide-leave-active {
|
||||
transition: all .4s;
|
||||
}
|
||||
.slide-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-30vw);
|
||||
}
|
||||
|
||||
.slide_reverse-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(-30vw);
|
||||
}
|
||||
.slide_reverse-enter-active, .slide_reverse-leave-active {
|
||||
transition: all .4s;
|
||||
}
|
||||
.slide_reverse-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(30vw);
|
||||
}
|
||||
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: all .5s ease;
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
label {
|
||||
position: relative;
|
||||
background: $white;
|
||||
height: 3rem;
|
||||
min-height: 3rem;
|
||||
transition: all 150ms linear;
|
||||
border-radius: $border-radius-lg;
|
||||
border: 1px solid $gray-500;
|
||||
|
|
@ -37,23 +37,6 @@
|
|||
color: $danger;
|
||||
}
|
||||
}
|
||||
&.button-loader {
|
||||
padding: 0 40px 0 12px;
|
||||
&:after {
|
||||
content: url(../../assets/img/icons/button-spinner-blue.svg);
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 12px;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,3 @@ body {
|
|||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
//Custom Mixins
|
||||
|
||||
//Blue gradient background mixin
|
||||
@mixin blue-gradient {
|
||||
background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,3 +43,15 @@ caption {
|
|||
line-height: 1.7;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
|
||||
// Font size
|
||||
.fs-5 {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.fs-6 {
|
||||
font-size: 1rem !important;
|
||||
line-height: 1.4;
|
||||
font-weight: 500;
|
||||
}
|
||||
6
src/styles/mixins/customMixins.scss
Normal file
6
src/styles/mixins/customMixins.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
//Custom Mixins
|
||||
|
||||
//Blue gradient background mixin
|
||||
@mixin blue-gradient {
|
||||
background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%);
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<div class="alert fade show text-center mb-0" role="alert"
|
||||
<div class="alert fade show text-center mb-0 py-2 px-3" role="alert"
|
||||
:class="[ isDismissible ? 'alert-dismissible' : '', this.alertClass ]"
|
||||
>
|
||||
<p class="m-0 fw-bold alert-heading">{{alertHeadline}}</p>
|
||||
<p class="m-0 text-body">{{alertCopy}}</p>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<p class="m-0 fw-bold small alert-heading">{{alertHeadline}}</p>
|
||||
<p class="m-0 text-body small">{{alertCopy}}</p>
|
||||
<button type="button" class="btn-close p-2" data-bs-dismiss="alert" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23.7 23.7" xml:space="preserve">
|
||||
<path d="m23.24 2.7-9.15 9.15L23.24 21a1.581 1.581 0 0 1-1.12 2.7c-.42 0-.82-.16-1.12-.46l-9.15-9.15-9.15 9.15c-.3.3-.7.46-1.12.46A1.581 1.581 0 0 1 .46 21l8.47-8.47.68-.68L.46 2.7c-.62-.62-.62-1.62 0-2.24.62-.62 1.62-.62 2.24 0l8.47 8.47.68.68L21 .46a1.57 1.57 0 0 1 2.23 0c.63.62.63 1.62.01 2.24z"/>
|
||||
</svg>
|
||||
|
|
@ -39,42 +39,58 @@ export default {
|
|||
.btn-close {
|
||||
background: none;
|
||||
opacity: 1;
|
||||
width: .75rem;
|
||||
height: .75rem;
|
||||
}
|
||||
&.alert-dismissible {
|
||||
button {
|
||||
display: flex;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
}
|
||||
&.alert-info {
|
||||
background-color: $blue-100;
|
||||
.alert-heading {
|
||||
color: $blue-700;
|
||||
}
|
||||
svg {
|
||||
fill: $blue-700;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
&.alert-danger {
|
||||
background-color: $red-100;
|
||||
.alert-heading {
|
||||
color: $red-700;
|
||||
color: $red-600;
|
||||
}
|
||||
svg {
|
||||
fill: $red-700;
|
||||
fill: $red-600;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
&.alert-warning {
|
||||
background-color: $yellow-100;
|
||||
.alert-heading {
|
||||
color: $yellow-700;
|
||||
color: $yellow-600;
|
||||
}
|
||||
svg {
|
||||
fill: $yellow-700;
|
||||
fill: $yellow-600;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
&.alert-success {
|
||||
background-color: $green-100;
|
||||
.alert-heading {
|
||||
color: $green-700;
|
||||
}
|
||||
svg {
|
||||
fill: $green-700;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,29 +3,41 @@
|
|||
:disabled="isDisabled"
|
||||
:aria-disabled="isDisabled"
|
||||
class="btn btn-primary d-flex align-items-center"
|
||||
v-on:click="showLoader()"
|
||||
v-bind:class="[this.isLoading ? 'button-loader' : 'not-loading']"
|
||||
>
|
||||
@click='displayComponent'
|
||||
>
|
||||
{{ this.buttonText }}
|
||||
<loader
|
||||
class="ms-2"
|
||||
v-if="display"
|
||||
v-bind:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
v-bind:class="[this.loaderColor, this.loaderPosition]"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "buttonPrimary",
|
||||
props: {
|
||||
buttonText: String,
|
||||
isDisabled: Boolean,
|
||||
loaderColor: String,
|
||||
loaderPosition: String,
|
||||
sizeInRem: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
display: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLoader() {
|
||||
this.isLoading = true;
|
||||
displayComponent() {
|
||||
this.display = true;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
loader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -3,29 +3,41 @@
|
|||
:disabled="isDisabled"
|
||||
:aria-disabled="isDisabled"
|
||||
class="btn btn-secondary d-flex align-items-center"
|
||||
v-on:click="showLoader()"
|
||||
v-bind:class="[this.isLoading ? 'button-loader' : 'not-loading']"
|
||||
>
|
||||
@click='displayComponent'
|
||||
>
|
||||
{{ this.buttonText }}
|
||||
<loader
|
||||
class="ms-2"
|
||||
v-if="display"
|
||||
v-bind:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
v-bind:class="[this.loaderColor, this.loaderPosition]"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "buttonSecondary",
|
||||
name: "buttonPrimary",
|
||||
props: {
|
||||
buttonText: String,
|
||||
isDisabled: Boolean,
|
||||
loaderColor: String,
|
||||
loaderPosition: String,
|
||||
sizeInRem: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isDisabled: false,
|
||||
display: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLoader() {
|
||||
this.isLoading = true;
|
||||
displayComponent() {
|
||||
this.display = true;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
loader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,48 @@
|
|||
<template>
|
||||
<div class="d-flex flex-column w-100">
|
||||
<button
|
||||
class="btn list-button d-flex align-items-center"
|
||||
v-on:click="showLoader()"
|
||||
v-bind:class="[
|
||||
this.isLoading ? 'button-loader' : 'not-loading',
|
||||
this.isError ? 'error' : '',
|
||||
]"
|
||||
class="btn list-button d-flex align-items-center justify-content-between"
|
||||
@click='displayComponent'
|
||||
v-bind:class="[
|
||||
this.isLoading ? 'button-loader' : 'not-loading',
|
||||
this.isError ? 'error' : '',
|
||||
]"
|
||||
>
|
||||
{{ this.buttonText }}
|
||||
</button>
|
||||
<label class="small mt-1">{{ this.errorText }}</label>
|
||||
</div>
|
||||
{{ this.buttonText }}
|
||||
<loader
|
||||
v-if="display"
|
||||
v-bind:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
v-bind:class="[this.loaderColor, this.loaderPosition]"
|
||||
/>
|
||||
</button>
|
||||
<label class="small mt-1">{{ this.errorText }}</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "listButton",
|
||||
props: {
|
||||
buttonText: String,
|
||||
errorText: String,
|
||||
loaderColor: String,
|
||||
loaderPosition: String,
|
||||
sizeInRem: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
display: false,
|
||||
isError: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLoader() {
|
||||
this.isLoading = true;
|
||||
displayComponent() {
|
||||
this.display = true;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
loader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
1
src/ux-components/loader/loader.spec.js
Normal file
1
src/ux-components/loader/loader.spec.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
test.todo("some test to be written in the future");
|
||||
88
src/ux-components/loader/loader.vue
Normal file
88
src/ux-components/loader/loader.vue
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<div class="loader"
|
||||
v-bind:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
v-bind:class="[this.loaderColor, this.loaderPosition]"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "loader",
|
||||
/* Specify size in number value which translates to rem value. For example, 1.5 = 1.5rem */
|
||||
props: {
|
||||
sizeInRem: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
/* Color options: red, green, blue, white, black */
|
||||
loaderColor: {
|
||||
type: String
|
||||
},
|
||||
/* Position options: center, right, left (OPTIONAL) */
|
||||
loaderPosition: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.loader {
|
||||
display: flex;
|
||||
//Open an overlay to prevent page interaction
|
||||
&:before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: transparent;
|
||||
z-index: 9999;
|
||||
cursor: default;
|
||||
}
|
||||
//Spinner basics
|
||||
&:after {
|
||||
content: '';
|
||||
mask: url(../../assets/img/icons/spinner.svg);
|
||||
mask-size: cover;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: rotation 1s infinite linear;
|
||||
@keyframes rotation {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Spinner position
|
||||
&.center {
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
&.right {
|
||||
margin: 0 0 0 auto;
|
||||
}
|
||||
&.left {
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
//Spinner color
|
||||
&:after { //Default spinner color (blue) if no other color is specified from the options below
|
||||
background-color: $blue;
|
||||
}
|
||||
&.red:after {
|
||||
background-color: $red;
|
||||
}
|
||||
&.green:after {
|
||||
background-color: $green;
|
||||
}
|
||||
&.white:after {
|
||||
background-color: $white;
|
||||
}
|
||||
&.black:after {
|
||||
background-color: $black;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,28 +1,51 @@
|
|||
<template>
|
||||
<div class="radiogroup radio-list-button d-flex flex-column w-100">
|
||||
<input type="radio" v-bind:id="radioID" v-bind:name="groupName" v-bind:value="radioID" />
|
||||
<label role="radio" tabindex="0" aria-checked="false" v-bind:for="radioID" class="mb-2 d-flex align-items-center p-2" v-on:click="showLoader()" v-bind:class="[
|
||||
this.isLoading ? 'button-loader' : 'not-loading',
|
||||
this.isError ? 'error' : '',
|
||||
]">{{ radioID }}</label>
|
||||
<p class="small">{{ errorMessage }}</p>
|
||||
<div class="radiogroup radio-list-button d-flex flex-column w-100">
|
||||
<input type="radio"
|
||||
v-bind:id="radioID"
|
||||
v-bind:name="groupName"
|
||||
v-bind:value="radioID">
|
||||
<label role="radio" tabindex="0" aria-checked="false"
|
||||
v-bind:for="radioID"
|
||||
class="mb-2 d-flex align-items-center justify-content-between p-2"
|
||||
@click='displayComponent'
|
||||
>{{radioID}}
|
||||
<loader
|
||||
v-if="display"
|
||||
v-bind:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
v-bind:class="[this.loaderColor, this.loaderPosition]"
|
||||
/>
|
||||
</label>
|
||||
<p class="small">{{errorMessage}}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "radioList",
|
||||
props: ["groupName", "ariaLabelBy", "radioID", "errorMessage"],
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLoader() {
|
||||
this.isLoading = true;
|
||||
},
|
||||
name: "radioList",
|
||||
props: [
|
||||
"groupName",
|
||||
"ariaLabelBy",
|
||||
"radioID",
|
||||
"errorMessage",
|
||||
"loaderColor",
|
||||
"loaderPosition",
|
||||
"sizeInRem"
|
||||
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
isError: false,
|
||||
display: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
displayComponent() {
|
||||
this.display = true;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
loader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -2,22 +2,46 @@ import { shallowMount } from "@vue/test-utils";
|
|||
import radio from "./radio";
|
||||
|
||||
describe("radio.vue", () => {
|
||||
it("Should render the 'text' prop value as a span value for the radio button label and add the 'value' prop value as the radio button value and id.", () => {
|
||||
it("Should render the 'radioID' prop value as the label and id value as well as the radio button value, groupName as the name value, and fire a click even that sets the display data attribute to true.", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(radio, {
|
||||
propsData: {
|
||||
value: "2023",
|
||||
text: "12",
|
||||
radioID: "2023",
|
||||
groupName: "TestGroup",
|
||||
loaderColor: "blue",
|
||||
loaderPosition: "right",
|
||||
sizeInRem: "1.5",
|
||||
errorMessage: 'null'
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(wrapper.find("span").text()).toEqual("12");
|
||||
expect(wrapper.find("input").attributes()).toEqual({
|
||||
class: "position-absolute opacity-0",
|
||||
const input = wrapper.find("input");
|
||||
const label = wrapper.find("label");
|
||||
const paragraph = wrapper.find("p");
|
||||
|
||||
await label.trigger('click');
|
||||
|
||||
expect(input.attributes()).toEqual({
|
||||
id: "2023",
|
||||
type: "radio",
|
||||
value: "2023",
|
||||
name: "TestGroup",
|
||||
});
|
||||
|
||||
expect(label.attributes()).toEqual({
|
||||
role: "radio",
|
||||
tabindex: "0",
|
||||
for: "2023",
|
||||
class: "d-flex align-items-center justify-content-between p-2",
|
||||
"aria-checked": "false"
|
||||
});
|
||||
|
||||
expect(label.text()).toEqual('2023');
|
||||
|
||||
expect(paragraph.text()).toEqual('null');
|
||||
|
||||
expect(wrapper.vm.display).toBe(true);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,35 +1,49 @@
|
|||
<template>
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
:id="this.value"
|
||||
:value="this.value"
|
||||
class="position-absolute opacity-0"
|
||||
v-on:click="showLoader()"
|
||||
<div class="radiogroup radio-list-button d-flex flex-column w-100">
|
||||
<input type="radio"
|
||||
:id="radioID"
|
||||
:name="groupName"
|
||||
:value="radioID">
|
||||
<label role="radio" tabindex="0" aria-checked="false"
|
||||
:for="radioID"
|
||||
class="d-flex align-items-center justify-content-between p-2"
|
||||
@click='displayComponent'
|
||||
>{{radioID}}
|
||||
<loader
|
||||
v-if="display"
|
||||
:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||
:class="[this.loaderColor, this.loaderPosition]"
|
||||
/>
|
||||
<label
|
||||
:for="this.value"
|
||||
class="btn list-button d-flex align-items-center"
|
||||
v-bind:class="[this.isLoading ? 'button-loader' : '']"
|
||||
>
|
||||
<span>{{ text }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</label>
|
||||
<p class="small">{{errorMessage}}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import loader from "@/ux-components/loader/loader";
|
||||
export default {
|
||||
name: "radio",
|
||||
props: ["value", "text"],
|
||||
name: "radioList",
|
||||
props: [
|
||||
"groupName",
|
||||
"radioID",
|
||||
"errorMessage",
|
||||
"loaderColor",
|
||||
"loaderPosition",
|
||||
"sizeInRem"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
display: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showLoader() {
|
||||
this.isLoading = true;
|
||||
displayComponent() {
|
||||
this.display = true;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
loader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ module.exports = {
|
|||
@import "@/styles/ux-variables.scss";
|
||||
@import "./node_modules/bootstrap/scss/variables";
|
||||
@import "./node_modules/bootstrap/scss/mixins";
|
||||
@import "@/styles/mixins/customMixins";
|
||||
@import "./node_modules/bootstrap/scss/bootstrap";
|
||||
@import "@/styles/common-styles.scss";
|
||||
@import "@/styles/common-button-styles.scss";
|
||||
@import "@/styles/common-radio-styles.scss";
|
||||
@import "@/styles/common-typography-styles.scss";
|
||||
@import "@/styles/common-component-styles/ymms-common-styles.scss";
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ module.exports = {
|
|||
@import "@/styles/ux-variables.scss";
|
||||
@import "./node_modules/bootstrap/scss/variables";
|
||||
@import "./node_modules/bootstrap/scss/mixins";
|
||||
@import "@/styles/mixins/customMixins";
|
||||
@import "./node_modules/bootstrap/scss/bootstrap";
|
||||
@import "@/styles/common-styles.scss";
|
||||
@import "@/styles/common-button-styles.scss";
|
||||
@import "@/styles/common-radio-styles.scss";
|
||||
@import "@/styles/common-typography-styles.scss";
|
||||
@import "@/styles/common-component-styles/ymms-common-styles.scss";
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue