Commit eb0990a2 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Fix loading subscription details

Introducing multiple GraphQL clients
introduced some errors in loading
Subscription details.
This commit fixes that and simplifies this process
a bit.
parent 8280b77a
...@@ -8,9 +8,12 @@ import { NEW_GROUP } from 'ee/subscriptions/new/constants'; ...@@ -8,9 +8,12 @@ import { NEW_GROUP } from 'ee/subscriptions/new/constants';
import Step from 'ee/vue_shared/purchase_flow/components/step.vue'; import Step from 'ee/vue_shared/purchase_flow/components/step.vue';
import { sprintf, s__, __ } from '~/locale'; import { sprintf, s__, __ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { getParameterValues } from '~/lib/utils/url_utility';
import { GENERAL_ERROR_MESSAGE } from 'ee/vue_shared/purchase_flow/constants';
import createFlash from '~/flash';
export default { export default {
components: { components: {
GlFormGroup, GlFormGroup,
GlFormSelect, GlFormSelect,
GlFormInput, GlFormInput,
...@@ -34,45 +37,37 @@ export default { ...@@ -34,45 +37,37 @@ export default {
customer: {}, customer: {},
isSetupForCompany: null, isSetupForCompany: null,
isNewUser: null, isNewUser: null,
selectedPlanId: null,
}; };
}, },
apollo: { apollo: {
state: { state: {
query: STATE_QUERY, query: STATE_QUERY,
update(data) { manual: true,
const { result({ data, loading }) {
subscription = {}, if (loading) {
namespaces = [], return;
customer = {}, }
isSetupForCompany = null,
isNewUser = null,
} = data;
return {
subscription,
namespaces,
customer,
isSetupForCompany,
isNewUser,
};
},
result({ data }) {
const { subscription, namespaces, customer, isSetupForCompany, isNewUser } = data || {};
this.subscription = subscription; this.subscription = data.subscription;
this.namespaces = namespaces; this.namespaces = data.namespaces;
this.customer = customer; this.customer = data.customer;
this.isSetupForCompany = isSetupForCompany; this.isSetupForCompany = data.isSetupForCompany;
this.isNewUser = isNewUser; this.isNewUser = data.isNewUser;
this.selectedPlanId = data.selectedPlanId;
}, },
}, },
}, },
mounted() {
this.preselectPlan();
},
computed: { computed: {
selectedPlanModel: { selectedPlanModel: {
get() { get() {
return this.subscription.planId || this.plans[0].code; return this.selectedPlanId || this.plans[0].id;
}, },
set(planId) { set(planId) {
this.updateSubscription({ subscription: { planId } }); this.updateState({ subscription: { planId } });
}, },
}, },
selectedGroupModel: { selectedGroupModel: {
...@@ -83,7 +78,7 @@ export default { ...@@ -83,7 +78,7 @@ export default {
const quantity = const quantity =
this.namespaces.find((namespace) => namespace.id === namespaceId)?.users || 1; this.namespaces.find((namespace) => namespace.id === namespaceId)?.users || 1;
this.updateSubscription({ subscription: { namespaceId, quantity } }); this.updateState({ subscription: { namespaceId, quantity } });
}, },
}, },
numberOfUsersModel: { numberOfUsersModel: {
...@@ -91,7 +86,7 @@ export default { ...@@ -91,7 +86,7 @@ export default {
return this.selectedGroupUsers || 1; return this.selectedGroupUsers || 1;
}, },
set(number) { set(number) {
this.updateSubscription({ subscription: { quantity: number } }); this.updateState({ subscription: { quantity: number } });
}, },
}, },
companyModel: { companyModel: {
...@@ -99,11 +94,11 @@ export default { ...@@ -99,11 +94,11 @@ export default {
return this.customer.company; return this.customer.company;
}, },
set(company) { set(company) {
this.updateSubscription({ customer: { company } }); this.updateState({ customer: { company } });
}, },
}, },
selectedPlan() { selectedPlan() {
const selectedPlan = this.plans.find((plan) => plan.code === this.subscription.planId); const selectedPlan = this.plans.find((plan) => plan.id === this.selectedPlanId);
if (!selectedPlan) { if (!selectedPlan) {
return this.plans[0]; return this.plans[0];
} }
...@@ -111,13 +106,13 @@ export default { ...@@ -111,13 +106,13 @@ export default {
return selectedPlan; return selectedPlan;
}, },
selectedPlanTextLine() { selectedPlanTextLine() {
return sprintf(this.$options.i18n.selectedPlan, { selectedPlanText: this.selectedPlan.code }); return sprintf(this.$options.i18n.selectedPlan, { selectedPlanText: this.selectedPlan.id });
},
selectedGroup() {
return this.namespaces.find((namespace) => namespace.id === this.subscription.namespaceId);
}, },
selectedGroupUsers() { selectedGroupUsers() {
return ( return this.selectedGroup?.users || 1;
this.namespaces.find((namespace) => namespace.id === this.subscription.namespaceId)
?.users || 1
);
}, },
isGroupSelected() { isGroupSelected() {
return this.subscription.namespaceId !== null; return this.subscription.namespaceId !== null;
...@@ -129,14 +124,10 @@ export default { ...@@ -129,14 +124,10 @@ export default {
}, },
isValid() { isValid() {
if (this.isSetupForCompany) { if (this.isSetupForCompany) {
return ( return this.isNumberOfUsersValid && !isEmpty(this.selectedPlanId) && (!isEmpty(this.customer.company) || this.isGroupSelected);
!isEmpty(this.subscription.planId) &&
(!isEmpty(this.customer.company) || this.isNewGroupSelected) &&
this.isNumberOfUsersValid
);
} }
return !isEmpty(this.subscription.planId) && this.subscription.quantity === 1; return (this.subscription.quantity === 1) && !isEmpty(this.selectedPlanId);
}, },
isShowingGroupSelector() { isShowingGroupSelector() {
return !this.isNewUser && this.namespaces.length; return !this.isNewUser && this.namespaces.length;
...@@ -167,37 +158,54 @@ export default { ...@@ -167,37 +158,54 @@ export default {
}, },
}, },
methods: { methods: {
updateSubscription(payload = {}) { updateState(payload = {}) {
this.$apollo.mutate({ this.$apollo.mutate({
mutation: UPDATE_STATE, mutation: UPDATE_STATE,
variables: { variables: {
input: payload, input: payload,
}, },
}).catch((error) => {
createFlash({ message: GENERAL_ERROR_MESSAGE, error, captureError: true });
}); });
}, },
toggleIsSetupForCompany() { toggleIsSetupForCompany() {
this.updateSubscription({ isSetupForCompany: !this.isSetupForCompany }); this.updateSubscription({ isSetupForCompany: !this.isSetupForCompany });
}, },
preselectPlan() {
if (this.selectedPlanId) {
return;
}
let plan = this.plans[0];
const planIdFromSearchParams = getParameterValues('planId');
if (planIdFromSearchParams.length > 0) {
plan = this.plans.find((plan) => plan.id === planIdFromSearchParams[0].id) || plan;
}
this.updateState({ selectedPlanId: plan.id });
},
}, },
i18n: { i18n: {
stepTitle: s__('Checkout|Subscription details'), stepTitle: s__('Checkout|Subscription details'),
nextStepButtonText: s__('Checkout|Continue to billing'), nextStepButtonText: s__('Checkout|Continue to billing'),
selectedPlanLabel: s__('Checkout|GitLab plan'), selectedPlanLabel: s__('Checkout|GitLab plan'),
selectedGroupLabel: s__('Checkout|GitLab group'), selectedGroupLabel: s__('Checkout|GitLab group'),
groupSelectPrompt: __('Select'), groupSelectPrompt: __('Select'),
groupSelectCreateNewOption: s__('Checkout|Create a new group'), groupSelectCreateNewOption: s__('Checkout|Create a new group'),
selectedGroupDescription: s__('Checkout|Your subscription will be applied to this group'), selectedGroupDescription: s__('Checkout|Your subscription will be applied to this group'),
createNewGroupDescription: s__("Checkout|You'll create your new group after checkout"), createNewGroupDescription: s__("Checkout|You'll create your new group after checkout"),
organizationNameLabel: s__('Checkout|Name of company or organization using GitLab'), organizationNameLabel: s__('Checkout|Name of company or organization using GitLab'),
numberOfUsersLabel: s__('Checkout|Number of users'), numberOfUsersLabel: s__('Checkout|Number of users'),
needMoreUsersLink: s__('Checkout|Need more users? Purchase GitLab for your %{company}.'), needMoreUsersLink: s__('Checkout|Need more users? Purchase GitLab for your %{company}.'),
companyOrTeam: s__('Checkout|company or team'), companyOrTeam: s__('Checkout|company or team'),
selectedPlan: s__('Checkout|%{selectedPlanText} plan'), selectedPlan: s__('Checkout|%{selectedPlanText} plan'),
group: __('Group'), group: __('Group'),
users: __('Users'), users: __('Users'),
}, },
stepId: STEPS[0].id, stepId: STEPS[0].id,
}; };
</script> </script>
<template> <template>
<step <step
...@@ -213,7 +221,7 @@ export default { ...@@ -213,7 +221,7 @@ export default {
v-model="selectedPlanModel" v-model="selectedPlanModel"
v-autofocusonshow v-autofocusonshow
:options="plans" :options="plans"
value-field="code" value-field="id"
text-field="name" text-field="name"
data-qa-selector="plan_name" data-qa-selector="plan_name"
/> />
...@@ -271,7 +279,7 @@ export default { ...@@ -271,7 +279,7 @@ export default {
{{ selectedPlanTextLine }} {{ selectedPlanTextLine }}
</strong> </strong>
<div v-if="isSetupForCompany" ref="summary-line-2"> <div v-if="isSetupForCompany" ref="summary-line-2">
{{ $options.i18n.group }}: {{ customer.company || selectedGroupName }} {{ $options.i18n.group }}: {{ customer.company || selectedGroup.name }}
</div> </div>
<div ref="summary-line-3">{{ $options.i18n.users }}: {{ subscription.quantity }}</div> <div ref="summary-line-3">{{ $options.i18n.users }}: {{ subscription.quantity }}</div>
</template> </template>
......
...@@ -24,8 +24,8 @@ export function writeInitialDataToApolloCache(apolloProvider, dataset) { ...@@ -24,8 +24,8 @@ export function writeInitialDataToApolloCache(apolloProvider, dataset) {
isSetupForCompany, isSetupForCompany,
namespaces, namespaces,
fullName, fullName,
selectedPlanId: planId,
subscription: { subscription: {
planId,
paymentMethodId: null, paymentMethodId: null,
quantity: 1, quantity: 1,
namespaceId: null, namespaceId: null,
......
query state { query State {
namespaces @client { namespaces @client {
id id
name name
...@@ -7,6 +7,7 @@ query state { ...@@ -7,6 +7,7 @@ query state {
isNewUser @client isNewUser @client
fullName @client fullName @client
isSetupForCompany @client isSetupForCompany @client
selectedPlanId @client
customer @client { customer @client {
country country
address1 address1
...@@ -17,7 +18,6 @@ query state { ...@@ -17,7 +18,6 @@ query state {
company company
} }
subscription @client { subscription @client {
planId
paymentMethodId paymentMethodId
quantity quantity
namespaceId namespaceId
......
...@@ -263,25 +263,14 @@ describe('Subscription Details', () => { ...@@ -263,25 +263,14 @@ describe('Subscription Details', () => {
describe('when setting up for a company', () => { describe('when setting up for a company', () => {
it('should be valid', () => { it('should be valid', () => {
wrapper = createComponent({ wrapper = createComponent({
subscription: { planId: 'firstPlanId', namespaceId: 483, quantity: 14 }, subscription: { namespaceId: 483, quantity: 14 },
selectedPlanId: 'firstPlanId',
customer: { company: 'Organization name' }, customer: { company: 'Organization name' },
}); });
expect(isStepValid()).toBe(true); expect(isStepValid()).toBe(true);
}); });
it('should be invalid when no plan is selected', async () => {
wrapper = createComponent({
isSetupForCompany: true,
subscription: { planId: null, namespaceId: 483, quantity: 14 },
customer: { company: 'Organization name' },
});
await nextTick();
expect(isStepValid()).toBe(false);
});
it('should be invalid when no organization name is given, and no group is selected', async () => { it('should be invalid when no organization name is given, and no group is selected', async () => {
wrapper = createComponent({ wrapper = createComponent({
isSetupForCompany: true, isSetupForCompany: true,
...@@ -321,7 +310,8 @@ describe('Subscription Details', () => { ...@@ -321,7 +310,8 @@ describe('Subscription Details', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent({ wrapper = createComponent({
isSetupForCompany: false, isSetupForCompany: false,
subscription: { planId: 'firstPlanId', namespaceId: 483, quantity: 1 }, subscription: { namespaceId: 483, quantity: 1 },
selectedPlanId: 'firstPlanId',
customer: { company: 'Organization name' }, customer: { company: 'Organization name' },
}); });
}); });
...@@ -330,22 +320,11 @@ describe('Subscription Details', () => { ...@@ -330,22 +320,11 @@ describe('Subscription Details', () => {
expect(isStepValid()).toBe(true); expect(isStepValid()).toBe(true);
}); });
it('should be invalid when no plan is selected', async () => {
wrapper = createComponent({
isSetupForCompany: false,
subscription: { planId: null, namespaceId: 483, quantity: 1 },
customer: { company: 'Organization name' },
});
await nextTick();
expect(isStepValid()).toBe(false);
});
it('should be invalid when no number of users is 0', async () => { it('should be invalid when no number of users is 0', async () => {
wrapper = createComponent({ wrapper = createComponent({
isSetupForCompany: false, isSetupForCompany: false,
subscription: { planId: 'firstPlanId', namespaceId: 483, quantity: 0 }, subscription: { namespaceId: 483, quantity: 0 },
selectedPlanId: 'firstPlanId',
customer: { company: 'Organization name' }, customer: { company: 'Organization name' },
}); });
...@@ -357,7 +336,8 @@ describe('Subscription Details', () => { ...@@ -357,7 +336,8 @@ describe('Subscription Details', () => {
it('should be invalid when no number of users is greater than 1', async () => { it('should be invalid when no number of users is greater than 1', async () => {
wrapper = createComponent({ wrapper = createComponent({
isSetupForCompany: false, isSetupForCompany: false,
subscription: { planId: 'firstPlanId', namespaceId: 483, quantity: 2 }, subscription: { namespaceId: 483, quantity: 2 },
selectedPlanId: 'firstPlanId',
customer: { company: 'Organization name' }, customer: { company: 'Organization name' },
}); });
......
...@@ -19,12 +19,12 @@ export const mockSetupForCompany = 'true'; ...@@ -19,12 +19,12 @@ export const mockSetupForCompany = 'true';
export const stateData = { export const stateData = {
namespaces: [], namespaces: [],
subscription: { subscription: {
planId: 'secondPlanId',
quantity: 1, quantity: 1,
namespaceId: null, namespaceId: null,
paymentMethodId: null, paymentMethodId: null,
__typename: 'Subscription', __typename: 'Subscription',
}, },
selectedPlanId: null,
customer: { customer: {
country: null, country: null,
address1: null, address1: null,
......
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