Commit db05741a authored by Diana Zubova's avatar Diana Zubova Committed by Brandon Labuschagne

Improve alerts for addons purchase

parent 9622e8d7
...@@ -7,7 +7,11 @@ import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; ...@@ -7,7 +7,11 @@ import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants'; import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import createFlash from '~/flash'; import createFlash from '~/flash';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { I18N_DETAILS_STEP_TITLE, I18N_DETAILS_NEXT_STEP_BUTTON_TEXT } from '../../constants'; import {
I18N_DETAILS_STEP_TITLE,
I18N_DETAILS_NEXT_STEP_BUTTON_TEXT,
I18N_DETAILS_INVALID_QUANTITY_MESSAGE,
} from '../../constants';
export default { export default {
name: 'AddonPurchaseDetails', name: 'AddonPurchaseDetails',
...@@ -49,7 +53,7 @@ export default { ...@@ -49,7 +53,7 @@ export default {
computed: { computed: {
quantityModel: { quantityModel: {
get() { get() {
return this.quantity || 1; return this.quantity || 0;
}, },
set(quantity) { set(quantity) {
this.updateQuantity(quantity); this.updateQuantity(quantity);
...@@ -63,7 +67,7 @@ export default { ...@@ -63,7 +67,7 @@ export default {
}, },
}, },
methods: { methods: {
updateQuantity(quantity = 1) { updateQuantity(quantity = 0) {
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: updateState, mutation: updateState,
...@@ -79,6 +83,7 @@ export default { ...@@ -79,6 +83,7 @@ export default {
i18n: { i18n: {
stepTitle: I18N_DETAILS_STEP_TITLE, stepTitle: I18N_DETAILS_STEP_TITLE,
nextStepButtonText: I18N_DETAILS_NEXT_STEP_BUTTON_TEXT, nextStepButtonText: I18N_DETAILS_NEXT_STEP_BUTTON_TEXT,
invalidQuantityErrorMessage: I18N_DETAILS_INVALID_QUANTITY_MESSAGE,
}, },
stepId: STEPS[0].id, stepId: STEPS[0].id,
}; };
...@@ -89,6 +94,7 @@ export default { ...@@ -89,6 +94,7 @@ export default {
:step-id="$options.stepId" :step-id="$options.stepId"
:title="$options.i18n.stepTitle" :title="$options.i18n.stepTitle"
:is-valid="isValid" :is-valid="isValid"
:error-message="$options.i18n.invalidQuantityErrorMessage"
:next-step-button-text="$options.i18n.nextStepButtonText" :next-step-button-text="$options.i18n.nextStepButtonText"
> >
<template #body> <template #body>
...@@ -98,7 +104,12 @@ export default { ...@@ -98,7 +104,12 @@ export default {
<label class="gl-mt-3" for="quantity" data-testid="product-label"> <label class="gl-mt-3" for="quantity" data-testid="product-label">
{{ productLabel }} {{ productLabel }}
</label> </label>
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center gl-mb-6"> <div
:class="[
{ 'gl-mb-6': isValid },
'gl-display-flex gl-flex-direction-row gl-align-items-center',
]"
>
<gl-form-input <gl-form-input
ref="quantity" ref="quantity"
v-model.number="quantityModel" v-model.number="quantityModel"
......
...@@ -65,6 +65,9 @@ export default { ...@@ -65,6 +65,9 @@ export default {
quantityPresent() { quantityPresent() {
return this.subscription.quantity > 0; return this.subscription.quantity > 0;
}, },
quantity() {
return this.subscription.quantity || 0;
},
namespaceName() { namespaceName() {
return this.selectedNamespace.name; return this.selectedNamespace.name;
}, },
...@@ -104,7 +107,7 @@ export default { ...@@ -104,7 +107,7 @@ export default {
:selected-plan-text="plan.name" :selected-plan-text="plan.name"
:selected-plan-price="selectedPlanPrice" :selected-plan-price="selectedPlanPrice"
:total-amount="totalAmount" :total-amount="totalAmount"
:quantity="subscription.quantity" :quantity="quantity"
:tax-rate="$options.taxRate" :tax-rate="$options.taxRate"
:purchase-has-expiration="purchaseHasExpiration" :purchase-has-expiration="purchaseHasExpiration"
> >
...@@ -128,7 +131,7 @@ export default { ...@@ -128,7 +131,7 @@ export default {
:selected-plan-text="plan.name" :selected-plan-text="plan.name"
:selected-plan-price="selectedPlanPrice" :selected-plan-price="selectedPlanPrice"
:total-amount="totalAmount" :total-amount="totalAmount"
:quantity="subscription.quantity" :quantity="quantity"
:tax-rate="$options.taxRate" :tax-rate="$options.taxRate"
:purchase-has-expiration="purchaseHasExpiration" :purchase-has-expiration="purchaseHasExpiration"
> >
......
...@@ -42,6 +42,7 @@ export const I18N_STORAGE_TOOLTIP_NOTE = s__( ...@@ -42,6 +42,7 @@ export const I18N_STORAGE_TOOLTIP_NOTE = s__(
export const I18N_DETAILS_STEP_TITLE = s__('Checkout|Purchase details'); export const I18N_DETAILS_STEP_TITLE = s__('Checkout|Purchase details');
export const I18N_DETAILS_NEXT_STEP_BUTTON_TEXT = s__('Checkout|Continue to billing'); export const I18N_DETAILS_NEXT_STEP_BUTTON_TEXT = s__('Checkout|Continue to billing');
export const I18N_DETAILS_INVALID_QUANTITY_MESSAGE = s__('Checkout|Enter a number greater than 0');
export const I18N_DETAILS_FORMULA = s__('Checkout|x %{quantity} %{units} per pack ='); export const I18N_DETAILS_FORMULA = s__('Checkout|x %{quantity} %{units} per pack =');
export const I18N_DETAILS_FORMULA_WITH_ALERT = s__('Checkout|x %{quantity} %{units} per pack'); export const I18N_DETAILS_FORMULA_WITH_ALERT = s__('Checkout|x %{quantity} %{units} per pack');
......
...@@ -35,6 +35,11 @@ export default { ...@@ -35,6 +35,11 @@ export default {
required: false, required: false,
default: '', default: '',
}, },
errorMessage: {
type: String,
required: false,
default: '',
},
}, },
data() { data() {
return { return {
...@@ -113,11 +118,15 @@ export default { ...@@ -113,11 +118,15 @@ export default {
<div :class="['card', snakeCasedStep]"> <div :class="['card', snakeCasedStep]">
<div v-show="isActive" @keyup.enter="nextStep"> <div v-show="isActive" @keyup.enter="nextStep">
<slot name="body" :active="isActive"></slot> <slot name="body" :active="isActive"></slot>
<gl-form-group v-if="nextStepButtonText" class="gl-mt-3 gl-mb-0"> <gl-form-group
<gl-button variant="success" category="primary" :disabled="!isValid" @click="nextStep"> v-if="nextStepButtonText"
{{ nextStepButtonText }} :invalid-feedback="errorMessage"
</gl-button> :state="isValid"
</gl-form-group> :class="[!isValid && errorMessage ? 'gl-mb-5' : 'gl-mb-0', 'gl-mt-3']"
/>
<gl-button variant="success" category="primary" :disabled="!isValid" @click="nextStep">
{{ nextStepButtonText }}
</gl-button>
</div> </div>
<step-summary v-if="isFinished" :is-editable="isEditable" :edit="edit"> <step-summary v-if="isFinished" :is-editable="isEditable" :edit="edit">
<slot name="summary"></slot> <slot name="summary"></slot>
......
import { GlButton } from '@gitlab/ui'; import { GlButton, GlFormGroup } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
...@@ -114,6 +114,16 @@ describe('Step', () => { ...@@ -114,6 +114,16 @@ describe('Step', () => {
expect(wrapper.findComponent(StepSummary).exists()).toBe(false); expect(wrapper.findComponent(StepSummary).exists()).toBe(false);
}); });
it('should pass correct props to form component', () => {
wrapper = createComponent({
propsData: { errorMessage: 'Input value is invalid!' },
});
expect(wrapper.findComponent(GlFormGroup).attributes('invalid-feedback')).toBe(
'Input value is invalid!',
);
});
}); });
describe('isEditable', () => { describe('isEditable', () => {
......
...@@ -6682,6 +6682,9 @@ msgstr "" ...@@ -6682,6 +6682,9 @@ msgstr ""
msgid "Checkout|Edit" msgid "Checkout|Edit"
msgstr "" msgstr ""
msgid "Checkout|Enter a number greater than 0"
msgstr ""
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}" msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment