Commit 717a73a6 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch '346620-automagically-obtain-translations' into 'master'

Resolve "Move add-on related data to GraphQL"

See merge request gitlab-org/gitlab!78436
parents 948a862c 3b9b980c
......@@ -20,16 +20,7 @@ export default {
GlAlert,
OrderSummary,
},
props: {
config: {
required: true,
type: Object,
},
tags: {
required: true,
type: Array,
},
},
inject: ['tags', 'i18n'],
data() {
return {
hasError: false,
......@@ -50,14 +41,14 @@ export default {
return Number.isFinite(this.quantity) && this.quantity > 0;
},
formulaText() {
const formulaText = this.isQuantityValid ? this.config.formula : this.config.formulaWithAlert;
const formulaText = this.isQuantityValid ? this.i18n.formula : this.i18n.formulaWithAlert;
return sprintf(formulaText, {
quantity: formatNumber(this.config.quantityPerPack),
units: this.config.productUnit,
quantity: formatNumber(this.plan.quantityPerPack),
units: this.plan.productUnit,
});
},
formulaTotal() {
const total = sprintf(this.config.formulaTotal, {
const total = sprintf(this.i18n.formulaTotal, {
quantity: formatNumber(this.totalUnits),
});
return this.isQuantityValid ? total : '';
......@@ -67,20 +58,20 @@ export default {
return plan;
},
totalUnits() {
return this.quantity * this.config.quantityPerPack;
return this.quantity * this.plan.quantityPerPack;
},
summaryTitle() {
return sprintf(this.config.summaryTitle(this.quantity), { quantity: this.quantity });
return sprintf(this.i18n.summaryTitle(this.quantity), { quantity: this.quantity });
},
summaryTotal() {
return sprintf(this.config.summaryTotal, {
return sprintf(this.i18n.summaryTotal, {
quantity: formatNumber(this.totalUnits),
});
},
},
methods: {
pricePerUnitLabel(price) {
return sprintf(this.config.pricePerUnit, {
return sprintf(this.i18n.pricePerUnit, {
selectedPlanPrice: price,
});
},
......@@ -137,10 +128,10 @@ export default {
<checkout :plan="plan">
<template #purchase-details>
<addon-purchase-details
:product-label="config.productLabel"
:product-label="plan.label"
:quantity="quantity"
:show-alert="true"
:alert-text="config.alertText"
:alert-text="i18n.alertText"
>
<template #formula>
{{ formulaText }}
......@@ -162,8 +153,8 @@ export default {
>
<order-summary
:plan="plan"
:title="config.title"
:purchase-has-expiration="config.hasExpiration"
:title="i18n.title"
:purchase-has-expiration="plan.hasExpiration"
@alertError="alertError"
>
<template #price-per-unit="{ price }">
......
......@@ -6,10 +6,6 @@ export const planTags = {
STORAGE_PLAN: 'STORAGE_PLAN',
};
/* eslint-enable @gitlab/require-i18n-strings */
export const planCode = {
CI_1000_MINUTES_PLAN: 'ci_minutes',
STORAGE_PLAN: 'storage',
};
export const CUSTOMERSDOT_CLIENT = 'customersDotClient';
export const GITLAB_CLIENT = 'gitlabClient';
......@@ -26,40 +22,25 @@ export const STATE_TYPE = 'State';
export const CI_MINUTES_PER_PACK = 1000;
export const STORAGE_PER_PACK = 10;
// CI Minutes addon data translations
export const I18N_CI_MINUTES_PRODUCT_LABEL = s__('Checkout|CI minute pack');
export const I18N_CI_MINUTES_PRODUCT_UNIT = s__('Checkout|minutes');
export const I18N_CI_MINUTES_FORMULA_TOTAL = s__('Checkout|%{quantity} CI minutes');
export const i18nCIMinutesSummaryTitle = (quantity) =>
n__('Checkout|%d CI minute pack', 'Checkout|%d CI minute packs', quantity);
export const I18N_CI_MINUTES_SUMMARY_TOTAL = s__('Checkout|Total minutes: %{quantity}');
export const I18N_CI_MINUTES_ALERT_TEXT = s__(
"Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year.",
);
export const I18N_CI_MINUTES_PRICE_PER_UNIT = s__(
'Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes',
);
export const I18N_CI_MINUTES_TITLE = s__("Checkout|%{name}'s CI minutes");
// Storage addon translations
export const I18N_STORAGE_PRODUCT_LABEL = s__('Checkout|Storage packs');
export const I18N_STORAGE_PRODUCT_UNIT = s__('Checkout|GB');
export const I18N_STORAGE_FORMULA_TOTAL = s__('Checkout|%{quantity} GB of storage');
export const i18nStorageSummaryTitle = (quantity) =>
n__('Checkout|%{quantity} storage pack', 'Checkout|%{quantity} storage packs', quantity);
export const I18N_STORAGE_SUMMARY_TOTAL = s__('Checkout|Total storage: %{quantity} GB');
export const I18N_STORAGE_PRICE_PER_UNIT = s__(
'Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year',
);
export const I18N_STORAGE_TITLE = s__("Checkout|%{name}'s storage subscription");
export const I18N_STORAGE_TOOLTIP_NOTE = s__(
'Checkout|Your storage subscription has the same term as your main subscription, and the price is prorated accordingly.',
);
// Shared addon translations
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_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_WITH_ALERT = s__('Checkout|x %{quantity} %{units} per pack');
// Summary translations
export const I18N_SUMMARY_QUANTITY = s__('Checkout|(x%{quantity})');
export const I18N_SUMMARY_DATES = s__('Checkout|%{startDate} - %{endDate}');
export const I18N_SUMMARY_SUBTOTAL = s__('Checkout|Subtotal');
......@@ -72,3 +53,30 @@ export const I18N_SUMMARY_TOTAL = s__('Checkout|Total');
export const I18N_API_ERROR = s__(
'Checkout|An unknown error has occurred. Please try again by refreshing this page.',
);
// Addon label translations
export const I18N_CI_1000_MINUTES_PLAN = {
alertText: s__(
"Checkout|CI minute packs are only used after you've used your subscription's monthly quota. The additional minutes will roll over month to month and are valid for one year.",
),
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: s__('Checkout|%{quantity} CI minutes'),
pricePerUnit: s__('Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes'),
summaryTitle: (quantity) =>
n__('Checkout|%d CI minute pack', 'Checkout|%d CI minute packs', quantity),
summaryTotal: s__('Checkout|Total minutes: %{quantity}'),
title: s__("Checkout|%{name}'s CI minutes"),
};
export const I18N_STORAGE_PLAN = {
alertText: '',
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: s__('Checkout|%{quantity} GB of storage'),
pricePerUnit: s__('Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year'),
summaryTitle: (quantity) =>
n__('Checkout|%{quantity} storage pack', 'Checkout|%{quantity} storage packs', quantity),
summaryTotal: s__('Checkout|Total storage: %{quantity} GB'),
title: s__("Checkout|%{name}'s storage subscription"),
};
......@@ -11,12 +11,16 @@ import {
I18N_CI_MINUTES_PRODUCT_UNIT,
I18N_STORAGE_PRODUCT_LABEL,
I18N_STORAGE_PRODUCT_UNIT,
planCode,
STORAGE_PER_PACK,
} from 'ee/subscriptions/buy_addons_shared/constants';
import stateQuery from 'ee/subscriptions/graphql/queries/state.query.graphql';
import createFlash from '~/flash';
const planCode = {
CI_1000_MINUTES_PLAN: 'ci_minutes',
STORAGE_PLAN: 'storage',
};
const planData = {
[planCode.CI_1000_MINUTES_PLAN]: {
hasExpiration: false,
......
<script>
import BuyAddonsApp from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import {
CI_MINUTES_PER_PACK,
planTags,
I18N_CI_MINUTES_PRICE_PER_UNIT,
I18N_CI_MINUTES_PRODUCT_LABEL,
I18N_CI_MINUTES_PRODUCT_UNIT,
I18N_DETAILS_FORMULA,
I18N_DETAILS_FORMULA_WITH_ALERT,
I18N_CI_MINUTES_FORMULA_TOTAL,
i18nCIMinutesSummaryTitle,
I18N_CI_MINUTES_SUMMARY_TOTAL,
I18N_CI_MINUTES_ALERT_TEXT,
I18N_CI_MINUTES_TITLE,
} from 'ee/subscriptions/buy_addons_shared/constants';
export default {
components: {
BuyAddonsApp,
},
computed: {
tags() {
return [planTags.CI_1000_MINUTES_PLAN];
},
config() {
// These will move into the GraphQL store. See: https://gitlab.com/gitlab-org/gitlab/-/issues/346620
return {
alertText: I18N_CI_MINUTES_ALERT_TEXT,
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: I18N_CI_MINUTES_FORMULA_TOTAL,
hasExpiration: false,
pricePerUnit: I18N_CI_MINUTES_PRICE_PER_UNIT,
productLabel: I18N_CI_MINUTES_PRODUCT_LABEL,
productUnit: I18N_CI_MINUTES_PRODUCT_UNIT,
quantityPerPack: CI_MINUTES_PER_PACK,
summaryTitle: i18nCIMinutesSummaryTitle,
summaryTotal: I18N_CI_MINUTES_SUMMARY_TOTAL,
title: I18N_CI_MINUTES_TITLE,
};
},
},
};
</script>
<template>
<buy-addons-app :config="config" :tags="tags" />
</template>
import Vue from 'vue';
import ensureData from '~/ensure_data';
import apolloProvider from '../buy_addons_shared/graphql';
import { planTags, I18N_CI_1000_MINUTES_PLAN } from 'ee/subscriptions/buy_addons_shared/constants';
import App from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import { writeInitialDataToApolloCache } from '../buy_addons_shared/utils';
import App from './components/app.vue';
import apolloProvider from '../buy_addons_shared/graphql';
export default (el) => {
if (!el) {
......@@ -13,6 +14,10 @@ export default (el) => {
parseData: writeInitialDataToApolloCache.bind(null, apolloProvider),
data: el.dataset,
shouldLog: true,
provide: {
tags: [planTags.CI_1000_MINUTES_PLAN],
i18n: I18N_CI_1000_MINUTES_PLAN,
},
});
return new Vue({
......
<script>
import BuyAddonsApp from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import {
I18N_STORAGE_PRODUCT_LABEL,
I18N_STORAGE_PRODUCT_UNIT,
I18N_DETAILS_FORMULA,
I18N_STORAGE_FORMULA_TOTAL,
I18N_DETAILS_FORMULA_WITH_ALERT,
i18nStorageSummaryTitle,
I18N_STORAGE_SUMMARY_TOTAL,
I18N_STORAGE_TITLE,
I18N_STORAGE_PRICE_PER_UNIT,
planTags,
STORAGE_PER_PACK,
} from 'ee/subscriptions/buy_addons_shared/constants';
export default {
name: 'BuyStorageApp',
components: {
BuyAddonsApp,
},
computed: {
tags() {
return [planTags.STORAGE_PLAN];
},
config() {
// These will move into the GraphQL store. See: https://gitlab.com/gitlab-org/gitlab/-/issues/346620
return {
alertText: '',
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: I18N_STORAGE_FORMULA_TOTAL,
hasExpiration: true,
pricePerUnit: I18N_STORAGE_PRICE_PER_UNIT,
productLabel: I18N_STORAGE_PRODUCT_LABEL,
productUnit: I18N_STORAGE_PRODUCT_UNIT,
quantityPerPack: STORAGE_PER_PACK,
summaryTitle: i18nStorageSummaryTitle,
summaryTotal: I18N_STORAGE_SUMMARY_TOTAL,
title: I18N_STORAGE_TITLE,
};
},
},
};
</script>
<template>
<buy-addons-app :config="config" :tags="tags" />
</template>
import Vue from 'vue';
import ensureData from '~/ensure_data';
import { planTags, I18N_STORAGE_PLAN } from 'ee/subscriptions/buy_addons_shared/constants';
import App from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import apolloProvider from '../buy_addons_shared/graphql';
import { writeInitialDataToApolloCache } from '../buy_addons_shared/utils';
import App from './components/app.vue';
export default (el) => {
if (!el) {
......@@ -13,10 +14,15 @@ export default (el) => {
parseData: writeInitialDataToApolloCache.bind(null, apolloProvider),
data: el.dataset,
shouldLog: true,
provide: {
tags: [planTags.STORAGE_PLAN],
i18n: I18N_STORAGE_PLAN,
},
});
return new Vue({
el,
name: 'BuyStorage',
apolloProvider,
render(createElement) {
return createElement(extendedApp);
......
import BuyAddonsApp from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import App from 'ee/subscriptions/buy_minutes/components/app.vue';
import {
CI_MINUTES_PER_PACK,
planTags,
I18N_CI_MINUTES_PRICE_PER_UNIT,
I18N_CI_MINUTES_PRODUCT_LABEL,
I18N_CI_MINUTES_PRODUCT_UNIT,
I18N_DETAILS_FORMULA,
I18N_DETAILS_FORMULA_WITH_ALERT,
I18N_CI_MINUTES_FORMULA_TOTAL,
i18nCIMinutesSummaryTitle,
I18N_CI_MINUTES_SUMMARY_TOTAL,
I18N_CI_MINUTES_ALERT_TEXT,
I18N_CI_MINUTES_TITLE,
} from 'ee/subscriptions/buy_addons_shared/constants';
describe('Buy Minutes App', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMountExtended(App);
};
const findBuyAddonsApp = () => wrapper.findComponent(BuyAddonsApp);
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('passes the correct tags', () => {
expect(findBuyAddonsApp().props('tags')).toEqual([planTags.CI_1000_MINUTES_PLAN]);
});
it('passes the correct config', () => {
expect(findBuyAddonsApp().props('config')).toMatchObject({
alertText: I18N_CI_MINUTES_ALERT_TEXT,
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: I18N_CI_MINUTES_FORMULA_TOTAL,
hasExpiration: false,
pricePerUnit: I18N_CI_MINUTES_PRICE_PER_UNIT,
productLabel: I18N_CI_MINUTES_PRODUCT_LABEL,
productUnit: I18N_CI_MINUTES_PRODUCT_UNIT,
quantityPerPack: CI_MINUTES_PER_PACK,
summaryTitle: i18nCIMinutesSummaryTitle,
summaryTotal: I18N_CI_MINUTES_SUMMARY_TOTAL,
title: I18N_CI_MINUTES_TITLE,
});
});
});
import BuyAddonsApp from 'ee/subscriptions/buy_addons_shared/components/app.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import App from 'ee/subscriptions/buy_storage/components/app.vue';
import {
I18N_STORAGE_PRODUCT_LABEL,
I18N_STORAGE_PRODUCT_UNIT,
I18N_DETAILS_FORMULA,
I18N_STORAGE_FORMULA_TOTAL,
I18N_DETAILS_FORMULA_WITH_ALERT,
i18nStorageSummaryTitle,
I18N_STORAGE_SUMMARY_TOTAL,
I18N_STORAGE_TITLE,
I18N_STORAGE_PRICE_PER_UNIT,
planTags,
STORAGE_PER_PACK,
} from 'ee/subscriptions/buy_addons_shared/constants';
describe('Buy Storage App', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMountExtended(App);
};
const findBuyAddonsApp = () => wrapper.findComponent(BuyAddonsApp);
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('passes the correct tags', () => {
expect(findBuyAddonsApp().props('tags')).toEqual([planTags.STORAGE_PLAN]);
});
it('passes the correct config', () => {
expect(findBuyAddonsApp().props('config')).toMatchObject({
alertText: '',
formula: I18N_DETAILS_FORMULA,
formulaWithAlert: I18N_DETAILS_FORMULA_WITH_ALERT,
formulaTotal: I18N_STORAGE_FORMULA_TOTAL,
hasExpiration: true,
pricePerUnit: I18N_STORAGE_PRICE_PER_UNIT,
productLabel: I18N_STORAGE_PRODUCT_LABEL,
productUnit: I18N_STORAGE_PRODUCT_UNIT,
quantityPerPack: STORAGE_PER_PACK,
summaryTitle: i18nStorageSummaryTitle,
summaryTotal: I18N_STORAGE_SUMMARY_TOTAL,
title: I18N_STORAGE_TITLE,
});
});
});
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