Merge branch 'feature/CSR-6' into feature/CSR-121_button-click-function
This commit is contained in:
commit
09396149c5
15 changed files with 223 additions and 212 deletions
|
|
@ -2,6 +2,7 @@ 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 = {
|
||||
|
|
@ -44,7 +45,7 @@ describe('vehicleBanner', () => {
|
|||
]
|
||||
};
|
||||
|
||||
test('renders the blurrycar image when vehicleImageSrc is not present', async () => {
|
||||
test('renders the blurrycar image when vehicleImageSrc is not present', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
|
|
@ -60,7 +61,7 @@ describe('vehicleBanner', () => {
|
|||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('does not render the blurrycar image when vehicleImageSrc exists', async () => {
|
||||
test('does not render the blurrycar image when vehicleImageSrc exists', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
mountOptions.global.mocks = {
|
||||
|
|
@ -77,9 +78,7 @@ describe('vehicleBanner', () => {
|
|||
}
|
||||
});
|
||||
// Assert
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
}, 500);
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
|
|
@ -98,13 +97,12 @@ describe('vehicleBanner', () => {
|
|||
}
|
||||
});
|
||||
// Assert
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
}, 500);
|
||||
await nextTick();
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('does not render the blurrycar image when a YMMS object is found', async () => {
|
||||
test('receives a carId when a YMMS object is found', async () => {
|
||||
// Arrange
|
||||
$store.state.order.vehicle.year = "2019"
|
||||
$store.state.order.vehicle.make = "acura"
|
||||
|
|
@ -120,14 +118,12 @@ describe('vehicleBanner', () => {
|
|||
...mountOptions
|
||||
});
|
||||
// Assert
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
}, 500);
|
||||
await nextTick();
|
||||
expect(wrapper.vm.$data.carId.length).toBeGreaterThan(0);
|
||||
wrapper.unmount();
|
||||
|
||||
});
|
||||
|
||||
test('does not render the blurrycar image when a VIN is found', async () => {
|
||||
test('receives a carId when a VIN is found', async () => {
|
||||
// Arrange
|
||||
$store.state.order.vehicle.vin = "1J4GW58S4XC541166";
|
||||
const mountOptions = getMountOptions(actionList);
|
||||
|
|
@ -140,9 +136,9 @@ describe('vehicleBanner', () => {
|
|||
...mountOptions
|
||||
});
|
||||
// Assert
|
||||
setTimeout(() => {
|
||||
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
|
||||
}, 500);
|
||||
await nextTick();
|
||||
expect(wrapper.vm.$data.carId.length).toBeGreaterThan(0);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="vehicle_banner mb-3">
|
||||
<div class="vehicle_banner mb-3 text-center">
|
||||
<img
|
||||
class="vehicle-image img-fluid"
|
||||
:src="vehicleImageSrc"
|
||||
|
|
@ -53,14 +53,14 @@ export default {
|
|||
methods: {
|
||||
getCarIdWithYmms(ymms) { // retrieve carId with YMMS object
|
||||
this.dispatchNonBlockingStoreAction(this.storeActions.LOOKUP_VEHICLE_BY_YMMS, ymms).then((response) => {
|
||||
const carId = response.data[0].CarId;
|
||||
this.getVehicleImage(carId)
|
||||
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) => {
|
||||
const carId = response.data[0].CarId;
|
||||
this.getVehicleImage(carId)
|
||||
this.carId = response.data[0].CarId;
|
||||
this.getVehicleImage(this.carId)
|
||||
});
|
||||
},
|
||||
getVehicleImage(carId) { // look up evox with carId
|
||||
|
|
|
|||
30
src/helpers/cms-content-helper.js
Normal file
30
src/helpers/cms-content-helper.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { storeActions } from "@/constants/store-actions.js";
|
||||
import { widgetNames } from "@/constants/widget-names.js";
|
||||
import store from "@/store";
|
||||
|
||||
export function fetchCmsContentForPage(fmgPage) {
|
||||
return store.dispatch(storeActions.GET_PAGE_DATA, { pageName: fmgPage }).then((response) => {
|
||||
|
||||
const pageDataFromCms = {
|
||||
isCmsContentReady: false
|
||||
};
|
||||
|
||||
response.data.Result.forEach((widget) => {
|
||||
if (Object.values(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
|
||||
pageDataFromCms.isCmsContentReady = true;
|
||||
|
||||
return pageDataFromCms;
|
||||
});
|
||||
}
|
||||
|
||||
29
src/helpers/layout-helper.js
Normal file
29
src/helpers/layout-helper.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export function settleAllPromises(layoutPromiseTable) {
|
||||
|
||||
// Pull our keys out of the promise 'table'
|
||||
const promiseNames = Object.entries(layoutPromiseTable);
|
||||
|
||||
return Promise.allSettled(promiseNames.map(e => e[1]).map(n => n.promise))
|
||||
.then(results => {
|
||||
|
||||
const resultMap = {};
|
||||
|
||||
// Build a map of the results
|
||||
for (let i = 0; i < results.length; ++i) {
|
||||
|
||||
const promiseName = promiseNames[i][1].key;
|
||||
|
||||
// Some Promises like the cms content call don't have a 'data' field
|
||||
// when returned, so other promises do. Map the results to the object
|
||||
// so that the object is the return data.
|
||||
|
||||
if (results[i].value.data === undefined) {
|
||||
resultMap[promiseName] = results[i].value
|
||||
} else {
|
||||
resultMap[promiseName] = results[i].value.data;
|
||||
}
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
});
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { storeActions } from "@/constants/store-actions";
|
||||
import store from "@/store";
|
||||
|
||||
export function getMountOptions(mockData, cmsMockData = null) {
|
||||
export function getMountOptions(mockData) {
|
||||
// Define our mocks to attached to the 'global' object for Vue/Jest.
|
||||
const mocks = {};
|
||||
|
||||
|
|
@ -18,16 +18,9 @@ export function getMountOptions(mockData, cmsMockData = null) {
|
|||
}
|
||||
});
|
||||
|
||||
if(cmsMockData){
|
||||
mocks.GetContentFromCms = jest.fn();
|
||||
mocks.GetContentFromCms.mockImplementation(() =>
|
||||
{
|
||||
return cmsMockData;
|
||||
});
|
||||
}
|
||||
|
||||
// Mock store actions from js file
|
||||
mocks.storeActions = storeActions;
|
||||
|
||||
const global = {
|
||||
mocks: mocks,
|
||||
plugins: [store]
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary
|
||||
buttonText="Primary"
|
||||
loaderColor="white"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -44,6 +47,9 @@
|
|||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonSecondary
|
||||
buttonText="Secondary"
|
||||
loaderColor="white"
|
||||
loaderPosition="right"
|
||||
sizeInRem="1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -227,7 +233,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col">
|
||||
<vehicleBanner
|
||||
passedCarId=""
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,56 @@
|
|||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
// Mock our module for promises.
|
||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||
settleAllPromises: jest.fn()
|
||||
}));
|
||||
|
||||
describe("vehicle-year.vue", () => {
|
||||
test("vehicle-year.vue should render data from CMS", async () => {
|
||||
|
||||
// Arrange
|
||||
const cmsMockData = {
|
||||
PageHeaderWidget: [{ HeaderText: "Select a year to get started" }],
|
||||
RadioQuestionWidget: [{ QuestionText: "What year is your vehicle?" }],
|
||||
|
||||
// Our mock data for our call to settleAllPromises
|
||||
const mockData = {
|
||||
getPageContent: {
|
||||
PageHeaderWidget: [{ HeaderText: "Select a year to get started" }],
|
||||
RadioQuestionWidget: [{ QuestionText: "What year is your vehicle?" }],
|
||||
isCmsContentReady: true,
|
||||
},
|
||||
getVehicleYear: [2023, 2022, 2021]
|
||||
}
|
||||
|
||||
const mountOptions = getMountOptions({}, cmsMockData);
|
||||
// our router information needed.
|
||||
const to = {
|
||||
query: {
|
||||
fmgPage: 'vehicle-year'
|
||||
}
|
||||
};
|
||||
|
||||
const mountOptions = getMountOptions(mockData);
|
||||
|
||||
// our mock implementation of settleAllPromises
|
||||
settleAllPromises.mockImplementation(() => { return Promise.resolve(mockData);});
|
||||
|
||||
// Act
|
||||
const wrapper = shallowMount(vehicleYear, mountOptions);
|
||||
await flushPromises();
|
||||
|
||||
// Call our beforeRouteEnter on the component.
|
||||
// This passes (c) => c(wrapper.vm) so that next can be called and our
|
||||
// data can be set.
|
||||
vehicleYear.beforeRouteEnter.call(wrapper.vm, to, undefined, (c) => c(wrapper.vm));
|
||||
|
||||
await nextTick(); // Wait for the DOM to update.
|
||||
|
||||
// Assert
|
||||
const header = await wrapper.find(".Header");
|
||||
expect(header.attributes("text")).toEqual("Select a year to get started");
|
||||
|
||||
const yearQuestion = await wrapper.findComponent({name: 'year-question'});
|
||||
const yearQuestion = wrapper.findComponent({ name: 'year-question' });
|
||||
expect(yearQuestion.attributes("questiontext")).toEqual("What year is your vehicle?");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,37 +1,62 @@
|
|||
<template v-if="isCmsContentReady">
|
||||
<div class="select-car">
|
||||
<template>
|
||||
<div class="select-car">
|
||||
<div class="select-car-form rounded text-center">
|
||||
<vehicleBanner />
|
||||
<pageHeader :text="pageHeaderWidgets.HeaderText" class="Header" />
|
||||
<yearQuestion :questionText="radioQuestionWidgets.QuestionText" />
|
||||
<pageHeader :text="pageHeaderWidgets.HeaderText" class="Header" />
|
||||
<yearQuestion :questionText="radioQuestionWidgets.QuestionText" :years="vehicleYears" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
||||
import pageHeader from "@/ux-components/header/header";
|
||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import store from "@/store";
|
||||
import { storeActions } from "@/constants/store-actions.js";
|
||||
|
||||
export default {
|
||||
name: "vehicle-year",
|
||||
data() {
|
||||
return {
|
||||
pageHeaderWidgets: {},
|
||||
radioQuestionWidgets: {},
|
||||
};
|
||||
},
|
||||
async created() {
|
||||
const pageContent = await this.GetContentFromCms();
|
||||
name: "vehicle-year",
|
||||
data() {
|
||||
return {
|
||||
pageHeaderWidgets: {},
|
||||
radioQuestionWidgets: {},
|
||||
vehicleYears: [],
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
beforeRouteEnter(to, from, next) {
|
||||
|
||||
this.pageHeaderWidgets = pageContent.PageHeaderWidget[0];
|
||||
this.radioQuestionWidgets = pageContent.RadioQuestionWidget[0];
|
||||
},
|
||||
components: {
|
||||
yearQuestion,
|
||||
pageHeader,
|
||||
vehicleBanner,
|
||||
},
|
||||
const contentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
const getVehicleYearPromise = store.dispatch(storeActions.GET_VEHICLE_YEARS, {});
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: "getPageContent",
|
||||
promise: contentPromise,
|
||||
},
|
||||
{
|
||||
resultKey: "getVehicleYear",
|
||||
promise: getVehicleYearPromise,
|
||||
},
|
||||
];
|
||||
|
||||
settleAllPromises(promiseResultMap).then((resultMap) => {
|
||||
|
||||
// Call our next function to transition to the next page.
|
||||
next((vm) => {
|
||||
vm.pageHeaderWidgets = resultMap.getPageContent.PageHeaderWidget[0];
|
||||
vm.radioQuestionWidgets = resultMap.getPageContent.RadioQuestionWidget[0];
|
||||
vm.vehicleYears = resultMap.getVehicleYear;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
components: {
|
||||
yearQuestion,
|
||||
pageHeader,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,16 +13,9 @@ export default {
|
|||
name: "year-question",
|
||||
props: {
|
||||
questionText: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
years: [],
|
||||
};
|
||||
years: Array
|
||||
},
|
||||
created() {
|
||||
this.dispatchNonBlockingStoreAction(this.storeActions.GET_VEHICLE_YEARS, {}).then((response) => {
|
||||
this.years = response.data;
|
||||
});
|
||||
},
|
||||
components: {
|
||||
radioQuestion,
|
||||
|
|
|
|||
|
|
@ -24,12 +24,11 @@ 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
|
||||
|
|
@ -39,10 +38,10 @@ export default {
|
|||
}
|
||||
|
||||
pageDataFromCms[widget.Type] = [widget.Model];
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Our 'Page' is ready because we have data now
|
||||
this.isCmsContentReady = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,60 +23,6 @@ describe("baseMixin.js", () => {
|
|||
|
||||
expect(mixIn.methods.$store.dispatch).toBeCalledWith(type, payload);
|
||||
});
|
||||
|
||||
test('GetContentFromCms: Should return mapped data and call dispatchNonblockingStoreAction', async () => {
|
||||
const mixIn = getMixInInstance({});
|
||||
|
||||
// Mock dispatch action
|
||||
mixIn.methods.dispatchNonBlockingStoreAction = jest.fn();
|
||||
mixIn.methods.dispatchNonBlockingStoreAction.mockImplementation((action) => {
|
||||
if (action === 'getPageData') {
|
||||
return Promise.resolve({
|
||||
data: {
|
||||
Result: [
|
||||
{
|
||||
Type: "PageConfigWidget",
|
||||
Model: {
|
||||
LayoutNames: [
|
||||
"None",
|
||||
"vehicle-year"
|
||||
],
|
||||
LayoutStyle: "vehicle-year"
|
||||
}
|
||||
},
|
||||
{
|
||||
Type: "RadioQuestionWidget",
|
||||
Model: {
|
||||
"QuestionText": "What year is your vehicle?"
|
||||
}
|
||||
},
|
||||
{
|
||||
Type: "RadioQuestionWidget",
|
||||
Model: {
|
||||
"QuestionText": "This is a second radio question"
|
||||
}
|
||||
},
|
||||
{
|
||||
Type: "PageHeaderWidget",
|
||||
Model: {
|
||||
"HeaderText": "Select a year to get started"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const result = await mixIn.methods.GetContentFromCms();
|
||||
await flushPromises();
|
||||
|
||||
|
||||
expect(mixIn.methods.dispatchNonBlockingStoreAction).toBeCalledWith(storeActions.GET_PAGE_DATA, { pageName: 'test-page'});
|
||||
|
||||
expect(result.PageHeaderWidget[0].HeaderText).toEqual('Select a year to get started');
|
||||
|
||||
});
|
||||
})
|
||||
function getMixInInstance({ isDispatchSuccess = true }) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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,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 small alert-heading">{{alertHeadline}}</p>
|
||||
<p class="m-0 text-body small">{{alertCopy}}</p>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<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,10 +39,14 @@ export default {
|
|||
.btn-close {
|
||||
background: none;
|
||||
opacity: 1;
|
||||
width: .75rem;
|
||||
height: .75rem;
|
||||
}
|
||||
&.alert-dismissible {
|
||||
button {
|
||||
display: flex;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
}
|
||||
&.alert-info {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue